package penta.haneda.IollMsgReceiver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

/**
 * MainAcivity
 * @author KMK-Teraoka
 */
public class MainActivity extends Activity
{
	private Handler mHandler;
	private MediaPlayer mMediaPlayer;
	private ServerSock mServerSock;
	private boolean mDetectFlg = false;
	private CstmView mCsView;
	
	private static final int AUTO_STOP_SECONDS = 120;
	
	private static AutoStopSounds mAtSoundStop;
	
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		Log.d("MAIN_ACTIVITY", "CALL_ON_CREATE");
		
		// フルスクリーン表示
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		
		// KeepScreen
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		
		mCsView = new CstmView(getApplicationContext());
		setContentView(mCsView);
		//setContentView(R.layout.activity_main);
		
		// アプリケーションの初期化
		Init();
		
		// Threadスタート
		mServerSock = new ServerSock();
		mServerSock.start();
	}
	
	/**
	 * onStart
	 * 2012/09/25 KMK-Teraoka
	 */
	@Override
	public void onStart()
	{
		super.onStart();
		Log.d("MAIN_ACTIVITY", "CALL_ON_START");
	}
	
	/**
	 * 各種変数の初期化
	 * 2012/09/25 KMK-Teraoka
	 */
	private void Init()
	{
		// Handler
		mHandler = new Handler();
		
		// 自動停止タスク準備
		mAtSoundStop = new AutoStopSounds();
		
		// 再生の準備
		try
		{
			mMediaPlayer = MediaPlayer.create(this, R.raw.cancel01);
			mMediaPlayer.setLooping(true);
			mMediaPlayer.prepare();
		}
		catch(Exception Exc)
		{
			Log.d("INIT_SOUND", Exc.toString());
		}
	}
	
	/**
	 * onResume
	 * 2012/09/25 KMK-Teraoka
	 */
	@Override
	public void onResume()
	{
		super.onResume();
		Log.d("MAIN_ACTIVITY", "CALL_ON_RESUME");
	}
	
	/**
	 * onPause
	 * 2012/09/25 KMK-Teraoka
	 */
	@Override
	public void onPause()
	{
		super.onPause();
		Log.d("MAIN_ACTIVITY", "CALL_ON_PAUSE");
	}
	
	/**
	 * onDestroy
	 * 2012/09/25 KMK-Teraoka
	 */
	@Override
	public void onDestroy()
	{
		super.onDestroy();
		Log.d("MAIN_ACTIVITY", "CALL_ON_DESTROY");
		
		// Asynctaskが実行されている場合停止させる
		if (mAtSoundStop.getStatus() == AsyncTask.Status.RUNNING)
		{
			mAtSoundStop.cancel(true);
		}
		
		// Threadの停止
		mServerSock.StopRun();
		
		// 音声ファイルが再生されている場合は停止
		if (mMediaPlayer.isPlaying() == true)
		{
			mMediaPlayer.stop();
			mMediaPlayer.release();
		}
		
		// KeepScreenを解除
		getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
	}
	
	/**
	 * 戻るキーを無効にする
	 * 2012/09/12 KMK-Teraoka
	 */
	public boolean dispatchKeyEvent(KeyEvent event_)
	{
		if (event_.getAction() == KeyEvent.ACTION_DOWN)
		{
			switch(event_.getKeyCode())
			{
				case KeyEvent.KEYCODE_BACK:
					return true;
			}
		}
		return super.dispatchKeyEvent(event_);
	}
	
	/**
	 * クライアントからの接続要求を待機するThread
	 * @author KMK-Teraoka
	 */
	public class ServerSock extends Thread
	{
		private boolean mLoop;
		
		/**
		 * コンストラクタ
		 */
		public ServerSock()
		{
			this.mLoop = true;
		}
		
		/**
		 * WorkerThreadで処理する内容
		 */
		public void run()
		{
			Log.d("SERVER_THREAD", "CALL_RUN");
			
			try
			{
				ServerSocket SockServer = null;
				SockServer = new ServerSocket(50002);
				
				while(mLoop)
				{
					try
					{
						// クライアントからの接続要求を待つ
						Socket Sock = SockServer.accept();
						
						// 要求に対して接続を行う
						ClientSock ClSock = new ClientSock(Sock);
						ClSock.start();
					}
					catch(IOException e)
					{
						System.out.println(e);
					}
				}
				
				if (SockServer != null)
				{
					SockServer.close();
					SockServer = null;
				}
			}
			catch (IOException IoExc)
			{
				Log.d("SERVER_SOCKET_THREAD", IoExc.toString());
			}
		}
		
		/**
		 * 処理を停止する
		 */
		public void StopRun()
		{
			mLoop = false;
		}
	}
	
	/**
	 * Serverに接続要求してきたSocketを処理するThread
	 * @author KMK-Teraoka
	 */
	public class ClientSock extends Thread
	{
		private Socket mSock = null;
		
		/**
		 * コンストラクタ
		 */
		public ClientSock(Socket Sock_)
		{
			this.mSock = Sock_;
		}
		
		/**
		 * WorkerThreadでの処理
		 */
		public void run()
		{
			if (mSock == null)
			{
				return;
			}
			
			try
			{
				BufferedReader BuffReader = new BufferedReader(new InputStreamReader(mSock.getInputStream()));
				String ReadObj = new String();
				
				while(true)
				{
					char[] Buff = new char[32];
					BuffReader.read(Buff, 0, 1);
					String StRead = String.valueOf(Buff, 0, 1);
					if (StRead.equals("\r"))
					{
						break;
					}
					ReadObj += StRead;
				}
				Log.d("CLIENT_SOCKET_THREAD", "RECV_MSG->" + ReadObj);
				
				if (ReadObj.equals("MSG_ON"))
				{
					if (mDetectFlg == false)
					{
						mDetectFlg = true;
						if (mMediaPlayer.isPlaying() == false)
						{
							mMediaPlayer.start();
						}
						mHandler.post(new Runnable()
						{
							public void run()
							{
								mCsView.invalidate();
							}
						});
					}
					
					// 自動停止タスクの実行
					if (mAtSoundStop.getStatus() == AsyncTask.Status.RUNNING)
					{
						mAtSoundStop.cancel(true);
						mAtSoundStop = new AutoStopSounds();
					}
					if (mAtSoundStop.getStatus() == AsyncTask.Status.FINISHED)
					{
						mAtSoundStop = new AutoStopSounds();
					}
					mAtSoundStop.execute(null, null, null);
				}
				else if (ReadObj.equals("MSG_OFF"))
				{
					if (mDetectFlg == true)
					{
						mDetectFlg = false;
						if (mMediaPlayer.isPlaying() == true)
						{
							mMediaPlayer.pause();
						}
						mHandler.post(new Runnable()
						{
							public void run()
							{
								mCsView.invalidate();
							}
						});
					}
					
					// 次回実行させるために下準備を行う
					if (mAtSoundStop.getStatus() == AsyncTask.Status.RUNNING)
					{
						mAtSoundStop.cancel(true);
						mAtSoundStop = new AutoStopSounds();
					}
					if (mAtSoundStop.getStatus() == AsyncTask.Status.FINISHED)
					{
						mAtSoundStop = new AutoStopSounds();
					}
				}
				// 戻りを返す
				byte [] SendByte = ("R" + ReadObj + "\\r").getBytes("UTF-8");
				OutputStream OutputSt = mSock.getOutputStream();
				OutputSt.write(SendByte);
				OutputSt.close();
				
				if (mSock != null)
				{
					mSock.close();
					mSock = null;
				}
			}
			catch (IOException IoExc)
			{
				Log.d("CLIENT_SOCKET_THREAD_ERORR", IoExc.toString());
			}
		}
		
		/**
		 * 処理を停止する
		 * ※使用しない
		 */
		public void StopRun()
		{
			
		}
	}
	
	/**
	 * 音声の再生を自動停止させる
	 * @author KMK-Teraoka <tatsuya.teraoka@kmk-ss.co.jp>
	 * @version 2012/10/31
	 */
	public class AutoStopSounds extends AsyncTask<Void, Void, Void>
	{
		@Override
		protected void onPreExecute()
		{
			
		}
		
		@Override
		protected Void doInBackground(Void... params_)
		{
			for(int iCount = 0; iCount < (AUTO_STOP_SECONDS * 2); iCount++)
			{
				try
				{
					if (isCancelled())
					{
						Log.i("AsyncTask", "onCancelled");
						break;
					}
					Thread.sleep(500);
				}
				catch (Exception exc)
				{
					Log.d("AsyncTask", "AutoStopSound doInBackground");
				}
			}
			return null;
		}
		
		@Override
		protected void onCancelled()
		{
			Log.i("Asynctask", "call onCancelled");
		}
		
		@Override
		protected void onPostExecute(Void result_)
		{
			mDetectFlg = false;
			if (mMediaPlayer.isPlaying() == true)
			{
				mMediaPlayer.pause();
			}
			mHandler.post(new Runnable()
			{
				public void run()
				{
					mCsView.invalidate();
				}
			});
		}
	}
	
	/**
	 * 画面を描画する
	 * @author KMK-Teraoka
	 */
	private class CstmView extends View
	{
		public CstmView(Context context)
		{
			super(context);
			setFocusable(true);
		}
		
		/**
		 * 描画を行う
		 */
		@SuppressLint("DrawAllocation") protected void onDraw(Canvas canvas_)
		{
			super.onDraw(canvas_);
			
			int[] ScreenSize = { getWidth(), getHeight() };
			
			Paint PnObj = new Paint();
			PnObj.setStyle(Paint.Style.FILL);
			if (mDetectFlg == false)
			{
				PnObj.setColor(Color.BLUE);
			}
			else
			{
				PnObj.setColor(Color.RED);
			}
			canvas_.drawRect(0, 0, ScreenSize[0], ScreenSize[1], PnObj);
		}
	}
}
