package com.example.fueltrack;

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.app.Fragment;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class FuelTrackActivity extends Activity {
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_fuel_track);
    getFragmentManager().beginTransaction()
        .replace(android.R.id.content, new FuelTrackFragment()).commit();

  }

  public static class FuelTrackFragment extends Fragment {
    private EditText dateText;
    private EditText distanceText;
    private EditText fuelText;
    private EditText costText;
    private Button enterButton;
    public static final String datafile = "mileagedata.txt";
    private SharedPreferences.OnSharedPreferenceChangeListener prefListener;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setHasOptionsMenu(true);

      // Get references to input fields
      dateText = (EditText) getActivity().findViewById(R.id.dateText);
      distanceText = (EditText) getActivity().findViewById(R.id.distanceText);
      fuelText = (EditText) getActivity().findViewById(R.id.fuelText);
      costText = (EditText) getActivity().findViewById(R.id.costText);

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

      clear_form();

      // Handle Save button to add new mileage record
      enterButton = (Button) getActivity().findViewById(R.id.enterButton);
      enterButton.setOnClickListener(new Button.OnClickListener() {
        @Override
        public void onClick(View v) {
          // save data to persistent storage
          saveMileageInput();
          // calculate & display mpg
        }
      });

    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
      super.onCreateOptionsMenu(menu, inflater);
      MenuItem prefItem = menu.add(0, 0, 0, "Preferences");
      prefItem.setIcon(android.R.drawable.ic_menu_preferences);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
      int itemid = item.getItemId();
      switch (itemid) {
        case 0:
          startActivity(new Intent("com.example.fueltrack.PREFERENCES"));
        case 1:
          // Show history list
      }
      return true;
    }

    public void setLabelsFromPreferences(SharedPreferences prefs) {
      TextView distanceLabel = (TextView) getActivity().findViewById(
          R.id.distanceLabel);
      TextView fuelLabel = (TextView) getActivity()
          .findViewById(R.id.fuelLabel);
      distanceLabel.setText(prefs.getString("distance_unit", "Distance"));
      fuelLabel.setText(prefs.getString("fuel_unit", "Fuel"));
    }

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

    private void clear_form() {
      distanceText.setText("");
      fuelText.setText("");
      costText.setText("");
      setDateFieldCurrentDate();
      showCurrentMileage();
    }

    private void saveMileageInput() {
      String dunit = PreferenceManager.getDefaultSharedPreferences(
          getActivity()).getString("distance_unit", "Kilometers");
      String funit = PreferenceManager.getDefaultSharedPreferences(
          getActivity()).getString("fuel_unit", "Liters");
      String date = dateText.getText().toString();
      Float distance = Float.valueOf(distanceText.getText().toString());
      Float fuel = Float.valueOf(fuelText.getText().toString());
      Float cost = Float.valueOf(costText.getText().toString());
      String testMessage = "Date: " + date + "; Distance: " + distance
          + "; Fuel: " + fuel + "; Cost: " + cost + "; $/G: " + cost / fuel;
      Toast toast = Toast.makeText(getActivity(), testMessage,
          Toast.LENGTH_LONG);
      toast.show();
      if (dunit.equals("Miles")) { // convert to kilometers for storage
        distance = milesToKm(distance);
      }
      if (funit.equals("Gallons")) { // convert to liters for storage
        fuel = gallonsToLiters(fuel);
      }
      saveMileageToFile(date, distance, fuel, cost);
      clear_form();
    }

    private void showCurrentMileage() {
      float[] data = mostRecentMileageFromFile();
      float kpl = 0f, mpg = 0f;
      if (data[1] != 0) {
        kpl = data[0] / data[1];
        mpg = kmToMiles(data[0]) / litersToGallons(data[1]);
      }
      TextView mpgView = (TextView) getActivity().findViewById(R.id.mpgView);
      mpgView.setText(mpg + " MPG (" + kpl + " KPL)");
    }

    private void saveMileageToFile(String date, Float distance, Float fuel,
        Float cost) {
      try {
        FileOutputStream fos = getActivity().openFileOutput(datafile,
            MODE_PRIVATE | MODE_APPEND);
        OutputStreamWriter os = new OutputStreamWriter(fos);
        os.write(date + "," + distance + "," + fuel + "," + cost + "\n");
        os.flush();
        os.close();
      }
      catch (IOException e) {
        Log.d(getActivity().getPackageName(),
            "Error opening mileagedata.txt for append", e);
      }
    }

    private float[] mostRecentMileageFromFile() {
      float distance = 0f;
      float fuel = 0f;
      String line;
      String curLine = "", prevLine = "";
      try {
        BufferedReader in = new BufferedReader(new InputStreamReader(
            new DataInputStream(getActivity().openFileInput(datafile))));
        while ((line = in.readLine()) != null) {
          prevLine = curLine;
          curLine = line;
        } // no more lines
        in.close();
        if (prevLine.length() > 0) {
          String[] p = prevLine.split(",");
          String[] c = curLine.split(",");
          if (p.length > 0 && c.length > 0) {
            distance = Float.valueOf(c[1]) - Float.valueOf(p[1]);
            fuel = Float.valueOf(c[2]);
          }
        }
      }
      catch (IOException e) {
        Log.d(getActivity().getPackageName(),
            "Error opening mileagedata.txt for read", e);
      }
      return new float[] {
          distance, fuel
      };
    }

    private float kmToMiles(float distance) {
      return distance * 0.621371192f;
    }

    private float milesToKm(float distance) {
      return distance * 1.609344f;
    }

    private float litersToGallons(float volume) {
      return volume * 0.264172037f;
    }

    private float gallonsToLiters(float volume) {
      return volume * 3.785412f;
    }
  }
}