package com.maxiee.heartbeat.ui;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.maxiee.heartbeat.R;
import com.maxiee.heartbeat.common.GalleryUtils;
import com.maxiee.heartbeat.common.ThemeUtils;
import com.maxiee.heartbeat.common.TimeUtils;
import com.maxiee.heartbeat.common.tagview.Tag;
import com.maxiee.heartbeat.common.tagview.TagView;
import com.maxiee.heartbeat.data.DataManager;
import com.maxiee.heartbeat.database.utils.EventUtils;
import com.maxiee.heartbeat.database.utils.ImageUtils;
import com.maxiee.heartbeat.database.utils.LabelUtils;
import com.maxiee.heartbeat.database.utils.ThoughtUtils;
import com.maxiee.heartbeat.model.Event;
import com.maxiee.heartbeat.model.Image;
import com.maxiee.heartbeat.model.Label;
import com.maxiee.heartbeat.model.Thoughts;
import com.maxiee.heartbeat.ui.common.BaseActivity;
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import butterknife.Bind;
import butterknife.ButterKnife;
/**
* Created by maxiee on 15-6-11.
*/
public class AddEventActivity extends BaseActivity{
private final static String TAG = AddEventActivity.class.getSimpleName();
public static final String ID_EVENT_MODIFY = "id";
private static final int ADD_IMAGE = 1127;
public final static int ADD_EVENT_REQUEST = 100;
public final static int EVENT_NO_ID = -1;
@Bind(R.id.edit_event) EditText mEditEvent;
@Bind(R.id.first_thought_layout) TextInputLayout mLayoutFirstThought;
@Bind(R.id.first_thought) EditText mEditFirstThought;
@Bind(R.id.tagview_added) TagView mTagViewRecent;
@Bind(R.id.tagview_to_add) TagView mTagViewToAdd;
@Bind(R.id.add_imgae) TextView mTvAddImage;
@Bind(R.id.backdrop) ImageView mImageBackDrop;
@Bind(R.id.header) View mHeaderView;
@Bind(R.id.current_date) TextView mCurrentDate;
@Bind(R.id.current_time) TextView mCurrentTime;
private String mStrEvent;
private String mStrFirstThought;
private ArrayList<String> mLabels = new ArrayList<>();
private Uri mImageUri;
private DataManager mDataManager;
private boolean mIsModify = false;
private boolean mExitEnsure = false;
private long mEventId;
private String mStrEventBackup;
private ArrayList<String> mLabelsBackup = new ArrayList<>();
private String mImagePath;
private String mImagePathBackup;
private boolean mHasImage = false;
private long mTimestamp;
private long mTimestampBackup;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_event);
ButterKnife.bind(this);
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setTitle("");
Intent i = getIntent();
// new event or edit event?
mEventId = i.getLongExtra(ID_EVENT_MODIFY, EVENT_NO_ID);
if (mEventId != EVENT_NO_ID) { // edit event
mIsModify = true;
Event e = EventUtils.getEvent(this, mEventId);
mStrEventBackup = e.getEvent();
mEditEvent.setText(mStrEventBackup);
// TODO hack
ArrayList<Label> labels = LabelUtils.getLabelsByEvent(this, e);
for (Label l : labels) mLabels.add(l.getLabel());
mLabelsBackup = new ArrayList<>(mLabels);
Image image = ImageUtils.getImageByEventId(this, mEventId);
if (image != null) {
mImagePath = image.getPath();
mTvAddImage.setText(R.string.change_image);
Glide.with(this).load(GalleryUtils.getImagePath(mImagePath)).into(mImageBackDrop);
changeHeaderToImage();
mImagePathBackup = mImagePath;
mHasImage = true;
} else {
mHasImage = false;
}
mTimestamp = e.getTimestamp();
mTimestampBackup = mTimestamp;
} else { // new event
mTimestamp = System.currentTimeMillis();
mTimestampBackup = mTimestamp;
}
initDate();
if (mIsModify) mLayoutFirstThought.setVisibility(View.GONE);
mDataManager = DataManager.getInstance(this);
mTvAddImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GalleryUtils.openGallery(AddEventActivity.this);
}
});
initTagsToAdd();
initTagsRecent();
mTagViewToAdd.setOnTagClickListener(new TagView.OnTagClickListener() {
@Override
public void onTagClick(Tag tag, int position) {
if (tag.text.equals(getString(R.string.new_tag))) {
final AlertDialog.Builder builder = new AlertDialog.Builder(
AddEventActivity.this,
ThemeUtils.getCurrentDialogTheme(AddEventActivity.this));
builder.setTitle(R.string.new_tag);
final EditText input = new EditText(AddEventActivity.this);
final FrameLayout container = new FrameLayout(AddEventActivity.this);
final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(40, 40, 40, 40);
container.addView(input, params);
builder.setView(container);
builder.setPositiveButton(R.string.add, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String label = input.getText().toString();
if (label.isEmpty()) return;
if (!mLabels.contains(label)) mLabels.add(label);
initTagsToAdd();
}
});
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
}
}
});
mTagViewToAdd.setOnTagDeleteListener(new TagView.OnTagDeleteListener() {
@Override
public void onTagDeleted(Tag tag, int position) {
if (!mLabels.isEmpty()) {
mLabels.remove(tag.text);
}
}
});
mTagViewRecent.setOnTagClickListener(new TagView.OnTagClickListener() {
@Override
public void onTagClick(Tag tag, int position) {
if (mLabels.contains(tag.text)) {
return;
}
mLabels.add(tag.text);
initTagsToAdd();
}
});
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mStrEvent = mEditEvent.getText().toString();
mStrFirstThought = mEditFirstThought.getText().toString();
if (mStrEvent.isEmpty()) {
Toast.makeText(AddEventActivity.this,
getString(R.string.notempty),
Toast.LENGTH_LONG).show();
return;
}
if (!mIsModify) {
new AddEventTask().execute();
} else {
new UpdateEventTask().execute();
}
}
});
}
private void initDate() {
updateDate();
mCurrentDate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(mTimestamp);
DatePickerDialog dpd = DatePickerDialog.newInstance(
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
mTimestamp = TimeUtils.updateTimestampWithDate(year, monthOfYear, dayOfMonth, mTimestamp);
updateDate();
}
},
cal.get(Calendar.YEAR),
cal.get(Calendar.MONTH),
cal.get(Calendar.DAY_OF_MONTH)
);
dpd.show(getFragmentManager(), getString(R.string.date));
}
});
mCurrentTime.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(mTimestamp);
TimePickerDialog tpd = TimePickerDialog.newInstance(
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {
mTimestamp = TimeUtils.updateTimestampWithTime(hourOfDay, minute, second, mTimestamp);
updateDate();
}
},
cal.get(Calendar.HOUR_OF_DAY),
cal.get(Calendar.MINUTE),
cal.get(Calendar.SECOND),
true);
tpd.show(getFragmentManager(), getString(R.string.date));
}
});
}
private void updateDate() {
mCurrentDate.setText(TimeUtils.parseDateDate(this, mTimestamp));
mCurrentTime.setText(TimeUtils.parseDateTime(this, mTimestamp));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
String path = GalleryUtils.onActivityResult(this, requestCode, resultCode, data);
if (path == null) return;
Glide.with(this).load(GalleryUtils.getImagePath(path)).into(mImageBackDrop);
mHasImage = true;
changeHeaderToImage();
mTvAddImage.setText(R.string.change_image);
mImagePath = path;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
ensureExit();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
ensureExit();
return true;
}
return super.onKeyDown(keyCode, event);
}
private void changeHeaderToImage() {
mHeaderView.setVisibility(View.GONE);
mImageBackDrop.setVisibility(View.VISIBLE);
}
private void ensureExit() {
if (!mExitEnsure) {
mExitEnsure = true;
Toast.makeText(this, getString(R.string.exit_next_time), Toast.LENGTH_SHORT).show();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
mExitEnsure = false;
}
}, 2000);
} else {
this.onBackPressed();
}
}
public void initTagsToAdd() {
final Tag newTag = new Tag(getString(R.string.new_tag));
mTagViewToAdd.clear();
mTagViewToAdd.addTag(newTag);
for (String tag: mLabels) {
Tag useTag = new Tag(tag);
useTag.isDeletable = true;
mTagViewToAdd.addTag(useTag);
}
}
public void initTagsRecent() {
Map<Long, Integer> recentLabels = LabelUtils.getFreq(this);
if (recentLabels == null) {
return;
}
ArrayList<Map.Entry<Long,Integer>> list = new ArrayList<>(recentLabels.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Long, Integer>>() {
@Override
public int compare(Map.Entry<Long, Integer> lhs, Map.Entry<Long, Integer> rhs) {
return rhs.getValue() - lhs.getValue();
}
});
for (Map.Entry<Long,Integer> labelId : list) {
Tag tag = new Tag(LabelUtils.getLabelByLabelId(this, labelId.getKey()).getLabel());
tag.hasExtraInfo = true;
tag.extraInfoString = " x" + String.valueOf(labelId.getValue());
tag.layoutColor = getResources().getColor(R.color.tag_gray);
tag.tagTextSize = 10.0f;
mTagViewRecent.addTag(tag);
}
}
private class AddEventTask extends AsyncTask<Void, Void, Void> {
private long mEventKey;
@Override
protected Void doInBackground(Void... params) {
// add event
Event newEvent = EventUtils.addEvent(AddEventActivity.this, mStrEvent, mTimestamp);
mEventKey = newEvent.getId();
// add thought
if (!mStrFirstThought.isEmpty()) {
ThoughtUtils.addThought(AddEventActivity.this, mEventKey, mStrFirstThought, mTimestamp, Thoughts.Thought.HAS_NO_RES, Thoughts.Thought.HAS_NO_PATH);
}
// add labels
LabelUtils.addLabels(AddEventActivity.this, mEventKey, mLabels);
if (mImagePath != null) {
ImageUtils.addImage(AddEventActivity.this, mEventKey, mImagePath);
}
mDataManager.addEvent(newEvent);
Log.d(TAG, "添加事件");
Log.d(TAG, "id: " + String.valueOf(mEventKey));
Log.d(TAG, "labels: " + mLabels.toString());
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
Intent i = new Intent(AddEventActivity.this, EventDetailActivity.class);
i.putExtra(EventDetailActivity.EXTRA_NAME, mEventKey);
startActivity(i);
finish();
}
}
private class UpdateEventTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
if (!mStrEventBackup.equals(mStrEvent) || mTimestamp != mTimestampBackup) {
// TODO temp Event
Event e = new Event(mEventId, mStrEvent, mTimestamp);
EventUtils.updateEvent(AddEventActivity.this, e);
}
if (mHasImage && !mImagePath.equals(mImagePathBackup)) {
// update
ImageUtils.updateImageByEventId(AddEventActivity.this, mEventId, mImagePath);
} else if (!mHasImage && mImagePath != null) {
// add
ImageUtils.addImage(AddEventActivity.this, mEventId, mImagePath);
}
for (String l: mLabels) {
long labelKey = LabelUtils.hasLabel(AddEventActivity.this, l);
if (labelKey == LabelUtils.NOT_FOUND) {
LabelUtils.addLabel(AddEventActivity.this, mEventId, l);
} else {
// TODO temp label
Label label = new Label(labelKey, "");
ArrayList<Event> events = EventUtils.getEvents(AddEventActivity.this, label);
boolean alreadyHas = false;
for (Event event:events)
if (event.getId() == mEventId)
alreadyHas = true;
if (!alreadyHas) {
LabelUtils.addRelation(AddEventActivity.this, mEventId, labelKey);
}
}
}
for (String l:mLabelsBackup)
if (!mLabels.contains(l)) {
long key = LabelUtils.hasLabel(AddEventActivity.this, l);
if (key != LabelUtils.NOT_FOUND) {
LabelUtils.deleteRelation(AddEventActivity.this, mEventId, key);
}
}
mDataManager.updateEvent(mEventId);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
finish();
}
}
}