package athary.audio.ency;

import java.io.IOException;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.MediaPlayer.OnBufferingUpdateListener;
import io.vov.vitamio.MediaPlayer.OnCompletionListener;
import io.vov.vitamio.MediaPlayer.OnErrorListener;
import io.vov.vitamio.MediaPlayer.OnInfoListener;
import io.vov.vitamio.MediaPlayer.OnPreparedListener;
import io.vov.vitamio.MediaPlayer.OnSeekCompleteListener;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

public class PlayService extends Service implements OnCompletionListener,
		OnPreparedListener, OnErrorListener, OnSeekCompleteListener,
		OnInfoListener, OnBufferingUpdateListener {

	private static final String TAG = "TELSERVICE";
	private MediaPlayer mediaPlayer;
	private String sntAudioLink;
	
	//-- URL location of audio clip PUT YOUR AUDIO URL LOCATION HERE ---
	
	// Set up the notification ID
	private static final int NOTIFICATION_ID = 1;
	private boolean isPausedInCall = false;
	private PhoneStateListener phoneStateListener;
	private TelephonyManager telephonyManager;

	// ---Variables for seekbar processing---
	String sntSeekPos;
	int intSeekPos;
	int mediaPosition;
	int mediaMax;
	//Intent intent;
	private final Handler handler = new Handler();
	private static int songEnded;
	public static final String BROADCAST_ACTION = "athary.audio.ency.seekprogress";

	// Set up broadcast identifier and intent
	public static final String BROADCAST_BUFFER = "athary.audio.ency.broadcastbuffer";
	
	Intent bufferIntent;
	Intent seekIntent;

	// Declare headsetSwitch variable
	private int headsetSwitch = 1;

	// OnCreate
	@Override
	public void onCreate() {
		if (io.vov.vitamio.Vitamio.initialize(this)) {
		} else {
			stopSelf();
		}

		mediaPlayer = new MediaPlayer(this);
		
		bufferIntent = new Intent(BROADCAST_BUFFER);
		seekIntent = new Intent(BROADCAST_ACTION);
		mediaPlayer.setOnCompletionListener(this);
		mediaPlayer.setOnErrorListener(this);
		mediaPlayer.setOnPreparedListener(this);
		mediaPlayer.setOnBufferingUpdateListener(this);
		mediaPlayer.setOnSeekCompleteListener(this);
		mediaPlayer.setOnInfoListener(this);
		mediaPlayer.reset();

		registerReceiver(headsetReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));

	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {

		registerReceiver(broadcastReceiver, new IntentFilter(IntroActivity.BROADCAST_SEEKBAR));

		telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
		Log.v(TAG, "Starting listener");
		phoneStateListener = new PhoneStateListener() {
			@Override
			public void onCallStateChanged(int state, String incomingNumber) {
				// String stateString = "N/A";
				Log.v(TAG, "Starting CallStateChange");
				switch (state) {
				case TelephonyManager.CALL_STATE_OFFHOOK:
				case TelephonyManager.CALL_STATE_RINGING:
					if (mediaPlayer != null) {
						if (mediaPlayer.isPlaying()) {
							pauseMedia();
							isPausedInCall = true;
						}
						
					}

					break;
				case TelephonyManager.CALL_STATE_IDLE:
					// Phone idle. Start playing.
					if (mediaPlayer != null) {
						if (isPausedInCall) {
							isPausedInCall = false;
							playMedia();
						}
					}
					break;
				}

			}
		};

		// Register the listener with the telephony manager
		telephonyManager.listen(phoneStateListener,	PhoneStateListener.LISTEN_CALL_STATE);

		// Insert notification start

		initNotification(intent.getExtras().getString("title"));

		sntAudioLink = intent.getExtras().getString("sentAudioLink");
		mediaPlayer.reset();

		// Set up the MediaPlayer data source using the strAudioLink value
		if (!mediaPlayer.isPlaying()) {
			try {
				mediaPlayer.setDataSource(sntAudioLink);

				// Send message to Activity to display progress dialogue
				sendBufferingBroadcast();
				// Prepare mediaplayer
				mediaPlayer.prepare();

			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
			}
		}
		// --- Set up seekbar handler ---
		setupHandler();

		return START_STICKY;
	}

	// ---Send seekbar info to activity----
	private void setupHandler() {
		handler.removeCallbacks(sendUpdatesToUI);
		handler.postDelayed(sendUpdatesToUI, 1); // 1 second
	}

	private Runnable sendUpdatesToUI = new Runnable() {
		public void run() {
			// // Log.d(TAG, "entered sendUpdatesToUI");

			LogMediaPosition();

			handler.postDelayed(this, 1); // 2 seconds

		}
	};
 
	private void LogMediaPosition() {
		// // Log.d(TAG, "entered LogMediaPosition");
		if (mediaPlayer.isPlaying()) {
			mediaPosition = (int) mediaPlayer.getCurrentPosition();
			// if (mediaPosition < 1) {
			// Toast.makeText(this, "Buffering...", Toast.LENGTH_SHORT).show();
			// }
			mediaMax = (int) mediaPlayer.getDuration();
			//seekIntent.putExtra("time", new Date().toLocaleString());
			seekIntent.putExtra("counter", String.valueOf(mediaPosition));
			seekIntent.putExtra("mediamax", String.valueOf(mediaMax));
			seekIntent.putExtra("song_ended", String.valueOf(songEnded));

			sendBroadcast(seekIntent);
		}
	}

	// --Receive seekbar position if it has been changed by the user in the
	// activity
	private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			updateSeekPos(intent);
		}
	};

	// Update seek position from Activity
	public void updateSeekPos(Intent intent) {
		int seekPos = intent.getIntExtra("seekpos", 0);
		int stat = intent.getIntExtra("stat", 3);
		boolean seek = intent.getBooleanExtra("seekbol", false);
		
		if (stat == 1) {
			pauseMedia();
		}
		else if (stat == 2) {
			playMedia();
		}
		if (seek) {
			seek = false;
			handler.removeCallbacks(sendUpdatesToUI);
			mediaPlayer.seekTo(seekPos);
			setupHandler();
		}
	}

	// ---End of seekbar code

	// If headset gets unplugged, stop music and service.
	private BroadcastReceiver headsetReceiver = new BroadcastReceiver() {
		private boolean headsetConnected = false;

		@Override
		public void onReceive(Context context, Intent intent) {

			if (intent.hasExtra("state")) {
				if (headsetConnected && intent.getIntExtra("state", 0) == 0) {
					headsetConnected = false;
					headsetSwitch = 0;
					// Log.v(TAG, "State =  Headset disconnected");
					// headsetDisconnected();
				} else if (!headsetConnected
						&& intent.getIntExtra("state", 0) == 1) {
					headsetConnected = true;
					headsetSwitch = 1;
					// Log.v(TAG, "State =  Headset connected");
				}

			}

			switch (headsetSwitch) {
			case (0):
				headsetDisconnected();
				break;
			case (1):
				break;
			}
		}

	};

	private void headsetDisconnected() {
		stopMedia();
		stopSelf();

	}

	
	// --- onDestroy, stop media player and release.  Also stop phoneStateListener, notification, receivers...---
	@Override
	public void onDestroy() {
		super.onDestroy();
		if (mediaPlayer != null) {
			if (mediaPlayer.isPlaying()) {
				mediaPlayer.stop();
			}
			mediaPlayer.release();
		}

		if (phoneStateListener != null) {
			telephonyManager.listen(phoneStateListener,
					PhoneStateListener.LISTEN_NONE);
		}

		// Cancel the notification
		cancelNotification();

		// Unregister headsetReceiver
		unregisterReceiver(headsetReceiver);

		// Unregister seekbar receiver
		unregisterReceiver(broadcastReceiver);

		// Stop the seekbar handler from sending updates to UI
		handler.removeCallbacks(sendUpdatesToUI);

		// Service ends, need to tell activity to display "Play" button
		//resetButtonPlayStopBroadcast();
	}

	// Send a message to Activity that audio is being prepared and buffering
	// started.
	private void sendBufferingBroadcast() {
		// Log.v(TAG, "BufferStartedSent");
		bufferIntent.putExtra("buffering", "1");
		sendBroadcast(bufferIntent);
	}

	// Send a message to Activity that audio is prepared and ready to start
	// playing.
	private void sendBufferCompleteBroadcast() {
		// Log.v(TAG, "BufferCompleteSent");
		bufferIntent.putExtra("buffering", "0");
		sendBroadcast(bufferIntent);
	}

	// Send a message to Activity to reset the play button.
	private void resetButtonPlayStopBroadcast() {
		// Log.v(TAG, "BufferCompleteSent");
		bufferIntent.putExtra("buffering", "2");
		sendBroadcast(bufferIntent);
	}

	@Override
	public void onBufferingUpdate(MediaPlayer arg0, int arg1) {


	}

	@Override
	public boolean onInfo(MediaPlayer arg0, int arg1, int arg2) {

		return false;
	}

	@Override
	public void onSeekComplete(MediaPlayer mp) {
		
		if (!mediaPlayer.isPlaying()){
			playMedia();
			//Toast.makeText(this,"SeekComplete", Toast.LENGTH_SHORT).show();
		}
		
	}

	
	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		switch (what) {
		case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
			sendBufferCompleteBroadcast();
			//Toast.makeText(this,"MEDIA ERROR NOT VALID FOR PROGRESSIVE PLAYBACK " + extra,Toast.LENGTH_SHORT).show();
			break;
		case MediaPlayer.MEDIA_ERROR_UNKNOWN:
			sendBufferCompleteBroadcast();
			//Toast.makeText(this, "MEDIA ERROR UNKNOWN " + extra, Toast.LENGTH_SHORT).show();
			break;
		}
		return false;
	}

	@Override
	public void onPrepared(MediaPlayer arg0) {

		// Send a message to activity to end progress dialogue

		sendBufferCompleteBroadcast();
		playMedia();
	}

	@Override
	public void onCompletion(MediaPlayer mp) {
		// When song ends, need to tell activity to display "Play" button
		//stopMedia();
		//stopSelf();
		pauseMedia();
		resetButtonPlayStopBroadcast();
	}

	@Override
	public IBinder onBind(Intent arg0) {

		return null;
	}

	public void playMedia() {
		if (!mediaPlayer.isPlaying()) {
			mediaPlayer.start();
		}
	}

	// Add for Telephony Manager
	public void pauseMedia() {
		if (mediaPlayer.isPlaying()) {
			mediaPlayer.pause();
		}

	}

	public void stopMedia() {
		if (mediaPlayer.isPlaying()) {
			mediaPlayer.stop();
		}
	}

	// Create Notification
	private void initNotification(String title) {
		//String ns = Context.NOTIFICATION_SERVICE;
		//NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
		int icon = R.drawable.icon;
		CharSequence tickerText = "الموسوعة الصوتية";
		long when = System.currentTimeMillis();
		Notification notification = new Notification(icon, tickerText, when);
		notification.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;   
		Context context = getApplicationContext();
		CharSequence contentTitle = "الموسوعة الصوتية";
		CharSequence contentText = title;
		Intent notificationIntent = new Intent(this, IntroActivity.class);
		notificationIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
		PendingIntent contentIntent = PendingIntent.getActivity(context, 0,	notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
		notification.setLatestEventInfo(context, contentTitle, contentText,	contentIntent);
		//mNotificationManager.notify(NOTIFICATION_ID, notification);
		
		startForeground(NOTIFICATION_ID, notification);

	}

	// Cancel Notification
	private void cancelNotification() {
		//String ns = Context.NOTIFICATION_SERVICE;
		//NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
		//mNotificationManager.cancel(NOTIFICATION_ID);
		stopForeground(true);

	}
}
