content: /*
   * Copyright 2013 Chris Banes
   *
   * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package com.zhaojian.jolly.fragment;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.List;
  
  import android.app.Activity;
  import android.app.Fragment;
  import android.app.LoaderManager;
  import android.content.CursorLoader;
  import android.content.Intent;
  import android.content.Loader;
  import android.content.SharedPreferences;
  import android.database.Cursor;
  import android.media.MediaScannerConnection.OnScanCompletedListener;
  import android.net.Uri;
  import android.os.Build.VERSION;
  import android.os.Bundle;
  import android.preference.PreferenceManager;
  import android.provider.MediaStore;
  import android.provider.MediaStore.Images;
  import android.support.v4.app.ActivityCompat;
  import android.support.v4.app.ActivityOptionsCompat;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.view.ViewGroup;
  import android.widget.AdapterView;
  import android.widget.AdapterView.OnItemClickListener;
  import android.widget.AdapterView.OnItemSelectedListener;
  import android.widget.ArrayAdapter;
  import android.widget.Button;
  import android.widget.GridView;
  import android.widget.LinearLayout;
  import android.widget.Spinner;
  
  import com.commonsware.cwac.merge.MergeAdapter;
  import com.zhaojian.jolly.adapter.CameraBaseAdapter;
  import com.zhaojian.jolly.adapter.UsersPhotosCursorAdapter;
  import com.zhaojian.jolly.constant.PreferenceConstants;
  import com.zhaojian.jolly.controller.PhotoUploadController;
  import com.zhaojian.jolly.listener.OnNumChangeListener;
  import com.zhaojian.jolly.model.MediaStoreBucket;
  import com.zhaojian.jolly.model.PhotoUpload;
  import com.zhaojian.jolly.selectphotos.PhotoViewerActivity;
  import com.zhaojian.jolly.tasks.MediaStoreBucketsAsyncTask;
  import com.zhaojian.jolly.tasks.MediaStoreBucketsAsyncTask.MediaStoreBucketsResultListener;
  import com.zhaojian.jolly.utils.MediaStoreCursorHelper;
  import com.zhaojian.jolly.utils.PhotupCursorLoader;
  import com.zhaojian.jolly.utils.Utils;
  import com.zhaojian.select_photo_library.R;
  
  public class UserPhotosFragment extends Fragment implements
  		OnItemClickListener, LoaderManager.LoaderCallbacks<Cursor>,
  		MediaStoreBucketsResultListener, OnItemSelectedListener,
  		OnScanCompletedListener, OnNumChangeListener {
  
  	static final int RESULT_CAMERA = 101;
  	static final int RESULT_PHOTOVIEW = 102;
  	
  	static final String PHOTO_URIS="photo_uris";
  
  	static final String SAVE_PHOTO_URI = "camera_photo_uri";
  
  	static final String LOADER_PHOTOS_BUCKETS_PARAM = "bucket_id";
  	static final int LOADER_USER_PHOTOS_EXTERNAL = 0x01;
  
  	private MergeAdapter mAdapter;
  	private UsersPhotosCursorAdapter mPhotoAdapter;
  	private GridView mPhotoGrid;
  	private LinearLayout back_btn;
  	private Button finish_btn;
  
  	private ArrayAdapter<MediaStoreBucket> mBucketAdapter;
  	private Spinner mBucketSpinner;
  	private final ArrayList<MediaStoreBucket> mBuckets = new ArrayList<MediaStoreBucket>();
  
  	private PhotoUploadController mPhotoSelectionController;
  	private File mPhotoFile;
  	private SharedPreferences mPrefs;
  
  	@Override
  	public void onActivityCreated(Bundle savedInstanceState) {
  		super.onActivityCreated(savedInstanceState);
  
  		if (null != savedInstanceState) {
  			if (savedInstanceState.containsKey(SAVE_PHOTO_URI)) {
  				mPhotoFile = new File(
  						savedInstanceState.getString(SAVE_PHOTO_URI));
  			}
  		}
  	}
  
  	@Override
  	public void onActivityResult(int requestCode, int resultCode, Intent data) {
  		switch (requestCode) {
  		case RESULT_CAMERA:
  			if (null != mPhotoFile) {
  				if (resultCode == Activity.RESULT_OK) {
  					Utils.scanMediaJpegFile(getActivity(), mPhotoFile, this);
  				} else {
  					mPhotoFile.delete();
  				}
  				mPhotoFile = null;
  			}
  			return;
  		}
  		switch(resultCode){
  
  		case RESULT_PHOTOVIEW:
  			excuteFinish();
  			break;
  		}
  
  		super.onActivityResult(requestCode, resultCode, data);
  	}
  
  	@Override
  	public void onAttach(Activity activity) {
  		mPhotoSelectionController = PhotoUploadController
  				.getFromContext(activity);
  		mPhotoSelectionController.addMyEventListener(this);
  		super.onAttach(activity);
  	}
  
  	@Override
  	public void onResume() {
  		// TODO Auto-generated method stub
  		super.onResume();
  		if (mPhotoAdapter != null) {
  			mPhotoAdapter.notifyDataSetChanged();
  		}
  	}
  
  	public void onBucketsLoaded(final List<MediaStoreBucket> buckets) {
  		if (null != buckets && !buckets.isEmpty()) {
  			mBuckets.clear();
  			mBuckets.addAll(buckets);
  			mBucketAdapter.notifyDataSetChanged();
  			// setSelectedBucketFromPrefs();
  		}
  	}
  
  	public void onCreate(Bundle savedInstanceState) {
  		super.onCreate(savedInstanceState);
  
  		mAdapter = new MergeAdapter();
  
  		if (Utils.hasCamera(getActivity())) {
  			mAdapter.addAdapter(new CameraBaseAdapter(getActivity()));
  		}
  		mPhotoAdapter = new UsersPhotosCursorAdapter(getActivity(), null);
  		mAdapter.addAdapter(mPhotoAdapter);
  
  		mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
  
  		mBucketAdapter = new ArrayAdapter<MediaStoreBucket>(getActivity(),
  				Utils.getSpinnerItemResId(), mBuckets);
  		mBucketAdapter
  				.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
  
  	}
  
  	public Loader<Cursor> onCreateLoader(final int id, Bundle bundle) {
  
  		CursorLoader cursorLoader = null;
  
  		switch (id) {
  		case LOADER_USER_PHOTOS_EXTERNAL:
  			String selection = null;
  			String[] selectionArgs = null;
  
  			if (null != bundle
  					&& bundle.containsKey(LOADER_PHOTOS_BUCKETS_PARAM)) {
  				selection = Images.Media.BUCKET_ID + " = ?";
  				selectionArgs = new String[] { bundle
  						.getString(LOADER_PHOTOS_BUCKETS_PARAM) };
  			}
  
  			cursorLoader = new PhotupCursorLoader(getActivity(),
  					MediaStoreCursorHelper.MEDIA_STORE_CONTENT_URI,
  					MediaStoreCursorHelper.PHOTOS_PROJECTION, selection,
  					selectionArgs, MediaStoreCursorHelper.PHOTOS_ORDER_BY,
  					false);
  			break;
  		}
  
  		return cursorLoader;
  	}
  
  	@Override
  	public View onCreateView(LayoutInflater inflater, ViewGroup container,
  			Bundle savedInstanceState) {
  		View view = inflater.inflate(R.layout.fragment_user_photos, null);
  
  		mPhotoGrid = (GridView) view.findViewById(R.id.gv_photos);
  		mPhotoGrid.setAdapter(mAdapter);
  		mPhotoGrid.setOnItemClickListener(this);
  
  		mBucketSpinner = (Spinner) view.findViewById(R.id.sp_buckets);
  		mBucketSpinner.setOnItemSelectedListener(this);
  		mBucketSpinner.setAdapter(mBucketAdapter);
  
  		back_btn = (LinearLayout) view.findViewById(R.id.back_btn);
  		back_btn.setOnClickListener(new OnClickListener() {
  			
  			@Override
  			public void onClick(View arg0) {
  				getActivity().finish();
  			}
  		});
  
  		finish_btn = (Button) view.findViewById(R.id.finish_btn);
  		finish_btn.setOnClickListener(new OnClickListener() {
  			
  			@Override
  			public void onClick(View arg0) {
  				excuteFinish();
  			}
  		});
  
  		OnChangeNum();
  		return view;
  	}
  
  	@Override
  	public void onDestroy() {
  		super.onDestroy();
  		saveSelectedBucketToPrefs();
  	}
  
  	public void onItemClick(AdapterView<?> gridView, View view, int position,
  			long id) {
  		if (view.getId() == R.id.iv_camera_button) {
  			takePhoto();
  		} else {
  			Bundle b = null;
  			if (VERSION.SDK_INT >= 16) {
  				ActivityOptionsCompat options = ActivityOptionsCompat
  						.makeThumbnailScaleUpAnimation(view,
  								Utils.drawViewOntoBitmap(view), 0, 0);
  				b = options.toBundle();
  			}
  
  			Intent intent = new Intent(getActivity(), PhotoViewerActivity.class);
  
  			// Need take Camera icon into account so minus 1
  			intent.putExtra(PhotoViewerActivity.EXTRA_POSITION, position - 1);
  			intent.putExtra(PhotoViewerActivity.EXTRA_MODE,
  					PhotoViewerActivity.MODE_ALL_VALUE);
  
  			MediaStoreBucket bucket = (MediaStoreBucket) mBucketSpinner
  					.getSelectedItem();
  			intent.putExtra(PhotoViewerActivity.EXTRA_BUCKET_ID, bucket.getId());
  
  			ActivityCompat.startActivityForResult(getActivity(), intent,
  					RESULT_PHOTOVIEW, b);
  		}
  
  	}
  
  	public void onItemSelected(AdapterView<?> adapterView, View view,
  			int position, long id) {
  		MediaStoreBucket item = (MediaStoreBucket) adapterView
  				.getItemAtPosition(position);
  		if (null != item) {
  			loadBucketId(item.getId());
  		}
  	}
  
  	public void onLoaderReset(Loader<Cursor> loader) {
  
  	}
  
  	public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
  		switch (loader.getId()) {
  		case LOADER_USER_PHOTOS_EXTERNAL:
  			mPhotoAdapter.swapCursor(data);
  			mPhotoGrid.setSelection(0);
  			break;
  		}
  	}
  
  	public void onNothingSelected(AdapterView<?> view) {
  		// NO-OP
  	}
  
  	@Override
  	public void onSaveInstanceState(Bundle outState) {
  		if (null != mPhotoFile) {
  			outState.putString(SAVE_PHOTO_URI, mPhotoFile.getAbsolutePath());
  		}
  		super.onSaveInstanceState(outState);
  	}
  
  	public void onScanCompleted(String path, Uri uri) {
  		getActivity().runOnUiThread(new Runnable() {
  			public void run() {
  				MediaStoreBucket bucket = getSelectedBucket();
  				if (null != bucket) {
  					loadBucketId(bucket.getId());
  				}
  			}
  		});
  	}
  
  	@Override
  	public void onStart() {
  		super.onStart();
  
  		// Load buckets
  		MediaStoreBucketsAsyncTask.execute(getActivity(), this);
  	}
  
  	public void selectAll() {
  		Cursor cursor = mPhotoAdapter.getCursor();
  		if (null != cursor) {
  			ArrayList<PhotoUpload> selections = MediaStoreCursorHelper
  					.photosCursorToSelectionList(
  							MediaStoreCursorHelper.MEDIA_STORE_CONTENT_URI,
  							cursor);
  			mPhotoSelectionController.addSelections(selections);
  		}
  	}
  
  	private MediaStoreBucket getSelectedBucket() {
  		if (null != mBucketSpinner) {
  			return (MediaStoreBucket) mBucketSpinner.getSelectedItem();
  		}
  		return null;
  	}
  
  	private void loadBucketId(String id) {
  		if (isAdded()) {
  			Bundle bundle = new Bundle();
  			if (null != id) {
  				bundle.putString(LOADER_PHOTOS_BUCKETS_PARAM, id);
  			}
  			try {
  				getLoaderManager().restartLoader(LOADER_USER_PHOTOS_EXTERNAL,
  						bundle, this);
  			} catch (IllegalStateException e) {
  				e.printStackTrace();
  				// Can sometimes catch with: Fragment not attached to Activity.
  				// Not much we can do to recover
  			}
  		}
  	}
  
  	private void saveSelectedBucketToPrefs() {
  		MediaStoreBucket bucket = getSelectedBucket();
  		if (null != bucket && null != mPrefs) {
  			mPrefs.edit()
  					.putString(
  							PreferenceConstants.PREF_SELECTED_MEDIA_BUCKET_ID,
  							bucket.getId()).commit();
  		}
  	}
  
  	private void setSelectedBucketFromPrefs() {
  		if (null != mBucketSpinner) {
  			int newSelection = 0;
  
  			if (null != mPrefs) {
  				final String lastBucketId = mPrefs
  						.getString(
  								PreferenceConstants.PREF_SELECTED_MEDIA_BUCKET_ID,
  								null);
  				if (null != lastBucketId) {
  					for (int i = 0, z = mBuckets.size(); i < z; i++) {
  						if (lastBucketId.equals(mBuckets.get(i).getId())) {
  							newSelection = i;
  							break;
  						}
  					}
  				}
  			}
  
  			// If we have a new position, then just set it. If it's our current
  			// position, then call onItemSelected manually
  			if (newSelection != mBucketSpinner.getSelectedItemPosition()) {
  				mBucketSpinner.setSelection(newSelection);
  			} else {
  				onItemSelected(mBucketSpinner, null, newSelection, 0);
  			}
  		}
  	}
  
  	private void takePhoto() {
  		if (null == mPhotoFile) {
  			Intent takePictureIntent = new Intent(
  					MediaStore.ACTION_IMAGE_CAPTURE);
  			mPhotoFile = Utils.getCameraPhotoFile();
  			takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
  					Uri.fromFile(mPhotoFile));
  			startActivityForResult(takePictureIntent, RESULT_CAMERA);
  		}
  	}
  
  	@Override
  	public void OnChangeNum() {
  		finish_btn.setText("完成(" + mPhotoSelectionController.getSelectedCount()
  				+ ")");
  	}
  
  	private void excuteFinish() {
  		if (mPhotoSelectionController.getSelectedCount() > 0) {
  			Intent intent = new Intent();
  			ArrayList<String> uri = new ArrayList<String>();
  			for(PhotoUpload photoUpload:mPhotoSelectionController.getSelected()){
  				String filePath = Utils.getPathFromContentUri(
  						getActivity().getContentResolver(), photoUpload.getOriginalPhotoUri());
  				uri.add(filePath);
  			}
  			intent.putStringArrayListExtra(PHOTO_URIS,uri);
  			getActivity().setResult(Activity.RESULT_OK,intent);
  			mPhotoSelectionController.clearSelected();
  			getActivity().finish();
  		}
  		
  	}
  }
  