/*
* Copyright (c) 2013 Andrew Fontaine, James Finlay, Jesse Tucker, Jacob Viau, and
* Evan DeGraff
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package ca.cmput301f13t03.adventure_datetime.view;
import android.app.Activity;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.util.Log;
import android.view.*;
import android.view.View.OnClickListener;
import android.widget.*;
import ca.cmput301f13t03.adventure_datetime.R;
import ca.cmput301f13t03.adventure_datetime.model.*;
import ca.cmput301f13t03.adventure_datetime.model.Interfaces.ICommentsListener;
import ca.cmput301f13t03.adventure_datetime.model.Interfaces.ICurrentFragmentListener;
import ca.cmput301f13t03.adventure_datetime.model.Interfaces.ICurrentStoryListener;
import ca.cmput301f13t03.adventure_datetime.serviceLocator.Locator;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Shows comments available for stories & storfragments. Only available for online stories.
*
* @author James Finlay
*/
public class CommentsView extends Activity implements ICurrentStoryListener,
ICurrentFragmentListener, ICommentsListener {
private static final String TAG = "CommentsView";
public static final String COMMENT_TYPE = "forStory";
private static final int PICTURE_REQUEST = 1;
private ListView _listView;
private ProgressBar _bar;
private Story _story;
private StoryFragment _fragment;
private List<Comment> _comments;
private RowArrayAdapter _adapter;
private boolean forStoryEh;
private Uri _commentPic;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.browse);
forStoryEh = getIntent().getBooleanExtra(COMMENT_TYPE, true);
_listView = (ListView) findViewById(R.id.list_view);
_bar = (ProgressBar) findViewById(R.id.progressBar);
setUpView();
}
@Override
protected void onResume() {
if (forStoryEh)
Locator.getPresenter().Subscribe((ICurrentStoryListener)this);
else
Locator.getPresenter().Subscribe((ICurrentFragmentListener)this);
super.onResume();
}
@Override
protected void onPause() {
if (forStoryEh) {
Locator.getPresenter().Unsubscribe((ICurrentStoryListener)this);
if (_story != null) Locator.getPresenter().Unsubscribe(_story.getId());
} else {
Locator.getPresenter().Unsubscribe((ICurrentFragmentListener)this);
if (_fragment != null) Locator.getPresenter().Unsubscribe(_fragment.getFragmentID());
}
super.onPause();
}
@Override
public void OnCurrentStoryChange(Story story) {
_story = story;
Log.v(TAG, "subscribe story");
Locator.getPresenter().Subscribe((ICommentsListener) this, _story.getId());
setUpView();
}
@Override
public void OnCurrentFragmentChange(StoryFragment fragment) {
_fragment = fragment;
Log.v(TAG, "subscribe fragment");
Locator.getPresenter().Subscribe((ICommentsListener)this, _fragment.getFragmentID());
setUpView();
}
@Override
public void OnCommentsChange(List<Comment> newComments) {
_comments = newComments;
Log.v(TAG, "Comments received. Count: " + newComments.size());
setUpView();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.comment_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_new:
final Dialog dia = new Dialog(CommentsView.this);
dia.setTitle("New Comment");
dia.setContentView(R.layout.comment_add);
dia.setCancelable(true);
/** Layout items **/
final EditText txt = (EditText) dia.findViewById(R.id.content);
Button okay = (Button) dia.findViewById(R.id.okay);
Button cancel = (Button) dia.findViewById(R.id.cancel);
Button photo = (Button) dia.findViewById(R.id.media);
/* Set image to null in case 2 comments are made */
_commentPic = null;
okay.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Comment c = new Comment();
c.setAuthor(AccountService.getUserName(getContentResolver()));
c.setContent(txt.getText().toString());
if (forStoryEh) c.setTargetId(_story.getId());
else c.setTargetId(_fragment.getFragmentID());
if(_commentPic != null) {
try {
InputStream is = getContentResolver().openInputStream(_commentPic);
Bitmap bit = BitmapFactory.decodeStream(is);
c.setImage(Image.compressBitmap(bit, 85));
}
catch(Exception e) {
e.printStackTrace();
}
}
Locator.getUserController().AddComment(c);
dia.dismiss();
}
});
cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dia.dismiss();
}
});
photo.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
File picDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"adventure.datetime");
if(!picDir.exists()) picDir.mkdirs();
File pic = null;
try {
pic = File.createTempFile("adventure.comment_", "_temp", picDir);
}
catch(IOException e) {
e.printStackTrace();
}
Uri location = Uri.fromFile(pic);
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for(ResolveInfo res : listCam) {
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, location);
_commentPic = location;
cameraIntents.add(intent);
}
// Filesystem.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
startActivityForResult(chooserIntent, PICTURE_REQUEST);
}
});
dia.show();
break;
}
return true;
}
private void setUpView() {
if (_listView == null) return;
if (_comments == null) return;
if (_story == null && forStoryEh) return;
if (_fragment == null && !forStoryEh) return;
runOnUiThread(new Runnable() {
public void run() {
_adapter = new RowArrayAdapter(getApplicationContext(),
R.layout.comment_single, _comments.toArray(new Comment[_comments.size()]));
_listView.setAdapter(_adapter);
_bar.setVisibility(View.GONE);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK) {
if(requestCode == PICTURE_REQUEST) {
final boolean isCamera;
if(data == null) {
isCamera = true;
}
else {
final String action = data.getAction();
if(action == null) {
isCamera = false;
}
else {
isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
}
}
Uri selectedImageUri;
if(isCamera) {
selectedImageUri = _commentPic;
}
else {
selectedImageUri = data == null ? null : data.getData();
}
_commentPic = selectedImageUri;
}
}
}
private class RowArrayAdapter extends ArrayAdapter<Comment> {
private Context context;
private Comment[] values;
public RowArrayAdapter(Context context, int layoutResourceID, Comment values[]) {
super(context, layoutResourceID, values);
this.context = context;
this.values = values;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater. inflate(R.layout.comment_single, parent, false);
Comment item = values[position];
/** Layout Items **/
TextView author = (TextView) rowView.findViewById(R.id.author);
TextView date = (TextView) rowView.findViewById(R.id.datetime);
Button btnImage = (Button) rowView.findViewById(R.id.image_button);
RelativeLayout layImage = (RelativeLayout) rowView.findViewById(R.id.wrapper);
TextView content = (TextView) rowView.findViewById(R.id.content);
ImageView image = (ImageView) rowView.findViewById(R.id.image);
author.setText(item.getAuthor());
content.setText(item.getContent());
date.setText(item.getFormattedTimestamp());
if (item.getImage() == null)
btnImage.setVisibility(View.GONE);
else
image.setImageBitmap(item.decodeImage());
layImage.setVisibility(View.GONE);
btnImage.setOnClickListener(new ShowOnClickListener().
setUp(layImage, btnImage));
return rowView;
}
}
private class ShowOnClickListener implements OnClickListener {
private RelativeLayout _layout;
private Button _button;
public OnClickListener setUp(RelativeLayout layout, Button button) {
_layout = layout;
_button = button;
return this;
}
@Override
public void onClick(View v) {
_layout.setVisibility(View.VISIBLE);
_button.setText("Hide Image");
_button.setOnClickListener(new HideOnClickListener().
setUp(_layout, _button));
}
}
private class HideOnClickListener implements OnClickListener {
private RelativeLayout _layout;
private Button _button;
public OnClickListener setUp(RelativeLayout layout, Button button) {
_layout = layout;
_button = button;
return this;
}
@Override
public void onClick(View v) {
_layout.setVisibility(View.GONE);
_button.setText("Show Image");
_button.setOnClickListener(new ShowOnClickListener().
setUp(_layout, _button));
}
}
}