/*******************************************************************************
* Copyright (c) 2010 Denis Solonenko.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v2.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* Denis Solonenko - initial API and implementation
******************************************************************************/
package ru.orangesoftware.financisto2.activity;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import ru.orangesoftware.financisto2.R;
import ru.orangesoftware.financisto2.recur.Recurrence;
import ru.orangesoftware.financisto2.recur.RecurrenceFrequency;
import ru.orangesoftware.financisto2.recur.DateRecurrenceIterator;
import ru.orangesoftware.financisto2.recur.RecurrencePattern;
import ru.orangesoftware.financisto2.recur.RecurrencePeriod;
import ru.orangesoftware.financisto2.recur.RecurrenceUntil;
import ru.orangesoftware.financisto2.recur.RecurrenceView;
import ru.orangesoftware.financisto2.recur.RecurrenceViewFactory;
import ru.orangesoftware.financisto2.datetime.DateUtils;
import ru.orangesoftware.financisto2.utils.EnumUtils;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
public class RecurrenceActivity extends AbstractActivity {
public static final String RECURRENCE_PATTERN = "recurrence_pattern";
private static final RecurrenceFrequency[] frequencies = RecurrenceFrequency.values();
private static final RecurrenceUntil[] untils = RecurrenceUntil.values();
private LinearLayout layout;
private RecurrenceViewFactory viewFactory;
private TextView startDateView;
private TextView startTimeView;
private Recurrence recurrence = Recurrence.noRecur();
private RecurrenceView recurrencePatternView;
private RecurrenceView recurrencePeriodView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.recurrence);
layout = (LinearLayout)findViewById(R.id.layout);
viewFactory = new RecurrenceViewFactory(this);
Intent intent = getIntent();
if (intent != null) {
String recurrencePattern = intent.getStringExtra(RECURRENCE_PATTERN);
if (recurrencePattern != null) {
try {
recurrence = Recurrence.parse(recurrencePattern);
} catch (Exception e) {
recurrence = Recurrence.noRecur();
}
recurrencePatternView = viewFactory.create(recurrence.pattern);
recurrencePeriodView = viewFactory.create(recurrence.period.until);
}
}
createNodes();
if (recurrencePatternView != null) {
recurrencePatternView.stateFromString(recurrence.pattern.params);
if (recurrencePeriodView != null) {
recurrencePeriodView.stateFromString(recurrence.period.params);
}
}
Button bOK = (Button)findViewById(R.id.bOK);
bOK.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
if (recurrencePatternView == null) {
Intent data = new Intent();
setResult(RESULT_OK, data);
finish();
} else {
if (recurrencePatternView.validateState() && (recurrencePeriodView == null || recurrencePeriodView.validateState())) {
Intent data = new Intent();
data.putExtra(RECURRENCE_PATTERN, stateToString());
setResult(RESULT_OK, data);
finish();
}
}
}
});
Button bCancel = (Button)findViewById(R.id.bCancel);
bCancel.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
setResult(RESULT_CANCELED);
finish();
}
});
}
protected String stateToString() {
if (recurrencePatternView != null) {
recurrence.pattern = RecurrencePattern.parse(recurrencePatternView.stateToString());
if (recurrencePeriodView != null) {
recurrence.period = RecurrencePeriod.parse(recurrencePeriodView.stateToString());
} else {
recurrence.period = RecurrencePeriod.noEndDate();
}
} else {
recurrence.pattern = RecurrencePattern.noRecur();
recurrence.period = RecurrencePeriod.noEndDate();
}
return recurrence.stateToString();
}
public void createNodes() {
layout.removeAllViews();
x.addListNode(layout, R.id.recurrence_pattern, R.string.recurrence_pattern, getString(recurrence.pattern.frequency.titleId));
if (recurrencePatternView != null) {
recurrencePatternView.createNodes(layout);
startDateView = x.addInfoNode(layout, R.id.start_date, R.string.recurrence_period_starts_on_date,
DateUtils.getShortDateFormat(this).format(recurrence.getStartDate().getTime()));
startTimeView = x.addInfoNode(layout, R.id.start_time, R.string.recurrence_period_starts_on_time,
DateUtils.getTimeFormat(this).format(recurrence.getStartDate().getTime()));
if (recurrence.pattern.frequency != RecurrenceFrequency.GEEKY) {
x.addListNode(layout, R.id.recurrence_period, R.string.recurrence_period, getString(recurrence.period.until.titleId));
if (recurrencePeriodView != null) {
recurrencePeriodView.createNodes(layout);
}
}
x.addInfoNodeSingle(layout, R.id.result, R.string.recurrence_evaluate);
}
}
@Override
protected void onClick(View v, int id) {
switch (id) {
case R.id.recurrence_pattern: {
ArrayAdapter<String> adapter = EnumUtils.createDropDownAdapter(this, frequencies);
x.selectPosition(this, R.id.recurrence_pattern, R.string.recurrence_pattern, adapter, recurrence.pattern.frequency.ordinal());
} break;
case R.id.recurrence_period: {
ArrayAdapter<String> adapter = EnumUtils.createDropDownAdapter(this, untils);
x.selectPosition(this, R.id.recurrence_period, R.string.recurrence_period, adapter, recurrence.period.until.ordinal());
} break;
case R.id.start_date: {
final Calendar c = recurrence.getStartDate();
new DatePickerDialog(this, new OnDateSetListener(){
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
recurrence.updateStartDate(year, monthOfYear, dayOfMonth);
startDateView.setText(DateUtils.getMediumDateFormat(RecurrenceActivity.this).format(c.getTime()));
}
}, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH)).show();
} break;
case R.id.start_time: {
final Calendar c = recurrence.getStartDate();
boolean is24Format = DateUtils.is24HourFormat(RecurrenceActivity.this);
new TimePickerDialog(RecurrenceActivity.this, new OnTimeSetListener(){
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
recurrence.updateStartTime(hourOfDay, minute, 0);
startTimeView.setText(DateUtils.getTimeFormat(RecurrenceActivity.this).format(c.getTime()));
}
}, c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), is24Format).show();
} break;
case R.id.result: {
try {
String stateAsString = stateToString();
Log.d("RRULE", stateAsString);
Recurrence r = Recurrence.parse(stateAsString);
DateRecurrenceIterator ri = r.createIterator(new Date());
StringBuilder sb = new StringBuilder();
DateFormat df = DateUtils.getMediumDateFormat(this);
String n = String.format("%n");
int count = 0;
while (count++ < 10 && ri.hasNext()) {
Date nextDate = ri.next();
if (count > 1) {
sb.append(n);
}
sb.append(df.format(nextDate.getTime()));
}
if (ri.hasNext()) {
sb.append(n).append("...");
}
new AlertDialog.Builder(this)
.setTitle(getString(r.pattern.frequency.titleId))
.setMessage(sb.toString())
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.show();
} catch (Exception ex) {
Toast.makeText(this, ex.getClass().getSimpleName()+":"+ex.getMessage(), Toast.LENGTH_SHORT).show();
}
} break;
}
}
@Override
public void onSelectedPos(int id, int selectedPos) {
switch (id) {
case R.id.recurrence_pattern:
RecurrenceFrequency newFrequency = frequencies[selectedPos];
if (recurrence.pattern.frequency != newFrequency) {
recurrence.pattern = RecurrencePattern.empty(newFrequency);
recurrencePatternView = viewFactory.create(recurrence.pattern);
createNodes();
}
break;
case R.id.recurrence_period:
RecurrenceUntil newUntil = untils[selectedPos];
if (recurrence.period.until != newUntil) {
recurrence.period = RecurrencePeriod.empty(newUntil);
recurrencePeriodView = viewFactory.create(newUntil);
createNodes();
}
break;
}
}
}