content: /*
  The contents of this file are subject to the Mozilla Public License
  Version 1.1 (the "License"); you may not use this file except in
  compliance with the License. You may obtain a copy of the License at
  http://www.mozilla.org/MPL/
  
  Software distributed under the License is distributed on an "AS IS"
  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  License for the specific language governing rights and limitations
  under the License.
  
  The Original Code is collection of files collectively known as Open Camera.
  
  The Initial Developer of the Original Code is Almalence Inc.
  Portions created by Initial Developer are Copyright (C) 2013 
  by Almalence Inc. All Rights Reserved.
   */
  
  /* <!-- +++
   package com.almalence.opencam_plus;
   +++ --> */
  // <!-- -+-
  package com.almalence.opencam;
  //-+- -->
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.List;
  
  import android.Manifest;
  import android.annotation.TargetApi;
  import android.app.Activity;
  import android.app.AlertDialog;
  import android.content.Context;
  import android.content.DialogInterface;
  import android.content.DialogInterface.OnDismissListener;
  import android.content.SharedPreferences;
  import android.content.SharedPreferences.Editor;
  import android.content.pm.ActivityInfo;
  import android.content.pm.PackageManager;
  import android.content.res.Resources;
  import android.graphics.ImageFormat;
  import android.graphics.Rect;
  import android.graphics.SurfaceTexture;
  import android.hardware.Camera;
  import android.hardware.Camera.Area;
  import android.media.AudioManager;
  import android.net.Uri;
  import android.opengl.GLSurfaceView;
  import android.os.Build;
  import android.os.Bundle;
  import android.os.CountDownTimer;
  import android.os.Environment;
  import android.os.Handler;
  import android.os.Message;
  import android.os.PowerManager;
  import android.os.StatFs;
  import android.preference.PreferenceFragment;
  import android.preference.PreferenceManager;
  import android.provider.MediaStore;
  import android.support.v4.app.ActivityCompat;
  import android.support.v4.content.ContextCompat;
  import android.util.Log;
  import android.view.Display;
  import android.view.KeyEvent;
  import android.view.MotionEvent;
  import android.view.OrientationEventListener;
  import android.view.Surface;
  import android.view.SurfaceHolder;
  import android.view.SurfaceView;
  import android.view.View;
  import android.view.ViewGroup.LayoutParams;
  import android.view.Window;
  import android.view.WindowManager;
  import android.widget.RelativeLayout;
  import android.widget.Toast;
  
  
  /* <!-- +++
   import com.almalence.opencam_plus.cameracontroller.CameraController;
   import com.almalence.opencam_plus.ui.GLLayer;
   import com.almalence.opencam_plus.ui.GUI;
   import com.almalence.opencam_plus.R;
   +++ --> */
  //<!-- -+-
  import com.almalence.opencam.cameracontroller.CameraController;
  import com.almalence.opencam.ui.GLLayer;
  import com.almalence.opencam.ui.GUI;
  import com.almalence.opencam.R;
  //-+- -->
  
  import com.almalence.sony.cameraremote.SimpleStreamSurfaceView;
  import com.almalence.util.Util;
  
  /***
   * ApplicationScreen - main activity screen with camera functionality
   * 
   * Passes all main events to PluginManager
   ***/
  
  @SuppressWarnings("deprecation")
  abstract public class ApplicationScreen extends Activity implements ApplicationInterface, View.OnClickListener,
  		View.OnTouchListener, SurfaceHolder.Callback, Handler.Callback, Camera.ShutterCallback
  {
  	// >>Description
  	// section with different global parameters available for everyone
  	//
  	// Camera parameters and possibly access to camera instance
  	//
  	// Global defines and others
  	//
  	// Description<<
  
  	public static ApplicationScreen		instance;
  	public Context						mainContext;
  	protected Handler					messageHandler;
  
  	// Interface to Camera2 camera and Old style camera
  	protected CameraController			cameraController			= null;
  
  	protected int						captureFormat				= CameraController.JPEG;
  
  	public GUI							guiManager					= null;
  
  	protected PluginManagerBase			pluginManager				= null;
  
  	// OpenGL layer. May be used to allow capture plugins to draw overlaying
  	// preview, such as night vision or panorama frames.
  	protected GLLayer					glView;
  
  	protected boolean					mPausing					= false;
  
  	protected SurfaceHolder				surfaceHolder;
  	protected SurfaceView				preview;
  	protected Surface					mCameraSurface				= null;
  	protected OrientationEventListener	orientListener;
  	protected boolean					landscapeIsNormal			= false;
  	protected boolean					surfaceCreated				= false;
  
  	protected int						surfaceWidth				= 0;
  	protected int						surfaceHeight				= 0;
  	//
  	protected int						surfaceLayoutWidth			= 0;
  	protected int						surfaceLayoutHeight			= 0;
  
  	// shared between activities
  	// protected int imageWidth, imageHeight;
  	protected int						previewWidth, previewHeight;
  
  	protected CountDownTimer			screenTimer					= null;
  	protected boolean					isScreenTimerRunning		= false;
  
  	protected static boolean			wantLandscapePhoto			= false;
  	protected int						orientationMain				= 0;
  	protected int						orientationMainPrevious		= 0;
  
  	protected SoundPlayer				shutterPlayer				= null;
  
  	// Common preferences
  	protected boolean					keepScreenOn				= false;
  
  	protected static boolean			mAFLocked					= false;
  	// // shows if mode is currently switching
  	protected boolean					switchingMode				= false;
  
  	// >>Description
  	// section with initialize, resume, start, stop procedures, preferences
  	// access
  	//
  	// Initialize, stop etc depends on plugin type.
  	//
  	// Create main GUI controls and plugin specific controls.
  	//
  	// Description<<
  
  	protected static boolean			mApplicationStarted			= false;
  	protected static boolean			mCameraStarted				= false;
  	protected static boolean			isForceClose				= false;
  
  	protected static final int			VOLUME_FUNC_SHUTTER			= 0;
  	protected static final int			VOLUME_FUNC_EXPO			= 2;
  	protected static final int			VOLUME_FUNC_NONE			= 3;
  
  	protected static List<Area>			mMeteringAreaMatrix5		= new ArrayList<Area>();
  	protected static List<Area>			mMeteringAreaMatrix4		= new ArrayList<Area>();
  	protected static List<Area>			mMeteringAreaMatrix1		= new ArrayList<Area>();
  	protected static List<Area>			mMeteringAreaCenter			= new ArrayList<Area>();
  	protected static List<Area>			mMeteringAreaSpot			= new ArrayList<Area>();
  
  	protected int						currentMeteringMode			= -1;
  
  	public static String				sInitModeListPref			= "initModeListPref";
  
  	public static String				sEvPref;
  	public static String				sExposureTimeModePref;
  	public static String				sRealExposureTimeOnPreviewPref;
  	public static String				sExposureTimePref;
  	public static String				sFocusDistanceModePref;
  	public static String				sFocusDistancePref;
  	public static String				sSceneModePref;
  	public static String				sWBModePref;
  	public static String				sColorTemperaturePref;
  	public static String				sFrontFocusModePref;
  	public static String				sFrontFocusModeVideoPref;
  	public static String				sRearFocusModePref;
  	public static String				sRearFocusModeVideoPref;
  	public static String				sFrontColorEffectPref;
  	public static String				sRearColorEffectPref;
  	public static String				sFlashModePref;
  	public static String				sISOPref;
  	public static String				sMeteringModePref;
  	public static String				sCameraModePref;
  
  	public static String				sUseFrontCameraPref;
  
  	public static String				sImageSizeRearPref;
  	public static String				sImageSizeFrontPref;
  	public static String				sImageSizeSonyRemotePref;
  
  	public static String				sImageSizeMultishotBackPref;
  	public static String				sImageSizeMultishotFrontPref;
  	public static String				sImageSizeMultishotSonyRemotePref;
  
  	public static String				sImageSizePanoramaBackPref;
  	public static String				sImageSizePanoramaFrontPref;
  	public static String				sImageSizeVideoBackPref;
  	public static String				sImageSizeVideoFrontPref;
  	public static String				sCaptureRAWPref;
  	public static String				sJPEGQualityPref;
  	public static String				sAntibandingPref;
  	public static String				sAELockPref;
  	public static String				sAWBLockPref;
  	public static String				sSavePathPref;
  	public static String				sExportNamePref;
  	public static String				sExportNameSeparatorPref;
  	public static String				sExportNamePrefixPref;
  	public static String				sExportNamePostfixPref;
  	public static String				sSaveToPref;
  	public static String				sSortByDataPref;
  	public static String				sEnableExifOrientationTagPref;
  	public static String				sAdditionalRotationPref;
  	public static String				sUseGeotaggingPref;
  
  	public static String				sTimestampDate;
  	public static String				sTimestampAbbreviation;
  	public static String				sTimestampTime;
  	public static String				sTimestampGeo;
  	public static String				sTimestampSeparator;
  	public static String				sTimestampCustomText;
  	public static String				sTimestampColor;
  	public static String				sTimestampFontSize;
  	public static String				sExpoPreviewModePref;
  
  	public static String				sDefaultModeName;
  	public static int					sDefaultValue				= CameraParameters.SCENE_MODE_AUTO;
  	public static int					sDefaultFocusValue				= CameraParameters.AF_MODE_CONTINUOUS_PICTURE;
  	public static int					sDefaultFlashValue				= CameraParameters.FLASH_MODE_OFF;
  	public static int					sDefaultISOValue				= CameraParameters.ISO_AUTO;
  	public static int					sDefaultMeteringValue			= CameraParameters.meteringModeAuto;
  	public static Long					lDefaultExposureTimeValue		= 33333333L;
  	public static int					sDefaultColorEffectValue		= CameraParameters.COLOR_EFFECT_MODE_OFF;
  	public static int					iDefaultColorTemperatureValue	= 6500;
  	public static int					iMinColorTemperatureValue		= 1000;
  	public static int					iMaxColorTemperatureValue		= 10000;
  
  	private static File					forceFilename					= null;
  	private static Uri					forceFilenameUri;
  	
  	private final static int			CAMERA_PERMISSION_CODE			= 0;
  	protected static boolean			cameraPermissionGranted			= false;
  	
  	private final static int			LOCATION_PERMISSION_CODE		= 1;
  	protected static boolean			locationPermissionGranted		= false;
  	
  	private final static int			MICROPHONE_PERMISSION_CODE		= 2;
  	protected static boolean			microphonePermissionGranted		= false;
  	
  	private final static int			STORAGE_PERMISSION_CODE			= 3;
  	protected static boolean			storagePermissionGranted		= false;
  
  	public void onCreate(Bundle savedInstanceState)
  	{
  		super.onCreate(savedInstanceState);
  
  		sEvPref = getResources().getString(R.string.Preference_EvCompensationValue);
  		sSceneModePref = getResources().getString(R.string.Preference_SceneModeValue);
  		sWBModePref = getResources().getString(R.string.Preference_WBModeValue);
  		sColorTemperaturePref = getResources().getString(R.string.Preference_ColorTemperatureValue);
  		sFrontFocusModePref = getResources().getString(R.string.Preference_FrontFocusModeValue);
  		sFrontFocusModeVideoPref = getResources().getString(R.string.Preference_FrontFocusModeVideoValue);
  		sRearFocusModePref = getResources().getString(R.string.Preference_RearFocusModeValue);
  		sRearFocusModeVideoPref = getResources().getString(R.string.Preference_RearFocusModeVideoValue);
  		sFrontColorEffectPref = getResources().getString(R.string.Preference_FrontColorEffectValue);
  		sRearColorEffectPref = getResources().getString(R.string.Preference_RearColorEffectValue);
  		sFlashModePref = getResources().getString(R.string.Preference_FlashModeValue);
  		sISOPref = getResources().getString(R.string.Preference_ISOValue);
  		sMeteringModePref = getResources().getString(R.string.Preference_MeteringModeValue);
  		sExposureTimePref = getResources().getString(R.string.Preference_ExposureTimeValue);
  		sExposureTimeModePref = getResources().getString(R.string.Preference_ExposureTimeModeValue);
  		sRealExposureTimeOnPreviewPref = getResources().getString(R.string.Preference_RealExposureTimeOnPreviewValue);
  		sFocusDistancePref = getResources().getString(R.string.Preference_FocusDistanceValue);
  		sFocusDistanceModePref = getResources().getString(R.string.Preference_FocusDistanceModeValue);
  		sCameraModePref = getResources().getString(R.string.Preference_CameraModeValue);
  
  		sUseFrontCameraPref = getResources().getString(R.string.Preference_UseFrontCameraValue);
  
  		sImageSizeRearPref = getResources().getString(R.string.Preference_ImageSizeRearValue);
  		sImageSizeFrontPref = getResources().getString(R.string.Preference_ImageSizeFrontValue);
  		sImageSizeSonyRemotePref = getResources().getString(R.string.Preference_ImageSizeSonyRemoteValue);
  
  		sImageSizeMultishotBackPref = getResources()
  				.getString(R.string.Preference_ImageSizePrefSmartMultishotBackValue);
  		sImageSizeMultishotFrontPref = getResources().getString(
  				R.string.Preference_ImageSizePrefSmartMultishotFrontValue);
  		sImageSizeMultishotSonyRemotePref = getResources().getString(
  				R.string.Preference_ImageSizePrefSmartMultishotSonyRemoteValue);
  
  		sImageSizePanoramaBackPref = getResources().getString(R.string.Preference_ImageSizePrefPanoramaBackValue);
  		sImageSizePanoramaFrontPref = getResources().getString(R.string.Preference_ImageSizePrefPanoramaFrontValue);
  
  		sImageSizeVideoBackPref = getResources().getString(R.string.Preference_ImageSizePrefVideoBackValue);
  		sImageSizeVideoFrontPref = getResources().getString(R.string.Preference_ImageSizePrefVideoFrontValue);
  
  		sCaptureRAWPref = getResources().getString(R.string.Preference_CaptureRAWValue);
  
  		sJPEGQualityPref = getResources().getString(R.string.Preference_JPEGQualityCommonValue);
  
  		sAntibandingPref = getResources().getString(R.string.Preference_AntibandingValue);
  
  		sExportNamePref = getResources().getString(R.string.Preference_ExportNameValue);
  		sExportNameSeparatorPref = getResources().getString(R.string.Preference_ExportNameSeparatorValue);
  		sExportNamePrefixPref = getResources().getString(R.string.Preference_SavePathPrefixValue);
  		sExportNamePostfixPref = getResources().getString(R.string.Preference_SavePathPostfixValue);
  		sSavePathPref = getResources().getString(R.string.Preference_SavePathValue);
  		sSaveToPref = getResources().getString(R.string.Preference_SaveToValue);
  		sSortByDataPref = getResources().getString(R.string.Preference_SortByDataValue);
  		sEnableExifOrientationTagPref = getResources().getString(R.string.Preference_EnableExifTagOrientationValue);
  		sAdditionalRotationPref = getResources().getString(R.string.Preference_AdditionalRotationValue);
  		sUseGeotaggingPref = getResources().getString(R.string.Preference_UseGeotaggingValue);
  
  		sTimestampDate = getResources().getString(R.string.Preference_TimestampDateValue);
  		sTimestampAbbreviation = getResources().getString(R.string.Preference_TimestampAbbreviationValue);
  		sTimestampTime = getResources().getString(R.string.Preference_TimestampTimeValue);
  		sTimestampGeo = getResources().getString(R.string.Preference_TimestampGeoValue);
  		sTimestampSeparator = getResources().getString(R.string.Preference_TimestampSeparatorValue);
  		sTimestampCustomText = getResources().getString(R.string.Preference_TimestampCustomTextValue);
  		sTimestampColor = getResources().getString(R.string.Preference_TimestampColorValue);
  		sTimestampFontSize = getResources().getString(R.string.Preference_TimestampFontSizeValue);
  
  		sAELockPref = getResources().getString(R.string.Preference_AELockValue);
  		sAWBLockPref = getResources().getString(R.string.Preference_AWBLockValue);
  
  		sExpoPreviewModePref = getResources().getString(R.string.Preference_ExpoBracketingPreviewModePref);
  
  		sDefaultModeName = getResources().getString(R.string.Preference_DefaultModeName);
  
  		mainContext = this.getBaseContext();
  		messageHandler = new Handler(this);
  		instance = this;
  		
  		surfaceCreated = false;
  
  		requestWindowFeature(Window.FEATURE_NO_TITLE);
  		// ensure landscape orientation
  		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  		// set to fullscreen
  		getWindow().addFlags(
  				WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
  						| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
  		
  		createPluginManager();
  		duringOnCreate();
  
  		try
  		{
  			cameraController = CameraController.getInstance();
  		} catch (VerifyError exp)
  		{
  			Log.e("ApplicationScreen", exp.getMessage());
  		}
  		CameraController.onCreate(ApplicationScreen.instance, ApplicationScreen.instance, pluginManager,
  				ApplicationScreen.instance.messageHandler);
  
  		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ApplicationScreen.getMainContext());
  		keepScreenOn = prefs.getBoolean("keepScreenOn", false);
  
  		orientListener = new OrientationEventListener(this)
  		{
  			@Override
  			public void onOrientationChanged(int orientation)
  			{
  				// figure landscape or portrait
  				if (ApplicationScreen.instance.landscapeIsNormal)
  				{
  					orientation += 90;
  				}
  
  				if ((orientation < 45) || (orientation > 315 && orientation < 405)
  						|| ((orientation > 135) && (orientation < 225)))
  				{
  					if (ApplicationScreen.wantLandscapePhoto)
  					{
  						ApplicationScreen.wantLandscapePhoto = false;
  					}
  				} else
  				{
  					if (!ApplicationScreen.wantLandscapePhoto)
  					{
  						ApplicationScreen.wantLandscapePhoto = true;
  					}
  				}
  
  				// orient properly for video
  				if ((orientation > 135) && (orientation < 225))
  					orientationMain = 270;
  				else if ((orientation < 45) || (orientation > 315))
  					orientationMain = 90;
  				else if ((orientation < 325) && (orientation > 225))
  					orientationMain = 0;
  				else if ((orientation < 135) && (orientation > 45))
  					orientationMain = 180;
  
  				if (orientationMain != orientationMainPrevious)
  				{
  					orientationMainPrevious = orientationMain;
  				}
  			}
  		};
  
  		// prevent power drain
  		screenTimer = new CountDownTimer(180000, 180000)
  		{
  			public void onTick(long millisUntilFinished)
  			{
  				// Not used
  			}
  
  			public void onFinish()
  			{
  				boolean isVideoRecording = PreferenceManager.getDefaultSharedPreferences(
  						ApplicationScreen.getMainContext()).getBoolean("videorecording", false);
  				if (isVideoRecording || keepScreenOn)
  				{
  					// restart timer
  					screenTimer.start();
  					isScreenTimerRunning = true;
  					if (preview != null)
  					{
  						preview.setKeepScreenOn(true);
  					}
  					return;
  				}
  				if (preview != null)
  				{
  					preview.setKeepScreenOn(keepScreenOn);
  				}
  				isScreenTimerRunning = false;
  			}
  		};
  		screenTimer.start();
  		isScreenTimerRunning = true;
  
  		if (this.getIntent().getAction() != null)
  		{
  			if (this.getIntent().getAction().equals(MediaStore.ACTION_IMAGE_CAPTURE))
  			{
  				try
  				{
  					forceFilenameUri = this.getIntent().getExtras().getParcelable(MediaStore.EXTRA_OUTPUT);
  					ApplicationScreen.setForceFilename(new File(((Uri) forceFilenameUri).getPath()));
  					if (ApplicationScreen.getForceFilename().getAbsolutePath().equals("/scrapSpace"))
  					{
  						ApplicationScreen.setForceFilename(new File(Environment.getExternalStorageDirectory()
  								.getAbsolutePath() + "/mms/scrapSpace/.temp.jpg"));
  						new File(ApplicationScreen.getForceFilename().getParent()).mkdirs();
  					}
  				} catch (Exception e)
  				{
  					ApplicationScreen.setForceFilename(null);
  				}
  			} else
  			{
  				ApplicationScreen.setForceFilename(null);
  			}
  		} else
  		{
  			ApplicationScreen.setForceFilename(null);
  		}
  
  		afterOnCreate();
  	}
  	
  	private void showRationaly(final String permission)
  	{
  		int titleId = 0;
  		int messageId = 0;
  		int permissionCodeTemp = -1;
  		String[] permissionsTemp = null;
  		
  		if (permission.contains(Manifest.permission.CAMERA))
  		{
  			titleId = R.string.camera_permission_rationaly_title;
  			messageId = R.string.camera_permission_rationaly_message;
  			permissionCodeTemp = ApplicationScreen.CAMERA_PERMISSION_CODE;
  			permissionsTemp = new String[]{Manifest.permission.CAMERA};
  		}
  		
  		if (permission.contains(Manifest.permission.ACCESS_COARSE_LOCATION) || permission.contains(Manifest.permission.ACCESS_FINE_LOCATION))
  		{
  			titleId = R.string.location_permission_rationaly_title;
  			messageId = R.string.location_permission_rationaly_message;
  			permissionCodeTemp = ApplicationScreen.LOCATION_PERMISSION_CODE;
  			permissionsTemp = new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
  		}
  		
  		if (permission.contains(Manifest.permission.RECORD_AUDIO))
  		{
  			titleId = R.string.microphone_permission_rationaly_title;
  			messageId = R.string.microphone_permission_rationaly_message;
  			permissionCodeTemp = ApplicationScreen.MICROPHONE_PERMISSION_CODE;
  			permissionsTemp = new String[]{Manifest.permission.RECORD_AUDIO};
  		}
  		
  		if (permission.contains(Manifest.permission.WRITE_EXTERNAL_STORAGE) || permission.contains(Manifest.permission.READ_EXTERNAL_STORAGE))
  		{
  			titleId = R.string.storage_permission_rationaly_title;
  			messageId = R.string.storage_permission_rationaly_message;
  			permissionCodeTemp = ApplicationScreen.STORAGE_PERMISSION_CODE;
  			permissionsTemp = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};
  		}
  		
  		final int permissionCode = permissionCodeTemp;
  		final String[] permissions = permissionsTemp;
  		
  		if (titleId != 0 && messageId != 0 && permissionCode != -1 && permissions != null)
  		{
  			new AlertDialog.Builder(this)
  			.setTitle(titleId)
  			.setMessage(messageId)
  			.setCancelable(true)
  			.setIcon(android.R.drawable.ic_dialog_alert)
  			.setOnDismissListener(new OnDismissListener()
  			{
  				@Override
  				public void onDismiss(DialogInterface dialog)
  				{
  					ActivityCompat.requestPermissions(ApplicationScreen.instance, permissions, permissionCode);
  				}
  			}).show();
  		}
  	}
  	
  	@TargetApi(23)
  	protected void checkCameraPermission()
  	{
  		if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
  		{
  			cameraPermissionGranted = false;
  		    // Should we show an explanation?
  		    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA))
  		    {
  		        // Show an explanation to the user *asynchronously* -- don't block
  		        // this thread waiting for the user's response! After the user
  		        // sees the explanation, try again to request the permission.
  		    	showRationaly(Manifest.permission.CAMERA);
  		    }
  		    else 
  		    {
  		
  		        // No explanation needed, we can request the permission.
  		        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, ApplicationScreen.CAMERA_PERMISSION_CODE);
  		    }
  		}
  		else
  			cameraPermissionGranted = true;
  	}
  	
  	@TargetApi(23)
  	public void checkLocationPermission()
  	{
  		if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
  		{
  			locationPermissionGranted = false;
  		    // Should we show an explanation?
  		    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION))
  		    {
  		        // Show an explanation to the user *asynchronously* -- don't block
  		        // this thread waiting for the user's response! After the user
  		        // sees the explanation, try again to request the permission.
  		    	showRationaly(Manifest.permission.ACCESS_FINE_LOCATION);
  		    }
  		    else 
  		    {
  		
  		        // No explanation needed, we can request the permission.
  		        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, ApplicationScreen.LOCATION_PERMISSION_CODE);
  		    }
  		}
  		else
  			locationPermissionGranted = true;
  	}
  	
  	@TargetApi(23)
  	public void checkMicrophonePermission()
  	{
  		if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED)
  		{
  			microphonePermissionGranted = false;
  		    // Should we show an explanation?
  		    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO))
  		    {
  		        // Show an explanation to the user *asynchronously* -- don't block
  		        // this thread waiting for the user's response! After the user
  		        // sees the explanation, try again to request the permission.
  		    	showRationaly(Manifest.permission.RECORD_AUDIO);
  		    }
  		    else 
  		    {
  		        // No explanation needed, we can request the permission.
  		        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, ApplicationScreen.MICROPHONE_PERMISSION_CODE);
  		    }
  		}
  		else
  			microphonePermissionGranted = true;
  	}
  	
  	@TargetApi(23)
  	public void checkStoragePermission()
  	{
  		if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
  		{
  			storagePermissionGranted = false;
  		    // Should we show an explanation?
  		    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE))
  		    {
  		        // Show an explanation to the user *asynchronously* -- don't block
  		        // this thread waiting for the user's response! After the user
  		        // sees the explanation, try again to request the permission.
  		    	showRationaly(Manifest.permission.WRITE_EXTERNAL_STORAGE);
  		    }
  		    else 
  		    {
  		        // No explanation needed, we can request the permission.
  		        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, ApplicationScreen.STORAGE_PERMISSION_CODE);
  		    }
  		}
  		else
  			storagePermissionGranted = true;
  	}
  	
  	@Override
  	public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
  	{
  		boolean permissionResult = false;
  	
  		// If request is cancelled, the result arrays are empty.
  		if (grantResults.length > 0)
      	{
      		for (int result : grantResults)
      		{
      			// If any of requested permission is granted, we consider that as success.
      			if (result == PackageManager.PERMISSION_GRANTED)
      			{
      				permissionResult = true;
      			}
      		}
      	}
  		
  	    switch (requestCode)
  	    {
  	        case ApplicationScreen.CAMERA_PERMISSION_CODE:
  	        {
              	cameraPermissionGranted = permissionResult;
              	return;
  	        }
  	        case ApplicationScreen.LOCATION_PERMISSION_CODE:
  	        {
  				locationPermissionGranted = permissionResult;
  	        	return;
  	        }
  	        case ApplicationScreen.MICROPHONE_PERMISSION_CODE:
  	        {
      			microphonePermissionGranted = permissionResult;
      			//restart camera if granted. on Nexus 5 camera hangs without restart.
      			if (microphonePermissionGranted)
      				relaunchCamera();
      			
  	        	return;
  	        }
  	        case ApplicationScreen.STORAGE_PERMISSION_CODE:
  	        {
  	        	if (grantResults.length > 0)
  	        	{
  	        		permissionResult = true;
  	        		for (int result : grantResults)
  	        		{
  	        			// For storage permissions we should check, that all permissions are granted.
  	        			// If one of storage permissions isn't granted, then we don't have enough access to device's memory.
  	        			// It means, that we can't read or write files. So we treat it as we don't have access to storage at all.
  	        			if (result != PackageManager.PERMISSION_GRANTED)
  	        			{
  	        				permissionResult = false;
  	        			}
  	        		}
  	        	}
  	        	
  	        	storagePermissionGranted = permissionResult;
  	        	return;
  	        }
  	    }
  	}
  	
  	public static boolean isCameraPermissionGranted()
  	{
  		return cameraPermissionGranted;
  	}
  	
  	public static boolean isLocationPermissionGranted()
  	{
  		return locationPermissionGranted;
  	}
  	
  	public static boolean isMicrophonePermissionGranted()
  	{
  		return microphonePermissionGranted;
  	}
  
  	public static boolean isStoragePermissionGranted()
  	{
  		return storagePermissionGranted;
  	}
  	
  	abstract protected void createPluginManager();
  
  	public static PluginManagerBase getPluginManager()
  	{
  		return ApplicationScreen.instance.pluginManager;
  	}
  
  	// At this point CameraController, GUIManager are not created yet.
  	// Use this method to initialize some shared preferences or do any other
  	// logic that isn't depended from OpenCamera core's objects.
  	abstract protected void duringOnCreate();
  
  	// At this point all OpenCamera main objects are created.
  	abstract protected void afterOnCreate();
  
  	public static Context getMainContext()
  	{
  		return instance.mainContext;
  	}
  
  	public static Handler getMessageHandler()
  	{
  		return instance.messageHandler;
  	}
  
  	public static CameraController getCameraController()
  	{
  		return instance.cameraController;
  	}
  
  	public static GUI getGUIManager()
  	{
  		return instance.guiManager;
  	}
  
  	public static SurfaceHolder getPreviewSurfaceHolder()
  	{
  		return instance.surfaceHolder;
  	}
  
  	public static SurfaceView getPreviewSurfaceView()
  	{
  		return instance.preview;
  	}
  
  	public static int getCaptureFormat()
  	{
  		return instance.captureFormat;
  	}
  
  	public static void setCaptureFormat(int capture)
  	{
  		if (!CameraController.isRemoteCamera()) {			
  			if(CameraController.isCaptureFormatSupported(capture))
  			{
  				instance.captureFormat = capture;
  				
  				if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
  					CameraController.setCaptureFormat(capture);
  			}
  			else if(CameraController.isCaptureFormatSupported(CameraController.JPEG))
  			{
  				instance.captureFormat = CameraController.JPEG;
  				
  				if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
  					CameraController.setCaptureFormat(CameraController.JPEG);
  			}
  		} else {
  			instance.captureFormat = CameraController.JPEG;
  		}
  	}
  
  	public static int getPreviewSurfaceLayoutWidth()
  	{
  		return instance.surfaceLayoutWidth;
  	}
  
  	public static int getPreviewSurfaceLayoutHeight()
  	{
  		return instance.surfaceLayoutHeight;
  	}
  
  	public static void setPreviewSurfaceLayoutWidth(int width)
  	{
  		instance.surfaceLayoutWidth = width;
  	}
  
  	public static void setPreviewSurfaceLayoutHeight(int height)
  	{
  		instance.surfaceLayoutHeight = height;
  	}
  
  	// Return true, if surface is resized or changed.
  	// return false, if changes are not required.
  	public static boolean setSurfaceHolderSize(int width, int height)
  	{
  		if (instance.surfaceWidth != width && instance.surfaceHeight != height)
  		{
  			if (instance.surfaceWidth != 0 && instance.surfaceHeight != 0)
  			{
  				// We can't change size of surfaceHolder. That's why, we replace the preview View with new one.
  				((RelativeLayout) ApplicationScreen.instance.findViewById(R.id.mainLayout2)).removeView(ApplicationScreen.instance.preview);
  				
  				ApplicationScreen.instance.preview = new SurfaceView(ApplicationScreen.instance);
  				ApplicationScreen.instance.surfaceHolder = ApplicationScreen.instance.preview.getHolder();
  				ApplicationScreen.instance.surfaceHolder.addCallback(ApplicationScreen.instance);
  				ApplicationScreen.instance.preview.setVisibility(View.VISIBLE);
  				ApplicationScreen.instance.preview.setOnClickListener(ApplicationScreen.instance);
  				ApplicationScreen.instance.preview.setOnTouchListener(ApplicationScreen.instance);
  				ApplicationScreen.instance.preview.setKeepScreenOn(true);
  				ApplicationScreen.instance.preview.setId(R.id.SurfaceView01);
  				
  				((RelativeLayout) ApplicationScreen.instance.findViewById(R.id.mainLayout2)).addView(ApplicationScreen.instance.preview, 0);
  			}
  			
  			if (ApplicationScreen.instance.surfaceHolder != null)
  			{
  				instance.surfaceWidth = width;
  				instance.surfaceHeight = height;
  				
  				instance.mCameraSurface = null;
  				instance.surfaceHolder.setFixedSize(width, height);
  			}
  			
  			if (instance.glView != null)
  			{
  				if (instance.glView.getSurfaceTexture() != null)
  				{
  					instance.glView.getSurfaceTexture().setDefaultBufferSize(width, height);
  				}
  			}
  			
  			return true;
  		}
  		
  		return false;
  	}
  
  	abstract public int getImageSizeIndex();
  
  	abstract public int getMultishotImageSizeIndex();
  
  	abstract public boolean isShutterSoundEnabled();
  
  	abstract public int isShotOnTap();
  
  	public static int getOrientation()
  	{
  		return instance.orientationMain;
  	}
  
  	public static int getMeteringMode()
  	{
  		return instance.currentMeteringMode;
  	}
  
  	abstract public void onPreferenceCreate(PreferenceFragment prefActivity);
  
  	abstract public void onAdvancePreferenceCreate(PreferenceFragment prefActivity);
  
  	public void glSetRenderingMode(final int renderMode)
  	{
  		if (renderMode != GLSurfaceView.RENDERMODE_WHEN_DIRTY && renderMode != GLSurfaceView.RENDERMODE_CONTINUOUSLY)
  		{
  			throw new IllegalArgumentException();
  		}
  
  		final GLSurfaceView surfaceView = glView;
  		if (surfaceView != null)
  		{
  			surfaceView.setRenderMode(renderMode);
  		}
  	}
  
  	public void glRequestRender()
  	{
  		final GLSurfaceView surfaceView = glView;
  		if (surfaceView != null)
  		{
  			surfaceView.requestRender();
  		}
  	}
  
  	public void queueGLEvent(final Runnable runnable)
  	{
  		final GLSurfaceView surfaceView = glView;
  
  		if (surfaceView != null && runnable != null)
  		{
  			surfaceView.queueEvent(runnable);
  		}
  	}
  
  	public int glGetPreviewTexture()
  	{
  		if (glView != null)
  		{
  			return glView.getPreviewTexture();
  		}
  		
  		return 0;
  	}
  
  	public SurfaceTexture glGetSurfaceTexture()
  	{
  		if (glView != null)
  		{
  			return glView.getSurfaceTexture();
  		}
  		
  		return null;
  	}
  
  	@Override
  	protected void onStart()
  	{
  		super.onStart();
  		onApplicationStart();
  	}
  
  	protected void onApplicationStart()
  	{
  		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ApplicationScreen.getMainContext());
  		int cameraSelected = prefs.getInt(ApplicationScreen.sCameraModePref, 0);
  		if (cameraSelected == CameraController.getNumberOfCameras() - 1)
  		{
  			prefs.edit().putInt(ApplicationScreen.sCameraModePref, 0).commit();
  			ApplicationScreen.getGUIManager().setCameraModeGUI(0);
  		}
  
  		CameraController.onStart();
  		ApplicationScreen.getGUIManager().onStart();
  		ApplicationScreen.getPluginManager().onStart();
  	}
  
  	@Override
  	protected void onStop()
  	{
  		super.onStop();
  		onApplicationStop();
  	}
  
  	protected void onApplicationStop()
  	{
  		switchingMode = false;
  		mApplicationStarted = false;
  		orientationMain = 0;
  		orientationMainPrevious = 0;
  		ApplicationScreen.getGUIManager().onStop();
  		ApplicationScreen.getPluginManager().onStop();
  		CameraController.onStop();
  	}
  
  	abstract protected void stopRemotePreview();
  
  	@Override
  	protected void onDestroy()
  	{
  		super.onDestroy();		
  		onApplicationDestroy();
  	}
  
  	protected void onApplicationDestroy()
  	{
  		ApplicationScreen.getGUIManager().onDestroy();
  		ApplicationScreen.getPluginManager().onDestroy();
  		CameraController.onDestroy();
  
  		this.hideOpenGLLayer();
  	}
  
  //	protected CountDownTimer	onResumeTimer	= null;
  
  	@Override
  	protected void onResume()
  	{
  		super.onResume();
  	
  		checkCameraPermission();
  		if (!cameraPermissionGranted)
  			return;
  		
  		checkStoragePermission();
  		if (!storagePermissionGranted)
  			return;
  		
  		onApplicationResume();
  	}
  
  	protected void onApplicationResume()
  	{
  		isCameraConfiguring = false;
  		
  		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ApplicationScreen
  				.getMainContext());
  
  		preview.setKeepScreenOn(true);
  
  		captureFormat = CameraController.JPEG;
  
  		String modeId = ApplicationScreen.getPluginManager().getActiveModeID();
  		if (CameraController.isRemoteCamera() && !(modeId.contains("single") || modeId.contains("video")))
  		{
  			prefs.edit().putInt(ApplicationScreen.sCameraModePref, 0).commit();
  			CameraController.setCameraIndex(0);
  			guiManager.setCameraModeGUI(0);
  		}
  
  		CameraController.onResume();
  		ApplicationScreen.getGUIManager().onResume();
  		ApplicationScreen.getPluginManager().onResume();
  		
  		ApplicationScreen.instance.mPausing = false;
  
  		if (!CameraController.isRemoteCamera())
  		{
  			// set preview, on click listener and surface buffers
  			findViewById(R.id.SurfaceView02).setVisibility(View.GONE);
  			preview = (SurfaceView) findViewById(R.id.SurfaceView01);
  			preview.setOnClickListener(ApplicationScreen.this);
  			preview.setOnTouchListener(ApplicationScreen.this);
  			preview.setKeepScreenOn(true);
  
  			surfaceHolder = preview.getHolder();
  			surfaceHolder.addCallback(ApplicationScreen.this);
  
  			// One of device camera is selected.
  			if (CameraController.isUseCamera2())
  			{
  				ApplicationScreen.instance.findViewById(R.id.mainLayout2).setVisibility(View.VISIBLE);
  				CameraController.setupCamera(null, true);
  
  				if (glView != null)
  					glView.onResume();
  			} else if ((surfaceCreated && (!CameraController.isCameraCreated())))
  			{
  				ApplicationScreen.instance.findViewById(R.id.mainLayout2).setVisibility(View.VISIBLE);
  				CameraController.setupCamera(surfaceHolder, true);
  
  				if (glView != null)
  				{
  					glView.onResume();
  				}
  			}
  		} else
  		{
  			sonyCameraSelected();
  		}
  		orientListener.enable();
  
  
  		shutterPlayer = new SoundPlayer(this.getBaseContext(), getResources().openRawResourceFd(
  				R.raw.plugin_capture_tick));
  
  		if (screenTimer != null)
  		{
  			if (isScreenTimerRunning)
  				screenTimer.cancel();
  			screenTimer.start();
  			isScreenTimerRunning = true;
  		}
  
  		long memoryFree = getAvailableInternalMemory();
  		if (memoryFree < 30)
  			Toast.makeText(ApplicationScreen.getMainContext(), "Almost no free space left on internal storage.",
  					Toast.LENGTH_LONG).show();
  
  		boolean dismissKeyguard = prefs.getBoolean("dismissKeyguard", true);
  		if (dismissKeyguard)
  			getWindow()
  					.addFlags(
  							WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
  									| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
  		else
  		{
  			getWindow()
  					.clearFlags(
  							WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
  									| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
  		}
  	}
  
  	@Override
  	public void relaunchCamera()
  	{
  		if (!CameraController.isRemoteCamera())
  		{
  			if (CameraController.isUseCamera2() || ApplicationScreen.getPluginManager().isRestart())
  			{
  				new CountDownTimer(100, 100)
  				{
  					public void onTick(long millisUntilFinished)
  					{
  						// Not used
  					}
  
  					public void onFinish()
  					{
  						ApplicationScreen.getPluginManager().switchMode(
  								ConfigParser.getInstance().getMode(
  										ApplicationScreen.getPluginManager().getActiveModeID()));
  					}
  				}.start();
  			} else
  			{
  				// Need this for correct exposure control state, after switching
  				// DRO-on/DRO-off in single mode.
  				guiManager.onPluginsInitialized();
  			}
  		} else
  		{
  			ApplicationScreen.getGUIManager().setCameraModeGUI(0);
  			ApplicationScreen.instance.pauseMain();
  			ApplicationScreen.instance.switchingMode(false);
  			ApplicationScreen.instance.resumeMain();
  		}
  	}
  
  	protected long getAvailableInternalMemory()
  	{
  		File path = Environment.getDataDirectory();
  		StatFs stat = new StatFs(path.getPath());
  		long blockSize = stat.getBlockSize();
  		long availableBlocks = stat.getAvailableBlocks();
  		return availableBlocks * blockSize / 1048576;
  	}
  
  	@Override
  	protected void onPause()
  	{
  		super.onPause();
  		onApplicationPause();
  	}
  
  	protected void onApplicationPause()
  	{
  		mApplicationStarted = false;
  
  		ApplicationScreen.getGUIManager().onPause();
  		ApplicationScreen.getPluginManager().onPause(true);
  
  		orientListener.disable();
  
  		this.mPausing = true;
  
  		this.hideOpenGLLayer();
  
  		if (screenTimer != null)
  		{
  			if (isScreenTimerRunning)
  				screenTimer.cancel();
  			isScreenTimerRunning = false;
  		}
  
  		CameraController.onPause(true);
  
  		if (CameraController.isRemoteCamera())
  			stopRemotePreview();
  
  		this.findViewById(R.id.mainLayout2).setVisibility(View.INVISIBLE);
  
  		if (shutterPlayer != null)
  		{
  			shutterPlayer.release();
  			shutterPlayer = null;
  		}
  	}
  
  	public void pauseMain()
  	{
  		onPause();
  	}
  
  	public void stopMain()
  	{
  		onStop();
  	}
  
  	public void startMain()
  	{
  		onStart();
  	}
  
  	public void resumeMain()
  	{
  		onResume();
  	}
  
  	@Override
  	public void surfaceChanged(final SurfaceHolder holder, final int format, final int width, final int height)
  	{
  		if (!cameraPermissionGranted || !storagePermissionGranted)
  			return;
  		
  		Log.e("ApplicationScreen", "SURFACE CHANGED");
  		mCameraSurface = holder.getSurface();
  
  		if (isCameraConfiguring)
  		{
  			ApplicationScreen.getPluginManager().sendMessage(ApplicationInterface.MSG_SURFACE_CONFIGURED, 0);
  			isCameraConfiguring = false;
  		} else
  		{
  			new CountDownTimer(50, 50)
  			{
  				public void onTick(long millisUntilFinished)
  				{
  					// Not used
  				}
  
  				public void onFinish()
  				{
  					if (!ApplicationScreen.instance.mPausing && surfaceCreated && (!CameraController.isCameraCreated()))
  					{
  						ApplicationScreen.instance.findViewById(R.id.mainLayout2).setVisibility(View.VISIBLE);
  						if (!CameraController.isRemoteCamera())
  						{
  							if (!CameraController.isUseCamera2())
  							{
  								CameraController.setupCamera(holder, true);
  							} else
  								messageHandler.sendEmptyMessage(ApplicationInterface.MSG_SURFACE_READY);
  						} else
  						{
  							// Sony camera
  						}
  					}
  				}
  			}.start();
  		}
  	}
  
  	public void setCameraImageSizeIndex(int captureIndex, boolean init)
  	{
  		CameraController.setCameraImageSizeIndex(captureIndex);
  	}
  
  	// Used if some modes want to set special image size
  	@Override
  	public void setSpecialImageSizeIndexPref(int iIndex)
  	{
  	}
  
  	@Override
  	public String getSpecialImageSizeIndexPref()
  	{
  		return "-1";
  	}
  
  	// Method used only in Almalence's multishot modes
  	abstract public int selectImageDimensionMultishot();
  
  	@Override
  	public void addSurfaceCallback()
  	{
  		instance.surfaceHolder.addCallback(instance);
  	}
  
  	boolean	isCameraConfiguring		= false;
  	
  	@Override
  	public void configureCamera(boolean createGUI)
  	{
  		CameraController.updateCameraFeatures();
  
  		// ----- Select preview dimensions with ratio correspondent to
  		// full-size image
  		ApplicationScreen.getPluginManager().setCameraPreviewSize();
  		// prepare list of surfaces to be used in capture requests
  		if (!CameraController.isRemoteCamera())
  		{
  			if (CameraController.isUseCamera2())
  				configureCamera2Camera(captureFormat);
  			else
  			{
  				Camera.Size sz = CameraController.getCameraParameters().getPreviewSize();
  
  				Log.e("ApplicationScreen", "Viewfinder preview size: " + sz.width + "x" + sz.height);
  				guiManager.setupViewfinderPreviewSize(new CameraController.Size(sz.width, sz.height));
  				double bufferSize = sz.width * sz.height
  						* ImageFormat.getBitsPerPixel(CameraController.getCameraParameters().getPreviewFormat()) / 8.0d;
  				CameraController.allocatePreviewBuffer(bufferSize);
  
  				CameraController.getCamera().setErrorCallback(CameraController.getInstance());
  
  				onCameraConfigured();
  			}
  		} else
  		{
  			guiManager.setupViewfinderPreviewSize(new CameraController.Size(((SimpleStreamSurfaceView) preview)
  					.getSurfaceWidth(), ((SimpleStreamSurfaceView) preview).getSurfaceHeight()));
  			onCameraConfigured();
  		}
  
  		if (createGUI)
  		{
  			ApplicationScreen.getPluginManager().onGUICreate();
  			ApplicationScreen.getGUIManager().onGUICreate();
  		}
  	}
  
  	protected void onCameraConfigured()
  	{
  		ApplicationScreen.getPluginManager().setupCameraParameters();
  
  		if (!CameraController.isRemoteCamera())
  		{
  			if (!CameraController.isUseCamera2())
  			{
  				Camera.Parameters cp = CameraController.getCameraParameters();
  
  				if (cp != null)
  				{
  					SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ApplicationScreen
  							.getMainContext());
  					int antibanding = Integer.parseInt(prefs.getString(ApplicationScreen.sAntibandingPref, "3"));
  					switch (antibanding)
  					{
  					case 0:
  						cp.setAntibanding("off");
  						break;
  					case 1:
  						cp.setAntibanding("50hz");
  						break;
  					case 2:
  						cp.setAntibanding("60hz");
  						break;
  					case 3:
  						cp.setAntibanding("auto");
  						break;
  					default:
  						cp.setAntibanding("auto");
  						break;
  					}
  					CameraController.setCameraParameters(cp);
  
  					previewWidth = cp.getPreviewSize().width;
  					previewHeight = cp.getPreviewSize().height;
  				}
  			}
  
  			try
  			{
  				Util.initialize(mainContext);
  				Util.initializeMeteringMatrix();
  			} catch (Exception e)
  			{
  				Log.e("Main setup camera", "Util.initialize failed!");
  			}
  
  			prepareMeteringAreas();
  
  			if (!CameraController.isUseCamera2())
  			{
  				guiManager.onCameraCreate();
  				ApplicationScreen.getPluginManager().onCameraParametersSetup();
  				guiManager.onPluginsInitialized();
  			}
  		} else
  		{
  			guiManager.onCameraCreate();
  			ApplicationScreen.getPluginManager().onCameraParametersSetup();
  			guiManager.onPluginsInitialized();
  		}
  
  		// ----- Start preview and setup frame buffer if needed
  
  		// call camera release sequence from onPause somewhere ???
  		new CountDownTimer(10, 10)
  		{
  			@Override
  			public void onFinish()
  			{
  				if (!CameraController.isRemoteCamera())
  				{
  					if (!CameraController.isUseCamera2())
  					{
  						if (!CameraController.isCameraCreated())
  							return;
  						// exceptions sometimes happen here when resuming after
  						// processing
  						try
  						{
  							CameraController.startCameraPreview();
  						} catch (RuntimeException e)
  						{
  							e.printStackTrace();
  							Toast.makeText(ApplicationScreen.instance, "Unable to start camera", Toast.LENGTH_LONG)
  									.show();
  							return;
  						}
  
  						CameraController.setPreviewCallbackWithBuffer();
  					} else
  					{
  						guiManager.onCameraCreate();
  						ApplicationScreen.getPluginManager().onCameraParametersSetup();
  						guiManager.onPluginsInitialized();
  					}
  				} else
  				{
  					guiManager.onCameraCreate();
  					ApplicationScreen.getPluginManager().onCameraParametersSetup();
  					guiManager.onPluginsInitialized();
  				}
  
  				ApplicationScreen.getPluginManager().onCameraSetup();
  				guiManager.onCameraSetup();
  				
  				PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
  				if(!pm.isScreenOn() && CameraController.isUseCamera2())
  					ApplicationScreen.mApplicationStarted = false;
  				else
  					ApplicationScreen.mApplicationStarted = true;
  				
  				if (ApplicationScreen.isForceClose)
  					ApplicationScreen.getPluginManager().sendMessage(ApplicationInterface.MSG_APPLICATION_STOP, 0);
  			}
  
  			@Override
  			public void onTick(long millisUntilFinished)
  			{
  				// Not used
  			}
  		}.start();
  	}
  
  	@TargetApi(21)
  	protected void configureCamera2Camera(int captureFormat)
  	{
  		isCameraConfiguring = true;
  		boolean needChange = setSurfaceHolderSize(previewWidth, previewHeight);
  		if (!needChange)
  		{
  			// If surface will not be changed, then configuring is finished. Send message about it.
  			ApplicationScreen.getPluginManager().sendMessage(ApplicationInterface.MSG_SURFACE_CONFIGURED, 0);
  			isCameraConfiguring = false;
  		}
  		
  	}
  
  	protected void prepareMeteringAreas()
  	{
  		Rect centerRect = CameraController.getSensorCoordinates(new Rect(previewWidth / 4, previewHeight / 4, previewWidth
  				- previewWidth / 4, previewHeight - previewHeight / 4));
  		Rect topLeftRect = CameraController.getSensorCoordinates(new Rect(0, 0, previewWidth / 2, previewHeight / 2));
  		Rect topRightRect = CameraController.getSensorCoordinates(new Rect(previewWidth / 2, 0, previewWidth,
  				previewHeight / 2));
  		Rect bottomRightRect = CameraController.getSensorCoordinates(new Rect(previewWidth / 2, previewHeight / 2,
  				previewWidth, previewHeight));
  		Rect bottomLeftRect = CameraController.getSensorCoordinates(new Rect(0, previewHeight / 2, previewWidth / 2,
  				previewHeight));
  		Rect spotRect = CameraController.getSensorCoordinates(new Rect(previewWidth / 2 - 10, previewHeight / 2 - 10,
  				previewWidth / 2 + 10, previewHeight / 2 + 10));
  
  		mMeteringAreaMatrix5.clear();
  		mMeteringAreaMatrix5.add(new Area(centerRect, 600));
  		mMeteringAreaMatrix5.add(new Area(topLeftRect, 200));
  		mMeteringAreaMatrix5.add(new Area(topRightRect, 200));
  		mMeteringAreaMatrix5.add(new Area(bottomRightRect, 200));
  		mMeteringAreaMatrix5.add(new Area(bottomLeftRect, 200));
  
  		mMeteringAreaMatrix4.clear();
  		mMeteringAreaMatrix4.add(new Area(topLeftRect, 250));
  		mMeteringAreaMatrix4.add(new Area(topRightRect, 250));
  		mMeteringAreaMatrix4.add(new Area(bottomRightRect, 250));
  		mMeteringAreaMatrix4.add(new Area(bottomLeftRect, 250));
  
  		mMeteringAreaMatrix1.clear();
  		mMeteringAreaMatrix1.add(new Area(centerRect, 1000));
  
  		mMeteringAreaCenter.clear();
  		mMeteringAreaCenter.add(new Area(centerRect, 1000));
  
  		mMeteringAreaSpot.clear();
  		mMeteringAreaSpot.add(new Area(spotRect, 1000));
  	}
  
  	@Override
  	public void surfaceCreated(SurfaceHolder holder)
  	{
  		// ----- Find 'normal' orientation of the device
  
  		Display display = ((WindowManager) this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
  		int rotation = display.getRotation();
  		if ((rotation == Surface.ROTATION_90) || (rotation == Surface.ROTATION_270))
  			landscapeIsNormal = true; // false; - if landscape view orientation
  										// set for ApplicationScreen
  		else
  			landscapeIsNormal = false;
  
  		surfaceCreated = true;
  
  		mCameraSurface = surfaceHolder.getSurface();
  	}
  
  	@Override
  	public void surfaceDestroyed(SurfaceHolder holder)
  	{
  		surfaceCreated = false;
  	}
  
  	// SURFACES (preview, image readers)
  	@Override
  	public Surface getCameraSurface()
  	{
  		if (glView != null)
  		{
  			return new Surface(glView.getSurfaceTexture());
  		}
  		return mCameraSurface;
  	}
  
  	// Probably used only by Panorama plugin. Added to avoid non direct
  	// interface (message/handler)
  	public static void takePicture()
  	{
  		ApplicationScreen.getPluginManager().takePicture();
  	}
  
  	@Override
  	public void captureFailed()
  	{
  		ApplicationScreen.getMessageHandler().sendEmptyMessage(ApplicationInterface.MSG_EXPORT_FINISHED_IOEXCEPTION);
  		ApplicationScreen.instance.muteShutter(false);
  	}
  
  	@TargetApi(14)
  	public boolean isFaceDetectionAvailable(Camera.Parameters params)
  	{
  		return params.getMaxNumDetectedFaces() > 0;
  	}
  
  	public CameraController.Size getPreviewSize()
  	{
  		if (SimpleStreamSurfaceView.class.isInstance(preview))
  		{
  			return new CameraController.Size(preview.getWidth(), preview.getHeight());
  		} else
  		{
  			LayoutParams lp = preview.getLayoutParams();
  			if (lp == null)
  				return null;
  
  			return new CameraController.Size(lp.width, lp.height);
  		}
  	}
  
  	/*
  	 * CAMERA PARAMETERS SECTION Supplementary methods for those plugins that
  	 * need an icons of supported camera parameters (scene, iso, wb, flash,
  	 * focus) Methods return id of drawable icon
  	 */
  	public int getSceneIcon(int sceneMode)
  	{
  		return guiManager.getSceneIcon(sceneMode);
  	}
  
  	public int getWBIcon(int wb)
  	{
  		return guiManager.getWBIcon(wb);
  	}
  
  	public int getFocusIcon(int focusMode)
  	{
  		return guiManager.getFocusIcon(focusMode);
  	}
  
  	public int getFlashIcon(int flashMode)
  	{
  		return guiManager.getFlashIcon(flashMode);
  	}
  
  	public int getISOIcon(int isoMode)
  	{
  		return guiManager.getISOIcon(isoMode);
  	}
  
  	public void setCameraMeteringMode(int mode)
  	{
  		if (CameraParameters.meteringModeAuto == mode)
  			CameraController.setCameraMeteringAreas(null);
  		else if (CameraParameters.meteringModeMatrix == mode)
  		{
  			int maxAreasCount = CameraController.getMaxNumMeteringAreas();
  			if (maxAreasCount > 4)
  				CameraController.setCameraMeteringAreas(mMeteringAreaMatrix5);
  			else if (maxAreasCount > 3)
  				CameraController.setCameraMeteringAreas(mMeteringAreaMatrix4);
  			else if (maxAreasCount > 0)
  				CameraController.setCameraMeteringAreas(mMeteringAreaMatrix1);
  			else
  				CameraController.setCameraMeteringAreas(null);
  		} else if (CameraParameters.meteringModeCenter == mode)
  			CameraController.setCameraMeteringAreas(mMeteringAreaCenter);
  		else if (CameraParameters.meteringModeSpot == mode)
  			CameraController.setCameraMeteringAreas(mMeteringAreaSpot);
  
  		currentMeteringMode = mode;
  	}
  
  	/*
  	 * 
  	 * CAMERA parameters access function ended
  	 */
  
  	// >>Description
  	// section with user control procedures and main capture functions
  	//
  	// all events translated to PluginManager
  	// Description<<
  
  	@Override
  	public void setAutoFocusLock(boolean locked)
  	{
  		mAFLocked = locked;
  	}
  
  	@Override
  	public boolean getAutoFocusLock()
  	{
  		return mAFLocked;
  	}
  
  	@Override
  	public boolean onKeyUp(int keyCode, KeyEvent event)
  	{
  		if (onKeyUpEvent(keyCode, event))
  			return true;
  
  		return super.onKeyUp(keyCode, event);
  	}
  
  	abstract boolean onKeyUpEvent(int keyCode, KeyEvent event);
  
  	@Override
  	public boolean onKeyDown(int keyCode, KeyEvent event)
  	{
  		if (onKeyDownEvent(keyCode, event))
  			return true;
  
  		return super.onKeyDown(keyCode, event);
  	}
  
  	abstract boolean onKeyDownEvent(int keyCode, KeyEvent event);
  
  	@Override
  	public void onClick(View v)
  	{
  		if (mApplicationStarted)
  			ApplicationScreen.getGUIManager().onClick(v);
  	}
  
  	@Override
  	public boolean onTouch(View view, MotionEvent event)
  	{
  		if (mApplicationStarted)
  			return ApplicationScreen.getGUIManager().onTouch(view, event);
  		return true;
  	}
  
  	public boolean onTouchSuper(View view, MotionEvent event)
  	{
  		return super.onTouchEvent(event);
  	}
  
  	public void onButtonClick(View v)
  	{
  		ApplicationScreen.getGUIManager().onButtonClick(v);
  	}
  
  	@Override
  	public void onShutter()
  	{
  		ApplicationScreen.getPluginManager().onShutter();
  	}
  
  	public static boolean isForceClose()
  	{
  		return isForceClose;
  	}
  
  	public static boolean isApplicationStarted()
  	{
  		return mApplicationStarted;
  	}
  	
  	// >>Description
  	// message processor
  	//
  	// processing main events and calling active plugin procedures
  	//
  	// possible some additional plugin dependent events.
  	//
  	// Description<<
  	@Override
  	public boolean handleMessage(Message msg)
  	{
  		switch (msg.what)
  		{
  		case ApplicationInterface.MSG_APPLICATION_STOP:
  			this.setResult(RESULT_OK);
  			this.finish();
  			break;
  		case ApplicationInterface.MSG_CAMERA_CONFIGURED:
  			onCameraConfigured();
  			break;
  		case ApplicationInterface.MSG_CAMERA_OPENED:
  			if (mCameraStarted)
  				break;
  		case ApplicationInterface.MSG_SURFACE_READY:
  			{
  				String modeName = ApplicationScreen.getPluginManager().getActiveModeID();
  				if (!CameraController.isRemoteCamera())
  				{
  					// if both surface is created and camera device is opened
  					// - ready to set up preview and other things
  					// if (surfaceCreated && (Camera2.getCamera2() != null))
  					if (surfaceCreated)
  					{
  						configureCamera(
  								   !CameraController.isUseCamera2() 
  								//|| modeName.contains("video")
  								|| (CameraController.isNexus6 && modeName.contains("preshot"))
  								//|| (CameraController.isFlex2 && (modeName.contains("hdrmode") || modeName.contains("expobracketing")))
  								);
  						mCameraStarted = true;
  					}
  				} else
  				{
  					if (!modeName.contains("video"))
  					{
  						CameraController.populateCameraDimensionsSonyRemote();
  						ApplicationScreen.getPluginManager().selectImageDimension();
  					}
  					configureCamera(true);
  				}
  			}
  			break;
  		case ApplicationInterface.MSG_SURFACE_CONFIGURED:
  			{
  				guiManager.setupViewfinderPreviewSize(new CameraController.Size(previewWidth, previewHeight));
  				CameraController.setCaptureFormat(captureFormat);
  				CameraController.startCameraPreview();
  				ApplicationScreen.getGUIManager().onGUICreate();
  				ApplicationScreen.getPluginManager().onGUICreate();
  				mCameraStarted = true;
  			}
  			break;
  		case ApplicationInterface.MSG_CAMERA_STOPED:
  			mCameraStarted = false;
  			break;
  		default:
  			ApplicationScreen.getPluginManager().handleMessage(msg);
  			break;
  		}
  
  		return true;
  	}
  
  	public void menuButtonPressed()
  	{
  		ApplicationScreen.getPluginManager().menuButtonPressed();
  	}
  
  	public void disableCameraParameter(GUI.CameraParameter iParam, boolean bDisable, boolean bInitMenu,
  			boolean bModeInit)
  	{
  		guiManager.disableCameraParameter(iParam, bDisable, bInitMenu, bModeInit);
  	}
  
  	public void showOpenGLLayer(final int version)
  	{
  		if (glView == null)
  		{
  			glView = new GLLayer(ApplicationScreen.getMainContext(), version);
  			LayoutParams params = ApplicationScreen.getPreviewSurfaceView().getLayoutParams();
  			glView.setLayoutParams(params);
  			((RelativeLayout) this.findViewById(R.id.mainLayout2)).addView(glView, 0);
  			preview.bringToFront();
  			glView.setZOrderMediaOverlay(true);
  			glView.onResume();
  		}
  	}
  
  	public void hideOpenGLLayer()
  	{
  		if (glView != null)
  		{
  			// preview.getHolder().getSurface().lockCanvas(null).drawColor(Color.BLACK);
  			glView.onPause();
  			glView.destroyDrawingCache();
  			((RelativeLayout) this.findViewById(R.id.mainLayout2)).removeView(glView);
  			glView = null;
  		}
  	}
  
  	@Override
  	abstract public void showCaptureIndication(boolean playShutter);
  
  	// set TRUE to mute and FALSE to unmute
  	public void muteShutter(boolean mute)
  	{
  		if (Build.VERSION.SDK_INT < 23)
  		{
  			AudioManager mgr = (AudioManager) ApplicationScreen.instance.getSystemService(ApplicationScreen.AUDIO_SERVICE);
  			mgr.setStreamMute(AudioManager.STREAM_SYSTEM, mute);
  		}
  	}
  
  	@Override
  	public void setExpoPreviewPref(boolean previewMode)
  	{
  		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mainContext);
  		Editor prefsEditor = prefs.edit();
  		prefsEditor.putBoolean(ApplicationScreen.sExpoPreviewModePref, previewMode);
  		prefsEditor.commit();
  	}
  
  	@Override
  	public boolean getExpoPreviewPref()
  	{
  		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mainContext);
  		if (true == prefs.contains(ApplicationScreen.sExpoPreviewModePref))
  		{
  			return prefs.getBoolean(ApplicationScreen.sExpoPreviewModePref, true);
  		} else
  			return true;
  	}
  
  	@Override
  	public void setCameraPreviewSize(int iWidth, int iHeight)
  	{
  		if (!CameraController.isRemoteCamera())
  		{
  			if (CameraController.isUseCamera2())
  			{
  				setSurfaceHolderSize(iWidth, iHeight);
  				setPreviewWidth(iWidth);
  				setPreviewHeight(iHeight);
  			}
  		} else
  		{
  			setPreviewWidth(iWidth);
  			setPreviewHeight(iHeight);
  		}
  
  		CameraController.setCameraPreviewSize(new CameraController.Size(iWidth, iHeight));
  	}
  
  	public static int getPreviewWidth()
  	{
  		return instance.previewWidth;
  	}
  
  	public static void setPreviewWidth(int iWidth)
  	{
  		instance.previewWidth = iWidth;
  	}
  
  	public static int getPreviewHeight()
  	{
  		return instance.previewHeight;
  	}
  
  	public static void setPreviewHeight(int iHeight)
  	{
  		instance.previewHeight = iHeight;
  	}
  
  	public static boolean getWantLandscapePhoto()
  	{
  		return wantLandscapePhoto;
  	}
  
  	public static void setWantLandscapePhoto(boolean setWantLandscapePhoto)
  	{
  		wantLandscapePhoto = setWantLandscapePhoto;
  	}
  
  	public void setScreenBrightness(boolean setMax)
  	{
  		Window window = getWindow();
  		WindowManager.LayoutParams layoutpars = window.getAttributes();
  
  		// Set the brightness of this window
  		if (setMax)
  			layoutpars.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL;
  		else
  			layoutpars.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
  
  		// Apply attribute changes to this window
  		window.setAttributes(layoutpars);
  	}
  
  	public void setKeepScreenOn(boolean keepScreenOn)
  	{
  		if (keepScreenOn)
  		{
  			preview.setKeepScreenOn(keepScreenOn);
  		} else
  		{
  			preview.setKeepScreenOn(this.keepScreenOn);
  		}
  	}
  
  	public static Resources getAppResources()
  	{
  		return ApplicationScreen.instance.getResources();
  	}
  
  	abstract protected void resetOrSaveSettings();
  
  	public void switchingMode(boolean isModeSwitching)
  	{
  		switchingMode = isModeSwitching;
  	}
  
  	public boolean getSwitchingMode()
  	{
  		return switchingMode;
  	}
  
  	@Override
  	abstract public Activity getMainActivity();
  
  	@Override
  	public void stopApplication()
  	{
  		finish();
  	}
  
  	// Set/Get camera parameters preference
  	@Override
  	public int getCameraParameterPref(GUI.CameraParameter iParam)
  	{
  		switch (iParam)
  		{
  		case CAMERA_PARAMETER_SCENE:
  			return getSceneModePref();
  		case CAMERA_PARAMETER_WB:
  			return getWBModePref();
  		case CAMERA_PARAMETER_FOCUS:
  			return getFocusModePref(-1);
  		case CAMERA_PARAMETER_FLASH:
  			return getFlashModePref(-1);
  		default: //All other parameters is not configurable
  			return -1;
  		}
  	}
  
  	// EXPOSURE COMPENSATION PREFERENCE
  	@Override
  	public void setEVPref(int iEv)
  	{
  		PreferenceManager.getDefaultSharedPreferences(mainContext).edit().putInt(ApplicationScreen.sEvPref, iEv)
  				.commit();
  	}
  
  	@Override
  	public int getEVPref()
  	{
  		return PreferenceManager.getDefaultSharedPreferences(mainContext).getInt(ApplicationScreen.sEvPref, 0);
  	}
  
  	// SCENE MODE PREFERENCE
  	@Override
  	public void setSceneModePref(int iSceneMode)
  	{
  		PreferenceManager.getDefaultSharedPreferences(mainContext).edit()
  				.putInt(ApplicationScreen.sSceneModePref, iSceneMode).commit();
  	}
  
  	@Override
  	public int getSceneModePref()
  	{
  		return PreferenceManager.getDefaultSharedPreferences(mainContext).getInt(ApplicationScreen.sSceneModePref,
  				ApplicationScreen.sDefaultValue);
  	}
  
  	// WHITE BALANCE MODE PREFERENCE
  	@Override
  	public void setWBModePref(int iWB)
  	{
  		PreferenceManager.getDefaultSharedPreferences(mainContext).edit().putInt(ApplicationScreen.sWBModePref, iWB)
  				.commit();
  	}
  
  	@Override
  	public int getWBModePref()
  	{
  		return PreferenceManager.getDefaultSharedPreferences(mainContext).getInt(ApplicationScreen.sWBModePref,
  				ApplicationScreen.sDefaultValue);
  	}
  	
  	
  	@Override
  	public void setColorTemperature(int iTemp)
  	{
  		PreferenceManager.getDefaultSharedPreferences(mainContext).edit().putInt(ApplicationScreen.sColorTemperaturePref, iTemp)
  		.commit();
  	}
  	
  	@Override
  	public int getColorTemperature()
  	{
  		return PreferenceManager.getDefaultSharedPreferences(mainContext).getInt(MainScreen.sColorTemperaturePref,
  				ApplicationScreen.iDefaultColorTemperatureValue);
  	}
  
  	// FOCUS MODE PREFERENCE
  	@Override
  	public void setFocusModePref(int iFocusMode)
  	{
  		String modeName = ApplicationScreen.getPluginManager().getActiveModeID();
  		String frontFocusMode = null;
  		String backFocusMode = null;
  
  		if (modeName.contains("video"))
  		{
  			frontFocusMode = ApplicationScreen.sFrontFocusModeVideoPref;
  			backFocusMode = ApplicationScreen.sRearFocusModeVideoPref;
  		} else
  		{
  			frontFocusMode = ApplicationScreen.sFrontFocusModePref;
  			backFocusMode = ApplicationScreen.sRearFocusModePref;
  		}
  
  		if (!CameraController.isRemoteCamera())
  		{
  			PreferenceManager.getDefaultSharedPreferences(mainContext).edit()
  					.putInt(CameraController.isFrontCamera() ? frontFocusMode : backFocusMode, iFocusMode).commit();
  		} else
  		{
  			// Sony cmaera
  		}
  	}
  
  	@Override
  	public int getFocusModePref(int defaultMode)
  	{
  		String modeName = ApplicationScreen.getPluginManager().getActiveModeID();
  		String frontFocusMode = null;
  		String backFocusMode = null;
  
  		if (modeName.contains("video"))
  		{
  			frontFocusMode = ApplicationScreen.sFrontFocusModeVideoPref;
  			backFocusMode = ApplicationScreen.sRearFocusModeVideoPref;
  		} else
  		{
  			frontFocusMode = ApplicationScreen.sFrontFocusModePref;
  			backFocusMode = ApplicationScreen.sRearFocusModePref;
  		}
  
  		if (!CameraController.isRemoteCamera())
  		{
  			return PreferenceManager.getDefaultSharedPreferences(mainContext).getInt(
  					CameraController.isFrontCamera() ? frontFocusMode : backFocusMode, defaultMode);
  		} else
  		{
  			// Sony camera
  			return 0;
  		}
  	}
  
  	// FLASH MODE PREFERENCE
  	@Override
  	public void setFlashModePref(int iFlashMode)
  	{
  		PreferenceManager.getDefaultSharedPreferences(mainContext).edit()
  				.putInt(ApplicationScreen.sFlashModePref, iFlashMode).commit();
  	}
  
  	@Override
  	public int getFlashModePref(int defaultMode)
  	{
  		return PreferenceManager.getDefaultSharedPreferences(mainContext).getInt(ApplicationScreen.sFlashModePref,
  				defaultMode);
  	}
  
  	// ISO MODE PREFERENCE
  	@Override
  	public void setISOModePref(int iISOMode)
  	{
  		PreferenceManager.getDefaultSharedPreferences(mainContext).edit().putInt(ApplicationScreen.sISOPref, iISOMode)
  				.commit();
  	}
  
  	@Override
  	public int getISOModePref(int defaultMode)
  	{
  		return PreferenceManager.getDefaultSharedPreferences(mainContext).getInt(ApplicationScreen.sISOPref,
  				defaultMode);
  	}
  
  	@Override
  	public int getAntibandingModePref()
  	{
  		return Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(mainContext).getString(
  				ApplicationScreen.sAntibandingPref, "3"));
  	}
  	
  	@Override
  	public int getColorEffectPref()
  	{
  		try
  		{
  			return Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(mainContext).getString(
  					CameraController.isFrontCamera() ? ApplicationScreen.sRearColorEffectPref
  							: ApplicationScreen.sFrontColorEffectPref, String
  							.valueOf(ApplicationScreen.sDefaultColorEffectValue)));
  		} catch (Exception e)
  		{
  			return (PreferenceManager.getDefaultSharedPreferences(mainContext).getInt(CameraController.isFrontCamera() ? ApplicationScreen.sRearColorEffectPref
  					: ApplicationScreen.sFrontColorEffectPref, ApplicationScreen.sDefaultColorEffectValue));
  		}
  	}
  	
  	@Override
  	public boolean useColorFilters()
  	{
  		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ApplicationScreen.getMainContext());
  		boolean captureRAW = prefs.getBoolean(ApplicationScreen.sCaptureRAWPref, false);
  		return ((ApplicationScreen.getPluginManager().getActiveModeID().equals("single")||
  				  ApplicationScreen.getPluginManager().getActiveModeID().equals("burstmode")||
  				  ApplicationScreen.getPluginManager().getActiveModeID().equals("expobracketing")||
  				  ApplicationScreen.getPluginManager().getActiveModeID().equals("preshot"))
  				  &&//and if raw capture is enabled
  				  (!(captureRAW && CameraController.isRAWCaptureSupported())));
  	}
  	
  	@Override
  	public boolean getAELockPref()
  	{
  		return PreferenceManager.getDefaultSharedPreferences(mainContext).getBoolean(ApplicationScreen.sAELockPref,
  				false);
  	}
  
  	@Override
  	public boolean getAWBLockPref()
  	{
  		return PreferenceManager.getDefaultSharedPreferences(mainContext).getBoolean(ApplicationScreen.sAWBLockPref,
  				false);
  	}
  
  	public static Uri getForceFilenameURI()
  	{
  		return ApplicationScreen.forceFilenameUri;
  	}
  
  	public static File getForceFilename()
  	{
  		return ApplicationScreen.forceFilename;
  	}
  
  	public static void setForceFilename(File fileName)
  	{
  		ApplicationScreen.forceFilename = fileName;
  	}
  
  	public void sonyCameraSelected()
  	{
  		findViewById(R.id.SurfaceView01).setVisibility(View.GONE);
  		preview = (SurfaceView) this.findViewById(R.id.SurfaceView02);
  		surfaceHolder = preview.getHolder();
  		surfaceHolder.addCallback(this);
  
  		preview.setVisibility(View.VISIBLE);
  		preview.setOnClickListener(this);
  		preview.setOnTouchListener(this);
  		preview.setKeepScreenOn(true);
  
  		CameraController.setupCamera(preview.getHolder(), !switchingMode);
  	}
  }
  