package com.android.facelock;

import java.io.FileDescriptor;

import com.android.facelock.PicturePasswordView.OnFingerUpListener;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PointF;
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

public class SetupIntro extends Activity implements View.OnClickListener
{
	private static final int STEP_INTRO = 0;
	private static final int STEP_CHOOSE_NUMBER = 1;
	private static final int STEP_CONFIRM_NUMBER = 2;
	
	private static final int LOAD_IMAGE_CODE = 1;
	
	private int mStep;
	
	private SparseIntArray mButtonIds;
	private Dialog mDialog;
	private int mChosenNumber;
	
	private Bitmap mBitmap;
	private PointF mUnlockPosition;
	private int mGridSize;
	private boolean mRandomize;

	@Override
	protected void onCreate( Bundle savedInstanceState )
	{
		mStep = STEP_INTRO;
		
		super.onCreate( savedInstanceState );
		setContentView( R.layout.activity_setup_intro );
		
		mButtonIds = new SparseIntArray();
		
		// there must be a better way to do this. I don't think R
		// IDs are guaranteed to stay in order though, so a loop
		// wouldn't really cut it.

		mButtonIds.put( R.id.button0, 0 );
		mButtonIds.put( R.id.button1, 1 );
		mButtonIds.put( R.id.button2, 2 );
		mButtonIds.put( R.id.button3, 3 );
		mButtonIds.put( R.id.button4, 4 );
		mButtonIds.put( R.id.button5, 5 );
		mButtonIds.put( R.id.button6, 6 );
		mButtonIds.put( R.id.button7, 7 );
		mButtonIds.put( R.id.button8, 8 );
		mButtonIds.put( R.id.button9, 9 );
		
		setListeners();
	}
	
	private void setListeners()
	{
		final Button btnCancel = ( Button ) findViewById( R.id.cancel_button );
		final Button btnNext = ( Button ) findViewById( R.id.next_button );
		
		btnCancel.setOnClickListener( this );
		btnNext.setOnClickListener( this );
	}
	
	private void chooseImage()
	{
		Intent intent = new Intent( Intent.ACTION_OPEN_DOCUMENT );
		intent.addCategory( Intent.CATEGORY_OPENABLE );
		intent.setType( "image/*" );
		startActivityForResult( intent, LOAD_IMAGE_CODE );
	}

	public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight )
	{
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if ( height > reqHeight || width > reqWidth )
		{
			final int halfHeight = height / 2;
			final int halfWidth = width / 2;

			// Calculate the largest inSampleSize value that is a power of 2 and
			// keeps both height and width larger than the requested height and
			// width.
			
			while ( ( halfHeight / inSampleSize ) > reqHeight
					&& ( halfWidth / inSampleSize ) > reqWidth )
			{
				inSampleSize *= 2;
			}
		}

		return inSampleSize;
	}

	@Override
	public void onActivityResult( int requestCode, int resultCode, Intent resultData )
	{
		if ( requestCode == LOAD_IMAGE_CODE && resultCode == Activity.RESULT_OK )
		{
			Uri uri = null;
			if ( resultData != null )
			{
				Bitmap image = null;
				
				mStep = STEP_CHOOSE_NUMBER;
				setContentView( R.layout.activity_setup_number );
				
				final PicturePasswordView imageview = ( PicturePasswordView ) findViewById( R.id.chosenImage );
				
				DisplayMetrics metrics = getResources().getDisplayMetrics();
				
				int vw = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 300, metrics );
				int vh = vw;
				
				uri = resultData.getData();
				try
				{
					// TODO: move to another thread.
					
					ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor( uri, "r" );
					FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
					
					BitmapFactory.Options opts = new BitmapFactory.Options();
					opts.inJustDecodeBounds = true;
					
					BitmapFactory.decodeFileDescriptor( fileDescriptor, null, opts );
					
					opts.inSampleSize = calculateInSampleSize( opts, vw, vh );
					opts.inJustDecodeBounds = false;
					
					image = BitmapFactory.decodeFileDescriptor( fileDescriptor, null, opts );
					
					parcelFileDescriptor.close();
				}
				catch ( Exception e )
				{
					e.printStackTrace();
				}
				
				if ( image != null )
				{
					mBitmap = image;
					
					imageview.setImageBitmap( image );
					
					imageview.setGridSize( 5 );
					
					final SeekBar gridSize = ( SeekBar ) findViewById( R.id.grid_size );
					gridSize.setMax( 8 - 4 );
					gridSize.setProgress( imageview.getGridSize() - 4 );
					
					final String sizeTextOriginal = getResources().getString( R.string.grid_size );
					final TextView sizeText = ( TextView ) findViewById( R.id.grid_size_text );
					
					sizeText.setText( sizeTextOriginal + " " + imageview.getGridSize() + "x" + imageview.getGridSize() );
					
					gridSize.setOnSeekBarChangeListener( new OnSeekBarChangeListener()
					{
						@Override
						public void onStopTrackingTouch( SeekBar seekBar )
						{
						}

						@Override
						public void onProgressChanged( SeekBar seekBar, int progress, boolean fromUser )
						{
							if ( fromUser )
							{
								imageview.setGridSize( progress + 4 );
								sizeText.setText( sizeTextOriginal + " " + ( progress + 4 ) + "x" + ( progress + 4 ) );
							}
						}

						@Override
						public void onStartTrackingTouch( SeekBar seekBar )
						{
						}
					} );
					
					setListeners();
					
					AlertDialog.Builder builder = new AlertDialog.Builder( this );
					LayoutInflater inflater = getLayoutInflater();
					
					builder.setView( inflater.inflate( R.layout.popup_select_number, null ) );
					
					Dialog dlg = builder.create();
					dlg.setCancelable( false );
					dlg.show();
					
					mDialog = dlg;
					
					for ( int i = 0; i < 10; i++ )
					{
						( ( Button ) dlg.findViewById( mButtonIds.keyAt( mButtonIds.indexOfValue( i ) ) ) ).setOnClickListener( this );
					}
				}
				
				return;
			}
		}
		finish();
	}
	
	private void confirmNumber()
	{
		final TextView title = ( TextView ) findViewById( R.id.headerText );
		title.setText( R.string.confirm_title );
		
		final Button nextButton = ( Button ) findViewById( R.id.next_button );
		nextButton.setEnabled( false );
		
		final SeekBar gridSize = ( SeekBar ) findViewById( R.id.grid_size );
		gridSize.setEnabled( false );
		
		final CheckBox randomize = ( CheckBox ) findViewById( R.id.randomize );
		randomize.setEnabled( false );
		
		PicturePasswordView passwordView = ( PicturePasswordView ) findViewById( R.id.chosenImage );
		mGridSize = passwordView.getGridSize();
		mRandomize = randomize.isChecked();
				
		int unlockNumber = mChosenNumber;
		PointF unlockPosition = passwordView.getHighlightPosition();
		mUnlockPosition = unlockPosition;
		
		passwordView.setFocusNumber( -1 );
		passwordView.reset();
		passwordView.setUnlockNumber( unlockNumber, unlockPosition.x, unlockPosition.y );
		passwordView.setOnFingerUpListener( new OnFingerUpListener()
		{
			@Override
			public void onFingerUp( PicturePasswordView picturePassword, boolean shouldUnlock )
			{
				if ( shouldUnlock )
				{
					nextButton.setEnabled( true );
					picturePassword.setEnabled( false );
					picturePassword.setHighlightUnlockNumber( true );
					title.setText( R.string.done_title );
				}
				else
				{
					title.setText( R.string.try_again );
					picturePassword.reset();
				}
			}
		} );
		
		mStep = STEP_CONFIRM_NUMBER;
	}
	
	private void saveData()
	{
		if ( !PicturePasswordUtils.saveUnlockData( this, mBitmap, mGridSize, mRandomize, mChosenNumber, mUnlockPosition ) )
		{
			// uh oh
			finish();
		}
		else
		{
			PendingIntent requestedIntent = getIntent().getParcelableExtra( "PendingIntent" );
			
			boolean ok = false;
			if ( requestedIntent != null )
			{
				try
				{
					requestedIntent.send();
					ok = true;
				}
				catch ( CanceledException e )
				{
					ok = false;
				}
			}
			else
			{
				Log.e( "PicturePassword", "PendingIntent was null or canceled! This is probably bad!" );
				Intent chooseIntent = new Intent();
				chooseIntent.setClassName( "com.android.settings", "com.android.settings.ChooseLockGeneric" );
				chooseIntent.putExtra( "lockscreen.biometric_weak_fallback", true );
				startActivity( chooseIntent );
			}
			finish();
		}
	}
	
	public void onClick( View which )
	{
		if ( which.getId() == R.id.cancel_button )
		{
			finish();
		}
		else if ( which.getId() == R.id.next_button )
		{
			if ( mStep == STEP_INTRO )
			{
				chooseImage();
			}
			else if ( mStep == STEP_CHOOSE_NUMBER )
			{
				confirmNumber();
			}
			else if ( mStep == STEP_CONFIRM_NUMBER )
			{
				saveData();
			}
		}
		else if ( mButtonIds.indexOfKey( which.getId() ) > -1 )
		{
			mDialog.dismiss();
			mChosenNumber = mButtonIds.get( which.getId() );

			final PicturePasswordView imageview = ( PicturePasswordView ) findViewById( R.id.chosenImage );
			imageview.setFocusNumber( mChosenNumber );
			imageview.setShowNumbers( true, true );
		}
	}
}