package me.yoqi.flashlight;

import java.io.IOException;
import java.util.List;

import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.Parameters;
import android.os.Build;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.RemoteViews;
import me.yoqi.flashlight.utils.DroidLED;

public class MainActivity extends Activity implements SurfaceHolder.Callback {

	int count = 0;
	static Camera mCamera;
	static Button flashlight_button;
	Parameters params;
	SurfaceView preview;
	SurfaceHolder mHolder;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		preview = (SurfaceView) findViewById(R.id.preview);
		mHolder = preview.getHolder();

		if (MyApplication.getIsFlashOn()) {
			if (FlashlightWidgetReceiver.getmCameraWidget() != null) {
				flashOffWidget();
				setWidgetTo(R.drawable.light_on);
			}

			if (mCamera != null) {
				try {
					flashOffApp();
				} catch (Exception e) {
					e.printStackTrace();
				}

				setWidgetTo(R.drawable.light_on);
			}

			count = 0;
			turnMotorolaOff();
		}

		try {
			mCamera = Camera.open();
		} catch (Exception e) {
			e.printStackTrace();
		}

		flashlight_button = (Button) findViewById(R.id.flashlight_button);
		flashlight_button.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				if (MyApplication.getIsFlashOn()) {
					processOffClick();
				} else {
					processOnClick();
				}

			}
		});

	}

	@Override
	protected void onPause() {
		super.onPause();
		if (!MyApplication.getIsFlashOn()) {
			processOffClick();
		}
	}

	/*
	 * 返回键关闭
	 */
	@Override
	public void onBackPressed() {
		super.onBackPressed();
		processOffClick();
	}

	@Override
	protected void onResume() {
		super.onResume();

		if (MyApplication.getIsFlashOn()) {
			if (FlashlightWidgetReceiver.getmCameraWidget() != null) {

				flashOffWidget();
				setWidgetTo(R.drawable.light_on);

			}

			if (mCamera != null) {

				try {
					flashOffApp();
				} catch (Exception e) {
					e.printStackTrace();
				}

				setWidgetTo(R.drawable.light_on);

			}

			count = 0;
			turnMotorolaOff();

		}

		if (MyApplication.getIsFlashOn()) {
			flashlight_button.setBackgroundResource(R.drawable.light_off);
		} else if (!MyApplication.getIsFlashOn()) {
			flashlight_button.setBackgroundResource(R.drawable.light_on);
		}

	}

	/**
	 * 开
	 */
	@SuppressWarnings("deprecation")
	private void processOnClick() {

		flashlight_button.setBackgroundResource(R.drawable.light_off);
		setWidgetTo(R.drawable.light_off);

		if (mCamera == null) {
			try {
				mHolder.addCallback(this);
				if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {//<11
					mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
				}
				mCamera = Camera.open();
				try {
					if (mHolder != null) {
						mCamera.setPreviewDisplay(mHolder);
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		if (mCamera != null) {
			flashOnApp();
		}

		if (FlashlightWidgetReceiver.getmCameraWidget() != null) {
			flashOnWidget();
		}
		turnMotorolaOn();
	}

	/**
	 * 关
	 */
	private void processOffClick() {

		flashlight_button.setBackgroundResource(R.drawable.light_on);
		setWidgetTo(R.drawable.light_on);

		if (mCamera != null) {
			count = 0;
			flashOffApp();
		}

		if (FlashlightWidgetReceiver.getmCameraWidget() != null) {
			count = 0;
			flashOffWidget();
		}

		turnMotorolaOff();

	}

	private void flashOnApp() {
		this.params = mCamera.getParameters();

		List<String> flashModes = params.getSupportedFlashModes();

		if (flashModes == null) {
			return;
		} else {
			if (count == 0) {
				params.setFlashMode(Parameters.FLASH_MODE_OFF);
				mCamera.setParameters(params);
				preview = (SurfaceView) findViewById(R.id.preview);
				mHolder = preview.getHolder();
				mHolder.addCallback(this);

				try {
					mCamera.startPreview();
				} catch (Exception e) {
					e.printStackTrace();

				}

				MyApplication.setIsFlashOn(true);
			}

			String flashMode = params.getFlashMode();

			if (!Parameters.FLASH_MODE_TORCH.equals(flashMode)) {

				if (flashModes.contains(Parameters.FLASH_MODE_TORCH)) {
					params.setFlashMode(Parameters.FLASH_MODE_TORCH);
					mCamera.setParameters(params);
				} else {
					params.setFlashMode(Parameters.FLASH_MODE_ON);

					mCamera.setParameters(params);
					try {
						mCamera.autoFocus(new AutoFocusCallback() {
							public void onAutoFocus(boolean success, Camera camera) {
								count = 1;
							}
						});
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				MyApplication.setIsFlashOn(true);

			}
		}
	}

	// Turns the LED on when the widget is pressed.
	private void flashOnWidget() {
		FlashlightWidgetReceiver.setParamsWidget(FlashlightWidgetReceiver.getmCameraWidget().getParameters());

		List<String> flashModes = FlashlightWidgetReceiver.getParamsWidget().getSupportedFlashModes();

		if (flashModes == null) {
			return;
		} else {
			if (count == 0) {
				FlashlightWidgetReceiver.getParamsWidget().setFlashMode(Parameters.FLASH_MODE_OFF);
				FlashlightWidgetReceiver.getmCameraWidget().setParameters(FlashlightWidgetReceiver.getParamsWidget());

				try {
					FlashlightWidgetReceiver.getmCameraWidget().startPreview();
				} catch (Exception e) {
					e.printStackTrace();

				}

				MyApplication.setIsFlashOn(true);
			}

			String flashMode = FlashlightWidgetReceiver.getParamsWidget().getFlashMode();

			if (!Parameters.FLASH_MODE_TORCH.equals(flashMode)) {

				if (flashModes.contains(Parameters.FLASH_MODE_TORCH)) {
					FlashlightWidgetReceiver.getParamsWidget().setFlashMode(Parameters.FLASH_MODE_TORCH);
					FlashlightWidgetReceiver.getmCameraWidget()
							.setParameters(FlashlightWidgetReceiver.getParamsWidget());
				} else {
					FlashlightWidgetReceiver.getParamsWidget().setFlashMode(Parameters.FLASH_MODE_ON);

					FlashlightWidgetReceiver.getmCameraWidget()
							.setParameters(FlashlightWidgetReceiver.getParamsWidget());
					try {
						FlashlightWidgetReceiver.getmCameraWidget().autoFocus(new AutoFocusCallback() {
							public void onAutoFocus(boolean success, Camera camera) {
								count = 1;
							}
						});
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				MyApplication.setIsFlashOn(true);

			}
		}
	}

	static void turnMotorolaOn() {
		DroidLED led;
		try {
			led = new DroidLED();
			led.enable(true);
			MyApplication.setIsFlashOn(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// Turns the LED off when the button on the app is pressed.
	private void flashOffApp() {
		mCamera.stopPreview();
		mCamera.release();
		mCamera = null;
		MyApplication.setIsFlashOn(false);
	}

	// Turns the LED off when the widget is pressed.
	private void flashOffWidget() {
		FlashlightWidgetReceiver.getmCameraWidget().stopPreview();
		FlashlightWidgetReceiver.getmCameraWidget().release();
		FlashlightWidgetReceiver.setmCameraWidget(null);
		MyApplication.setIsFlashOn(false);

	}

	// Turns the LED off for some Motorola phones.
	static void turnMotorolaOff() {
		DroidLED led;
		try {
			led = new DroidLED();
			led.enable(false);
			MyApplication.setIsFlashOn(false);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// setWidgetTo changes the widget view to either off or on.
	private void setWidgetTo(int drawable) {
		Context context = this;
		AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
		RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
		ComponentName thisWidget = new ComponentName(context, FlashlightWidgetProvider.class);
		remoteViews.setImageViewResource(R.id.flashlight_widget_imageview, drawable);
		appWidgetManager.updateAppWidget(thisWidget, remoteViews);
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		mHolder = holder;
		mHolder.addCallback(this);
		if (mCamera != null) {
			try {
				mCamera.setPreviewDisplay(mHolder);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		mHolder = holder;
		mHolder.addCallback(this);

		if (mCamera != null) {
			try {
				mCamera.setPreviewDisplay(mHolder);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		mHolder = null;
	}
}
