package com.example.checkregister;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class CheckRegisterActivity extends Activity {
  private EditText checkNumText;
  private EditText dateText;
  private AutoCompleteTextView payeeText;
  private EditText amountText;
  private EditText memoText;
  private TextView balanceView;
  private Button enterButton;
  private Context context;
  public static final String datafile = "checkdata.txt";
  private SharedPreferences.OnSharedPreferenceChangeListener prefListener;
  private CheckRegisterDBAdapter dba;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    context = this;
    setContentView(R.layout.check_input);

    // Get references to input fields
    checkNumText = (EditText) findViewById(R.id.checkNumText);
    dateText = (EditText) findViewById(R.id.dateText);
    payeeText = (AutoCompleteTextView) findViewById(R.id.payeeText);
    amountText = (EditText) findViewById(R.id.amountText);
    memoText = (EditText) findViewById(R.id.memoText);
    balanceView = (TextView) findViewById(R.id.balanceView);
    enterButton = (Button) findViewById(R.id.enterButton);
    setLabelsFromPreferences(PreferenceManager
        .getDefaultSharedPreferences(context));

    // Register listener for preference changes
    prefListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
      @Override
      public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
        setLabelsFromPreferences(prefs);
      }
    };
    PreferenceManager.getDefaultSharedPreferences(context)
        .registerOnSharedPreferenceChangeListener(prefListener);

    // Instantiate DB adapter
    dba = new CheckRegisterDBAdapter(this);
    dba.open();

    setPayeeList();

    Bundle b = getIntent().getExtras();
    if (b != null) {
      loadRecord(b.getLong("ID"));
    }
    else {
      clear_form();
    }

    // Handle Save button to add new check record
    enterButton = (Button) findViewById(R.id.enterButton);
    enterButton.setOnClickListener(new Button.OnClickListener() {
      @Override
      public void onClick(View v) {
        // save data to persistent storage
        saveCheckInput();
      }
    });

  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    MenuItem prefItem = menu.add(0, 0, 0, "Preferences");
    prefItem.setIcon(android.R.drawable.ic_menu_preferences);
    MenuItem fileItem = menu.add(0, 1, 1, "Logfile");
    fileItem.setIcon(android.R.drawable.ic_menu_recent_history);
    MenuItem viewItem = menu.add(0, 2, 2, "History");
    viewItem.setIcon(android.R.drawable.ic_menu_view);
    MenuItem editItem = menu.add(0, 3, 3, "Edit");
    editItem.setIcon(android.R.drawable.ic_menu_edit);
    MenuItem monthlyItem = menu.add(0, 4, 4, "Monthly");
    monthlyItem.setIcon(android.R.drawable.ic_menu_view);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    int itemid = item.getItemId();
    switch (itemid) {
    case 0:
      startActivity(new Intent("com.example.checkregister.PREFERENCES"));
      break;
    case 1:
      startActivity(new Intent("com.example.checkregister.FILE_VIEW"));
      break;
    case 2:
      startActivity(new Intent("com.example.checkregister.HISTORY"));
      break;
    case 3:
      startActivity(new Intent("com.example.checkregister.LIST"));
      break;
    case 4:
      startActivity(new Intent("com.example.checkregister.MONTHLY"));
      break;
    }
    return true;
  }

  public void setLabelsFromPreferences(SharedPreferences prefs) {
    TextView amountLabel = (TextView) findViewById(R.id.amountLabel);
    amountLabel.setText(prefs.getString("currencySymbol", "$"));
  }

  private void setDateFieldCurrentDate() {
    // Initialize date field with current date
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
    Date curDate = new Date(java.lang.System.currentTimeMillis());
    String dateString = df.format(curDate);
    dateText.setText(dateString);
  }

  private void loadRecord(long id) {
    Cursor c = dba.getCheckRecord(id);
    if (c.moveToFirst()) {
      checkNumText.setText(c.getString(c
          .getColumnIndex(CheckRegisterDBAdapter.KEY_CHECKNUM)));
      dateText.setText(c.getString(c
          .getColumnIndex(CheckRegisterDBAdapter.KEY_DATE)));
      payeeText.setText(c.getString(c
          .getColumnIndex(CheckRegisterDBAdapter.KEY_PAYEE)));
      amountText.setText(c.getString(c
          .getColumnIndex(CheckRegisterDBAdapter.KEY_AMOUNT)));
      memoText.setText(c.getString(c
          .getColumnIndex(CheckRegisterDBAdapter.KEY_MEMO)));
      balanceView.setText(c.getString(c
          .getColumnIndex(CheckRegisterDBAdapter.KEY_BALANCE)));
      enterButton.setText(R.string.enterButtonSave);
    }
    else {
      clear_form();
    }
    c.close();
  }

  private void clear_form() {
    int checkNum = 0;
    try { checkNum = dba.getNextHigherCheckNum(); }
    catch (SQLiteException sqle) { checkNum = 0; }
    checkNumText.setText("" + checkNum);
    payeeText.setText("");
    amountText.setText("");
    memoText.setText("");
    enterButton.setText(R.string.enterButtonDefault);
    setDateFieldCurrentDate();
    showCurrentBalance();
  }

  private void saveCheckInput() {
    int checkNum = 0;
    try {
      checkNum = Integer.parseInt(checkNumText.getText().toString());
    }
    catch (NumberFormatException nfe) {
      Log.e("saveCheckInput()", "Error parsing checkNum ["
          + checkNumText.getText().toString() + "]: " + nfe);
    }
    String date = dateText.getText().toString();
    String payee = payeeText.getText().toString();
    float amount = 0;
    try {
      amount = Float.parseFloat(amountText.getText().toString());
    }
    catch (NumberFormatException nfe) {
      Log.e("saveCheckInput()", "Error parsing amount ["
          + amountText.getText().toString() + "]: " + nfe);
    }
    String memo = memoText.getText().toString();
    saveCheckToFile(checkNum, date, payee, amount, memo);
    dba.addCheck(checkNum, date, payee, amount, memo, "");
    setPayeeList();
    clear_form();
  }

  private void showCurrentBalance() {
    // float data = currentBalanceFromFile();
    float data = dba.currentBalanceFromDb();
    TextView balanceView = (TextView) findViewById(R.id.balanceView);
    balanceView.setText("$" + data);
  }

  private void saveCheckToFile(Integer checkNum, String date, String payee,
      Float amount, String memo) {
    float balance = currentBalanceFromFile() - amount;
    try {
      FileOutputStream fos = openFileOutput(datafile, MODE_PRIVATE
          | MODE_APPEND);
      OutputStreamWriter os = new OutputStreamWriter(fos);
      os.write(checkNum + "|" + date + "|" + payee + "|" + amount + "|"
          + balance + "|" + memo + "\n");
      os.flush();
      os.close();
    }
    catch (IOException e) {
      Log.d(getPackageName(), "Error opening " + datafile + " for append", e);
    }
  }

  private float currentBalanceFromFile() {
    float balance = 0f;
    String line;
    String prevLine = "";
    try {
      BufferedReader in = new BufferedReader(new InputStreamReader(
          new DataInputStream(openFileInput(datafile))));
      while ((line = in.readLine()) != null) {
        prevLine = line;
      } // no more lines
      in.close();
      if (prevLine.length() > 0) {
        String[] c = prevLine.split("\\|");
        if (c.length > 0) {
          try {
            balance = Float.valueOf(c[4]);
          }
          catch (NumberFormatException nfe) {
            Log.e("currentBalanceFromFile()", "Error parsing balance [" + c[4]
                + "]: " + nfe);
          }
        }
      }
    }
    catch (IOException e) {
      Log.d(getPackageName(), "Error opening " + datafile + " for read", e);
    }
    return balance;
  }

  private void setPayeeList() {
    String[] payee = dba.getPayeeList();
    ArrayAdapter<String> aa = new ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1, payee);
    payeeText.setAdapter(aa);
  }
  
  @Override
  protected void onDestroy() {
    super.onDestroy();
    dba.close();
  }

}