package de.danoeh.antennapod.activity;

import android.content.SharedPreferences;
import android.media.AudioManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;

import com.google.android.gms.cast.ApplicationMetadata;

import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.cast.CastConsumer;
import de.danoeh.antennapod.core.cast.CastConsumerImpl;
import de.danoeh.antennapod.core.cast.CastManager;
import de.danoeh.antennapod.core.cast.SwitchableMediaRouteActionProvider;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;

/**
 * Activity that allows for showing the MediaRouter button whenever there's a cast device in the
 * network.
 */
public abstract class CastEnabledActivity extends AppCompatActivity
        implements SharedPreferences.OnSharedPreferenceChangeListener {
    public static final String TAG = "CastEnabledActivity";

    protected CastManager mCastManager;
    private volatile int castUICounter;
    protected SwitchableMediaRouteActionProvider mMediaRouteActionProvider;
    protected volatile boolean isCastEnabled;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).
                registerOnSharedPreferenceChangeListener(this);

        castUICounter = 0;
        mCastManager = CastManager.getInstance();
        mCastManager.addCastConsumer(castConsumer);
        isCastEnabled = UserPreferences.isCastEnabled();
        onCastConnectionChanged(mCastManager.isConnected());
    }

    @Override
    protected void onDestroy() {
        PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
                .unregisterOnSharedPreferenceChangeListener(this);
        mCastManager.removeCastConsumer(castConsumer);
        super.onDestroy();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.cast_enabled, menu);
        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        mMediaRouteActionProvider = mCastManager
                .addMediaRouterButton(menu.findItem(R.id.media_route_menu_item));
        mMediaRouteActionProvider.setEnabled(isCastEnabled);
        return true;
    }

    @Override
    protected void onResume() {
        super.onResume();
        castUICounter++;
        if (isCastEnabled) {
            mCastManager.incrementUiCounter();
            castUICounter++;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        castUICounter--;
        if (isCastEnabled) {
            mCastManager.decrementUiCounter();
            castUICounter--;
        }
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (UserPreferences.PREF_CAST_ENABLED.equals(key)) {
            isCastEnabled = UserPreferences.isCastEnabled();
            Log.d(TAG, "onSharedPreferenceChanged(), isCastEnabled set to " + isCastEnabled);
            mMediaRouteActionProvider.setEnabled(isCastEnabled);
            if (isCastEnabled) {
                //Test if activity is resumed but without UI counter incremented
                if (castUICounter==1) {
                    mCastManager.incrementUiCounter();
                    castUICounter++;
                }
            } else {
                if (castUICounter > 1) {
                    mCastManager.decrementUiCounter();
                    castUICounter--;
                }
                if (!PlaybackService.isRunning) {
                    CastManager.getInstance().disconnect();
                }
            }
        }
    }

    CastConsumer castConsumer = new CastConsumerImpl() {
        @Override
        public void onApplicationConnected(ApplicationMetadata appMetadata, String sessionId, boolean wasLaunched) {
            onCastConnectionChanged(true);
        }

        @Override
        public void onDisconnected() {
            onCastConnectionChanged(false);
        }
    };

    private void onCastConnectionChanged(boolean connected) {
        if (connected) {
            setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
        } else {
            setVolumeControlStream(AudioManager.STREAM_MUSIC);
        }
    }
}

@@ -1107,34 +1107,99 @@
 ate 
-volatile int castUICounter
+final Object UI_COUNTER_LOCK = new Object();%0A    private volatile boolean isResumed = false
 ;%0A  
@@ -1316,16 +1316,24 @@
 tEnabled
+ = false
 ;%0A%0A    @
@@ -1592,35 +1592,8 @@
 );%0A%0A
-        castUICounter = 0;%0A
     
@@ -2703,33 +2703,83 @@
         
-castUICounter++;%0A
+synchronized (UI_COUNTER_LOCK) %7B%0A            isResumed = true;%0A    
         
@@ -2791,32 +2791,36 @@
 sCastEnabled) %7B%0A
+    
             mCas
@@ -2862,32 +2862,17 @@
         
-castUICounter++;
+%7D
 %0A       
@@ -2959,33 +2959,84 @@
         
-castUICounter--;%0A
+synchronized (UI_COUNTER_LOCK) %7B%0A            isResumed = false;%0A    
         
@@ -3048,32 +3048,36 @@
 sCastEnabled) %7B%0A
+    
             mCas
@@ -3119,32 +3119,17 @@
         
-castUICounter--;
+%7D
 %0A       
@@ -3314,37 +3314,40 @@
             
-isCastEnabled
+boolean newValue
  = UserPrefe
@@ -3448,29 +3448,24 @@
  to %22 + 
-isCastEnabled
+newValue
 );%0A     
@@ -3475,215 +3475,143 @@
     
-mMediaRouteActionProvider.setEnabled(isCastEnabled);%0A            if (isCastEnabled) %7B%0A                //Test if activity is r
+synchronized (UI_COUNTER_LOCK) %7B%0A                if (isCastEnabled != newValue && isR
 esumed
- but without UI counter incremented%0A                if (castUICounter==1) %7B%0A
+) %7B%0A                    if (newValue) %7B%0A    
     
@@ -3685,25 +3685,80 @@
     
-castUICounter++;%0A
+%7D else %7B%0A                        mCastManager.decrementUiCounter();%0A    
     
@@ -3779,32 +3779,29 @@
             
-%7D else %7B
+    %7D
 %0A           
@@ -3810,31 +3810,32 @@
    i
-f (castUICounter %3E 1) %7B
+sCastEnabled = newValue;
 %0A   
@@ -3831,32 +3831,38 @@
 wValue;%0A        
+    %7D%0A
             mCas
@@ -3862,99 +3862,166 @@
    m
-CastManager.decrementUiCounter();%0A                    castUICounter--;%0A                %7D%0A  
+MediaRouteActionProvider.setEnabled(isCastEnabled);%0A            // PlaybackService has its own listener, so if it's active we don't have to take action here.%0A
     
@@ -4028,22 +4028,38 @@
         
-  
 if (
+!isCastEnabled && 
 !Playbac
@@ -4096,20 +4096,16 @@
         
-    
 CastMana
@@ -4136,34 +4136,16 @@
 nect();%0A
-                %7D%0A
         

make the UI counter, cast preference state, resumed state synchronized