package com.cooliris.media;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.TimeZone;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.provider.MediaStore.Images;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Toast;
import android.media.MediaScannerConnection;

import com.cooliris.cache.CacheService;
import com.cooliris.wallpaper.RandomDataSource;
import com.cooliris.wallpaper.Slideshow;

public final class Gallery extends Activity {
	public static final TimeZone CURRENT_TIME_ZONE = TimeZone.getDefault();
	public static float PIXEL_DENSITY = 0.0f;
	public static final int CROP_MSG_INTERNAL = 100;

	private static final String TAG = "Gallery";
	private static final int CROP_MSG = 10;
	private RenderView mRenderView = null;
	private GridLayer mGridLayer;
	private final Handler mHandler = new Handler();
	private ReverseGeocoder mReverseGeocoder;
	private boolean mPause;
	private MediaScannerConnection mConnection;
	private WakeLock mWakeLock;
	private HashMap<String, Boolean> mAccountsEnabled;
	private static final boolean TEST_WALLPAPER = false;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		final boolean imageManagerHasStorage = ImageManager.quickHasStorage();
		if (TEST_WALLPAPER || (isViewIntent() && getIntent().getData().equals(Images.Media.EXTERNAL_CONTENT_URI))) {
			if (!imageManagerHasStorage) {
				Toast.makeText(this, getResources().getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
				finish();
			} else {
				PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
				mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "GridView.Slideshow.All");
				mWakeLock.acquire();
				Slideshow slideshow = new Slideshow(this);
				slideshow.setDataSource(new RandomDataSource());
				setContentView(slideshow);
			}
			return;
		}
		final boolean isCacheReady = CacheService.isCacheReady(false);
		CacheService.startCache(this, false);
		if (PIXEL_DENSITY == 0.0f) {
			DisplayMetrics metrics = new DisplayMetrics();
			getWindowManager().getDefaultDisplay().getMetrics(metrics);
			PIXEL_DENSITY = metrics.density;
		}
		mReverseGeocoder = new ReverseGeocoder(this);
		mRenderView = new RenderView(this);
		mGridLayer = new GridLayer(this, (int) (96.0f * PIXEL_DENSITY), (int) (72.0f * PIXEL_DENSITY), new GridLayoutInterface(4),
		        mRenderView);
		mRenderView.setRootLayer(mGridLayer);
		setContentView(mRenderView);
		
		// Creating the DataSource objects
		final PicasaDataSource picasaDataSource = new PicasaDataSource(this);
		final LocalDataSource localDataSource = new LocalDataSource(this);
		final ConcatenatedDataSource combinedDataSource = new ConcatenatedDataSource(localDataSource, picasaDataSource);
		
		// Depending upon the intent, we assign the right dataSource.
		if (!isPickIntent() && !isViewIntent()) {
			if (imageManagerHasStorage) {
				mGridLayer.setDataSource(combinedDataSource);
			} else {
				mGridLayer.setDataSource(picasaDataSource);
			}
			if (!imageManagerHasStorage) {
				Toast.makeText(this, getResources().getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
			} else if (!isCacheReady) {
				Toast.makeText(this, getResources().getString(R.string.loading_new), Toast.LENGTH_LONG).show();
			}
		} else if (!isViewIntent()) {
			final Intent intent = getIntent();
			if (intent != null) {
				final String type = intent.resolveType(this);
				boolean includeImages = isImageType(type);
				boolean includeVideos = isVideoType(type);
				((LocalDataSource) localDataSource).setMimeFilter(!includeImages, !includeVideos);
				if (includeImages) {
					if (imageManagerHasStorage) {
						mGridLayer.setDataSource(combinedDataSource);
					} else {
						mGridLayer.setDataSource(picasaDataSource);
					}
				} else {
					mGridLayer.setDataSource(localDataSource);
				}
				mGridLayer.setPickIntent(true);
				if (!imageManagerHasStorage) {
					Toast.makeText(this, getResources().getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
				} else {
					Toast.makeText(this, getResources().getString(R.string.pick_prompt), Toast.LENGTH_LONG).show();
				}
			}
		} else {
			// View intent for images.
			Uri uri = getIntent().getData();
			boolean slideshow = getIntent().getBooleanExtra("slideshow", false);
			final SingleDataSource singleDataSource = new SingleDataSource(this, uri.toString(), slideshow);
			final ConcatenatedDataSource singleCombinedDataSource = new ConcatenatedDataSource(singleDataSource, picasaDataSource);
			mGridLayer.setDataSource(singleCombinedDataSource);
			mGridLayer.setViewIntent(true, Utils.getBucketNameFromUri(uri));
			if (singleDataSource.isSingleImage()) {
				mGridLayer.setSingleImage(false);
			} else if (slideshow) {
				mGridLayer.setSingleImage(true);
				mGridLayer.startSlideshow();
			}
		}
		// We record the set of enabled accounts for picasa.
		mAccountsEnabled = PicasaDataSource.getAccountStatus(this);
		Log.i(TAG, "onCreate");
	}

	public ReverseGeocoder getReverseGeocoder() {
		return mReverseGeocoder;
	}

	public Handler getHandler() {
		return mHandler;
	}

	@Override
	public void onRestart() {
		super.onRestart();
	}

	@Override
	public void onStart() {
		super.onStart();
	}

	@Override
	public void onResume() {
		super.onResume();
		if (mRenderView != null)
			mRenderView.onResume();
		if (mPause) {
			// We check to see if the authenticated accounts have changed, and
			// if so, reload the datasource.
			HashMap<String, Boolean> accountsEnabled = PicasaDataSource.getAccountStatus(this);
			String[] keys = new String[accountsEnabled.size()];
			keys = accountsEnabled.keySet().toArray(keys);
			int numKeys = keys.length;
			for (int i = 0; i < numKeys; ++i) {
				String key = keys[i];
				boolean newValue = accountsEnabled.get(key).booleanValue();
				boolean oldValue = false;
				Boolean oldValObj = mAccountsEnabled.get(key);
				if (oldValObj != null) {
					oldValue = oldValObj.booleanValue();
				}
				if (oldValue != newValue) {
					// Reload the datasource.
					mGridLayer.setDataSource(mGridLayer.getDataSource());
					break;
				}
			}
			mAccountsEnabled = accountsEnabled;
			mPause = false;
		}
	}

	@Override
	public void onPause() {
		super.onPause();
		if (mRenderView != null)
			mRenderView.onPause();
		mPause = true;
	}

	public boolean isPaused() {
		return mPause;
	}

	@Override
	public void onStop() {
		super.onStop();
		if (mGridLayer != null)
			mGridLayer.stop();
		if (mReverseGeocoder != null) {
			mReverseGeocoder.flushCache();
		}
		LocalDataSource.sThumbnailCache.flush();
		LocalDataSource.sThumbnailCacheVideo.flush();
		PicasaDataSource.sThumbnailCache.flush();
		CacheService.startCache(this, true);
	}

	@Override
	public void onDestroy() {
		// Force GLThread to exit.
		setContentView(R.layout.main);
		if (mGridLayer != null) {
			DataSource dataSource = mGridLayer.getDataSource();
			if (dataSource != null) {
				dataSource.shutdown();
			}
			mGridLayer.shutdown();
		}
		if (mWakeLock != null) {
			if (mWakeLock.isHeld()) {
				mWakeLock.release();
			}
			mWakeLock = null;
		}
		if (mReverseGeocoder != null)
			mReverseGeocoder.shutdown();
		if (mRenderView != null) {
			mRenderView.shutdown();
			mRenderView = null;
		}
		mGridLayer = null;
		super.onDestroy();
		Log.i(TAG, "onDestroy");
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		if (mGridLayer != null) {
			mGridLayer.markDirty(30);
		}
		if (mRenderView != null)
			mRenderView.requestRender();
		Log.i(TAG, "onConfigurationChanged");
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (mRenderView != null) {
			return mRenderView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
		} else {
			return super.onKeyDown(keyCode, event);
		}
	}

	private boolean isPickIntent() {
		String action = getIntent().getAction();
		return (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action));
	}

	private boolean isViewIntent() {
		String action = getIntent().getAction();
		return Intent.ACTION_VIEW.equals(action);
	}

	private boolean isImageType(String type) {
		return type.equals("vnd.android.cursor.dir/image") || type.equals("image/*");
	}

	private boolean isVideoType(String type) {
		return type.equals("vnd.android.cursor.dir/video") || type.equals("video/*");
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		case CROP_MSG: {
			if (resultCode == RESULT_OK) {
				setResult(resultCode, data);
				finish();
			}
			break;
		}
		case CROP_MSG_INTERNAL: {
			// We cropped an image, we must try to set the focus of the camera
			// to that image.
			if (resultCode == RESULT_OK) {
				String contentUri = data.getAction();
				if (mGridLayer != null) {
					mGridLayer.focusItem(contentUri);
				}
			}
			break;
		}
		}
	}

	@Override
	public void onLowMemory() {
		if (mRenderView != null) {
			mRenderView.handleLowMemory();
		}
	}

	public void launchCropperOrFinish(final MediaItem item) {
		final Bundle myExtras = getIntent().getExtras();
		String cropValue = myExtras != null ? myExtras.getString("crop") : null;
		final String contentUri = item.mContentUri;
		if (cropValue != null) {
			Bundle newExtras = new Bundle();
			if (cropValue.equals("circle")) {
				newExtras.putString("circleCrop", "true");
			}
			Intent cropIntent = new Intent();
			cropIntent.setData(Uri.parse(contentUri));
			cropIntent.setClass(this, CropImage.class);
			cropIntent.putExtras(newExtras);
			// Pass through any extras that were passed in.
			cropIntent.putExtras(myExtras);
			startActivityForResult(cropIntent, CROP_MSG);
		} else {
			if (contentUri.startsWith("http://")) {
				// This is a http uri, we must save it locally first and
				// generate a content uri from it.
				final ProgressDialog dialog = ProgressDialog.show(this, this.getResources().getString(R.string.initializing),
				        getResources().getString(R.string.running_face_detection), true, false);
				if (contentUri != null) {
					MediaScannerConnection.MediaScannerConnectionClient client = new MediaScannerConnection.MediaScannerConnectionClient() {
						public void onMediaScannerConnected() {
							if (mConnection != null) {
								try {
									final String path = UriTexture.writeHttpDataInDirectory(Gallery.this, contentUri,
									        LocalDataSource.DOWNLOAD_BUCKET_NAME);
									if (path != null) {
										mConnection.scanFile(path, item.mMimeType);
									} else {
										shutdown("");
									}
								} catch (Exception e) {
									shutdown("");
								}
							}
						}

						public void onScanCompleted(String path, Uri uri) {
							shutdown(uri.toString());
						}

						public void shutdown(String uri) {
							dialog.dismiss();
							performReturn(myExtras, uri.toString());
							if (mConnection != null) {
								mConnection.disconnect();
							}
						}
					};
					MediaScannerConnection connection = new MediaScannerConnection(Gallery.this, client);
					connection.connect();
					mConnection = connection;
				}
			} else {
				performReturn(myExtras, contentUri);
			}
		}
	}

	private void performReturn(Bundle myExtras, String contentUri) {
		Intent result = new Intent(null, Uri.parse(contentUri));
		if (myExtras != null && myExtras.getBoolean("return-data")) {
			// The size of a transaction should be below 100K.
			Bitmap bitmap = null;
			try {
				bitmap = UriTexture.createFromUri(this, contentUri, 1024, 1024, 0, null);
			} catch (IOException e) {
				;
			} catch (URISyntaxException e) {
				;
			}
			if (bitmap != null) {
				result.putExtra("data", bitmap);
			}
		}
		setResult(RESULT_OK, result);
		finish();
	}
}
