package com.abewy.android.apps.klyph.fragment;
import java.io.File;
import java.io.FileNotFoundException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import com.abewy.android.adapter.TypeAdapter;
import com.abewy.android.apps.klyph.KlyphBundleExtras;
import com.abewy.android.apps.klyph.R;
import com.abewy.android.apps.klyph.adapter.BaseAdapterSelector;
import com.abewy.android.apps.klyph.adapter.KlyphAdapter;
import com.abewy.android.apps.klyph.adapter.MultiObjectAdapter;
import com.abewy.android.apps.klyph.app.GalleryActivity;
import com.abewy.android.apps.klyph.core.KlyphDevice;
import com.abewy.android.apps.klyph.core.graph.GraphObject;
import com.abewy.android.apps.klyph.core.imageloader.ImageLoader;
import com.abewy.android.apps.klyph.core.util.AttrUtil;
import com.abewy.android.apps.klyph.widget.CheckableGalleryLayout;
import com.abewy.util.Android;
public class GalleryFragment extends KlyphFragment2
{
private static final int CAMERA_GALLERY_CODE = 1368;
private static final int CAMERA_CAPTURE_CODE = 2475;
private List<String> initUris;
private List<String> imageUris;
private ProgressBar loadingView;
// Prevent cursor to reload
private boolean cursorLoaded = false;
private boolean showCamera = false;
private boolean hasCamera = false;
private Uri cameraFileUri;
private ActionMode actionMode;
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu)
{
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu)
{
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item)
{
switch (item.getItemId())
{
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode mode)
{
actionMode = null;
goBack();
}
};
public GalleryFragment()
{
}
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_GALLERY_CODE && resultCode == Activity.RESULT_OK)
{
ArrayList<String> cameraUris = data.getStringArrayListExtra(KlyphBundleExtras.PHOTO_LIST_URI);
goBack(cameraUris);
}
else if (requestCode == CAMERA_CAPTURE_CODE && resultCode == Activity.RESULT_OK)
{
String url = "";
try
{
url = MediaStore.Images.Media.insertImage(getActivity().getContentResolver(), cameraFileUri.getPath(), "", "");
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
String uri = getRealPathFromURI(Uri.parse(url));
ArrayList<String> uris = new ArrayList<String>();
uris.add(uri);
goBack(uris);
}
}
private String getRealPathFromURI(Uri contentUri)
{
// can post image
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().getContentResolver().query(contentUri, proj, // Which columns to return
null, // WHERE clause; which rows to return (all rows)
null, // WHERE clause selection arguments (none)
null); // Order-by clause (ascending by name)
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
public void setSelectedPhotos(List<String> imageUrls)
{
this.initUris = imageUrls;
if (this.initUris == null)
this.initUris = new ArrayList<String>();
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
loadingView = (ProgressBar) view.findViewById(android.R.id.progress);
setListVisible(false);
super.onViewCreated(view, savedInstanceState);
imageUris = new ArrayList<String>();
getGridView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
getGridView().setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> gridView, View view, int position, long id)
{
GraphObject o = getAdapter().getItem(position);
if (o instanceof CameraObject)
{
Intent intent = new Intent(getActivity(), GalleryActivity.class);
intent.putExtra(KlyphBundleExtras.CAMERA_PICTURES, true);
intent.putStringArrayListExtra(KlyphBundleExtras.PHOTO_LIST_URI, (ArrayList<String>) initUris);
startActivityForResult(intent, CAMERA_GALLERY_CODE);
}
else
{
if (!Android.isMinAPI(11))
{
CheckableGalleryLayout cgl = (CheckableGalleryLayout) view;
cgl.toggle();
Picture image = (Picture) o;
image.setSelected(cgl.isChecked());
}
if (actionMode == null)
actionMode = getActivity().startActionMode(mActionModeCallback);
refreshActionModeTitle();
}
}
});
showCamera = !getActivity().getIntent().getBooleanExtra(KlyphBundleExtras.CAMERA_PICTURES, false);
hasCamera = getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)
|| getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
defineEmptyText(R.string.empty_list_no_photo);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
super.onCreateOptionsMenu(menu, inflater);
if (hasCamera && menu.findItem(R.id.menu_take_photo) == null)
{
menu.add(Menu.NONE, R.id.menu_take_photo, Menu.NONE, "Take a photo").setIcon(AttrUtil.getResourceId(getActivity(), R.attr.takePhotoIcon))
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == R.id.menu_take_photo)
{
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraFileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraFileUri); // set the image file name
// start the image capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_CODE);
return true;
}
return super.onOptionsItemSelected(item);
}
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type)
{
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type)
{
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Klyph");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists())
{
if (!mediaStorageDir.mkdirs())
{
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE)
{
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
}
else if (type == MEDIA_TYPE_VIDEO)
{
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_" + timeStamp + ".mp4");
}
else
{
return null;
}
return mediaFile;
}
@Override
protected int getNumColumn()
{
return getResources().getInteger(R.integer.klyph_gallery_num_column);
}
@Override
protected int getCustomLayout()
{
return R.layout.grid_simple;
}
private void refreshActionModeTitle()
{
int n = getGridView().getCheckedItemCount();
if (n == 0)
{
actionMode.setTitle(R.string.no_photo_selected);
}
else if (n == 1)
{
actionMode.setTitle(R.string.one_photo_selected);
}
else
{
actionMode.setTitle(getString(R.string.several_photos_selected, n));
}
}
public void goBack()
{
goBack(new ArrayList<String>());
}
public void goBack(ArrayList<String> uris)
{
Intent intent = new Intent();
SparseBooleanArray positions = getGridView().getCheckedItemPositions();
int n = getGridView().getCheckedItemCount();
if (uris == null)
uris = new ArrayList<String>();
if (n > 0)
{
MultiObjectAdapter adapter = getAdapter();
for (int i = 0; i < n; i++)
{
if (adapter.getItem(positions.keyAt(i)) instanceof Picture)
{
Picture image = (Picture) adapter.getItem(positions.keyAt(i));
uris.add(image.getUri());
}
}
}
if (uris.size() > 0)
{
intent.putStringArrayListExtra(KlyphBundleExtras.PHOTO_LIST_URI, uris);
getActivity().setResult(Activity.RESULT_OK, intent);
}
else
{
getActivity().setResult(Activity.RESULT_CANCELED, null);
}
getActivity().finish();
}
public void setCursor(Cursor cursor)
{
if (cursorLoaded == false)
{
MultiObjectAdapter adapter = new MultiObjectAdapter(getListView())
{
@Override
protected TypeAdapter<GraphObject> getAdapter(GraphObject object, int layoutType)
{
TypeAdapter<GraphObject> adapter = BaseAdapterSelector.getAdapter(object, layoutType);
if (adapter != null)
return adapter;
if (object instanceof Picture)
return new GalleryAdapter();
if (object instanceof CameraObject)
return new CameraObjectAdapter();
return null;
}
};
if (cursor != null && cursor.isClosed() == false)
{
int n = cursor.getCount();
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
for (int i = 0; i < n; i++)
{
cursor.moveToPosition(i);
imageUris.add(cursor.getString(columnIndex));
adapter.add(new Picture(cursor.getString(columnIndex)));
}
if (showCamera && hasCamera)
{
adapter.insert(new CameraObject(), 0);
}
getGridView().setAdapter(adapter);
getGridView().setVisibility(View.VISIBLE);
n = adapter.getCount();
int nSelected = 0;
for (int i = 0; i < n; i++)
{
if (adapter.getItem(i) instanceof Picture)
{
Picture image = (Picture) adapter.getItem(i);
// Log.d("GalleryFragment", "uri = " + image.getUri());
for (String uri : initUris)
{
if (image.getUri().equals(uri))
{
getGridView().setItemChecked(i, true);
nSelected++;
break;
}
}
}
}
adapter.notifyDataSetChanged();
if (nSelected > 0)
{
if (actionMode == null)
actionMode = getActivity().startActionMode(mActionModeCallback);
refreshActionModeTitle();
}
cursor.close();
}
else
{
if (showCamera && hasCamera)
{
adapter.insert(new CameraObject(), 0);
}
getGridView().setAdapter(adapter);
}
cursorLoaded = true;
}
loadingView.setVisibility(View.GONE);
getGridView().setVisibility(View.VISIBLE);
((View) getGridView().getParent()).setVisibility(View.VISIBLE);
}
@Override
public void onDestroy()
{
super.onDestroy();
initUris = null;
imageUris = null;
loadingView = null;
cameraFileUri = null;
actionMode = null;
mActionModeCallback = null;
}
private static class CameraObject extends GraphObject
{
private static final int VIEW_TYPE = 951478;
public CameraObject()
{
}
@Override
public int getItemViewType()
{
return VIEW_TYPE;
}
}
private static class CameraObjectAdapter extends KlyphAdapter
{
@Override
protected int getLayout()
{
return R.layout.item_gallery_camera_folder;
}
@Override
protected void mergeViewWithData(View view, GraphObject data)
{
setHolder(view, new CameraObjectHolder());
}
@Override
public void setLayoutParams(View view)
{
LayoutParams lp = view.getLayoutParams();
int numColumn = view.getContext().getResources().getInteger(R.integer.klyph_gallery_num_column);
lp.height = lp.width = (KlyphDevice.getDeviceWidth() - (numColumn - 1) * 2) / numColumn;
view.setLayoutParams(lp);
}
private class CameraObjectHolder
{
public CameraObjectHolder()
{
}
}
}
private static class Picture extends GraphObject
{
private static final int VIEW_TYPE = 12896475;
private String uri;
public Picture(String uri)
{
this.uri = uri;
}
public String getUri()
{
return uri;
}
@Override
public int getItemViewType()
{
return VIEW_TYPE;
}
}
private static class GalleryAdapter extends KlyphAdapter
{
private int placeHolder = -1;
@Override
protected void attachHolder(View view)
{
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
setHolder(view, new GalleryHolder(imageView));
}
@Override
protected int getLayout()
{
return R.layout.item_gallery;
}
@Override
protected void mergeViewWithData(View view, GraphObject data)
{
if (!Android.isMinAPI(11))
{
((CheckableGalleryLayout) view).setChecked(data.isSelected());
}
GalleryHolder holder = (GalleryHolder) getHolder(view);
Picture mi = (Picture) data;
holder.getImageView().setImageDrawable(null);
if (placeHolder == -1)
placeHolder = AttrUtil.getResourceId(holder.getImageView().getContext(), R.attr.squarePlaceHolderIcon);
String uri = "file://" + mi.getUri();
ImageLoader.display(holder.getImageView(), uri, placeHolder);
}
private class GalleryHolder
{
private ImageView imageView;
public GalleryHolder(ImageView imageView)
{
this.imageView = imageView;
}
public ImageView getImageView()
{
return imageView;
}
}
}
}