package ch.spherIC;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;
import ch.spherIC.components.ApertureSpinner;
import ch.spherIC.components.ShutterSpeedSpinner;
import ch.spherIC.components.XSpinner;
import ch.spherIC.resultlist.Exposure;
import ch.spherIC.resultlist.ExposureAdapter;
import ch.spherIC.resultlist.ExposureFactory;
import ch.spherIC.settings.SettingsDlg;


/**
 * Main class EasyBracketing
 */
public class EasyBracketMain extends Activity {

    public static final int ABOUT_DLG = 0;
    public static final int SETTINGS_DLG = 1;
    public static final int USERGUIDE_DLG = 2;

    private static String DEF_SHUTTER_SPEED = "1/125";
    private static String DEF_APERTURE = "f/8";
    private static String DEF_EVSTEP = "2.0";

    private ShutterSpeedSpinner spnDPShutterSpeed;
    private ApertureSpinner spnDPAperture;
    private ShutterSpeedSpinner spnBPShutterSpeed;
    private ApertureSpinner spnBPAperture;
    private TextView txtDPEVValue;
    private TextView txtBPEVValue;
    private TextView txtCalcPDeltaEV;
    private ApertureSpinner spnCalcPAperture;
    private XSpinner spnCalcPEVStep;
    private Button resetBtn;
    private Button calculateBtn;
    private ListView resultList;
    private LinearLayout resultsHeader;

    private double bpCorrection;
    private double dpCorrection;
    private boolean fixBP;

    private double dpEV;
    private double bpEV;
    public static final DecimalFormat DF = new DecimalFormat("0.##");

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

        initComponents();
        setDefaults();
        loadSettings();
    }

    /**
     * Loads and stores the settings
     */
    public void loadSettings() {

        // Load settings
        SharedPreferences settings = getSharedPreferences(SettingsDlg.PREFS_NAME, Context.MODE_PRIVATE);

        this.fixBP = settings.getBoolean("fixBrightPoint", true);
        this.bpCorrection = settings.getFloat("brightPointCorrection", 0f);
        this.dpCorrection = settings.getFloat("darkPointCorrection", 0f);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);

        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.mainmenu, menu);
        return true;
    }

    /**
     * @see  android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        // Handle item selection
        switch (item.getItemId()) {

            case R.id.itemAbout:
                showDialog(ABOUT_DLG);
                return true;

            case R.id.itemSettings:
                showDialog(SETTINGS_DLG);
                return true;

            case R.id.itemUserGuide:
                showDialog(USERGUIDE_DLG);
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

    /**
     * Initialization method
     */
    private void initComponents() {

        // initialize dropdowns

        OnItemSelectedListener evRangeItemSelListener = new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                EasyBracketMain.this.dpEV = EVFormula.calcEV(EasyBracketMain.this.spnDPAperture.getSelectedAperture(),
                                                             EasyBracketMain.this.spnDPShutterSpeed
                                                             .getSelectedShutterSpeed());
                EasyBracketMain.this.bpEV = EVFormula.calcEV(EasyBracketMain.this.spnBPAperture.getSelectedAperture(),
                                                             EasyBracketMain.this.spnBPShutterSpeed
                                                             .getSelectedShutterSpeed());

                EasyBracketMain.this.txtDPEVValue.setText(EasyBracketMain.DF.format(EasyBracketMain.this.dpEV));
                EasyBracketMain.this.txtBPEVValue.setText(EasyBracketMain.DF.format(EasyBracketMain.this.bpEV));
                EasyBracketMain.this.txtCalcPDeltaEV.setText(EasyBracketMain.DF.format((EasyBracketMain.this.bpEV
                                                                                        + EasyBracketMain.this.bpCorrection)
                                                                                       - (EasyBracketMain.this.dpEV
                                                                                          - EasyBracketMain.this.dpCorrection)));
                EasyBracketMain.this.calculateBtn.setEnabled(EasyBracketMain.this.bpEV > EasyBracketMain.this.dpEV);

                EasyBracketMain.this.resultsHeader.setVisibility(View.INVISIBLE);
                findViewById(R.id.View_ResHeader_Understroke).setVisibility(View.INVISIBLE);
                EasyBracketMain.this.resultList.setAdapter(null);

                if (EasyBracketMain.this.bpEV < EasyBracketMain.this.dpEV) {
                    Toast toast = Toast.makeText(EasyBracketMain.this, R.string.toastWarningDP_BP, Toast.LENGTH_LONG);
                    toast.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0);
                    toast.show();
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        };

        OnItemSelectedListener calcPItemSelListener = new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                toggleResultsList(false);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        };

        this.spnDPShutterSpeed = (ShutterSpeedSpinner) findViewById(R.id.Spinner_DP_Shutter);
        this.spnDPAperture = (ApertureSpinner) findViewById(R.id.Spinner_DP_Aperture);
        this.spnBPShutterSpeed = (ShutterSpeedSpinner) findViewById(R.id.Spinner_BP_Shutter);
        this.spnBPAperture = (ApertureSpinner) findViewById(R.id.Spinner_BP_Aperture);
        this.spnCalcPAperture = (ApertureSpinner) findViewById(R.id.Spinner_calcP_Aperture);
        this.spnCalcPEVStep = (XSpinner) findViewById(R.id.Spinner_calcP_EVStep);

        this.txtDPEVValue = (TextView) findViewById(R.id.Text_EVVal_DP);
        this.txtBPEVValue = (TextView) findViewById(R.id.Text_EVVal_BP);
        this.txtCalcPDeltaEV = (TextView) findViewById(R.id.label_deltaEV_Val);
        this.resultsHeader = (LinearLayout) ExposureAdapter.getHeaderView(this,
                                                                          (LinearLayout)
                                                                          findViewById(R.id.LinearLayout_ResultsHeader));
        this.resultsHeader.setVisibility(View.INVISIBLE);
        findViewById(R.id.View_ResHeader_Understroke).setVisibility(View.INVISIBLE);
        this.resultList = (ListView) findViewById(R.id.ListView_ExpResults);
        this.resultList.setAdapter(null);

        this.resetBtn = (Button) findViewById(R.id.Btn_Reset);
        this.calculateBtn = (Button) findViewById(R.id.Btn_Calculate);

        this.calculateBtn.setEnabled(false);

        this.spnDPShutterSpeed.setOnItemSelectedListener(evRangeItemSelListener);
        this.spnDPAperture.setOnItemSelectedListener(evRangeItemSelListener);
        this.spnBPShutterSpeed.setOnItemSelectedListener(evRangeItemSelListener);
        this.spnBPAperture.setOnItemSelectedListener(evRangeItemSelListener);

        this.resetBtn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    setDefaults();
                    toggleResultsList(false);
                }
            });

        this.calculateBtn.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    toggleResultsList(true);
                    calculateExposures();
                }
            });

        this.spnCalcPAperture.setOnItemSelectedListener(calcPItemSelListener);
        this.spnCalcPEVStep.setOnItemSelectedListener(calcPItemSelListener);
    }

    /**
     * Clears the results list.
     */
    private void toggleResultsList(boolean visible) {
        if (visible) {
            EasyBracketMain.this.resultsHeader.setVisibility(View.VISIBLE);
            findViewById(R.id.View_ResHeader_Understroke).setVisibility(View.VISIBLE);
        } else {
            EasyBracketMain.this.resultsHeader.setVisibility(View.INVISIBLE);
            findViewById(R.id.View_ResHeader_Understroke).setVisibility(View.INVISIBLE);
            EasyBracketMain.this.resultList.setAdapter(null);
        }
    }

    /**
     * Sets the default values.
     */
    public void setDefaults() {
        this.spnDPShutterSpeed.setSelectionByVal(DEF_SHUTTER_SPEED);
        this.spnDPAperture.setSelectionByVal(DEF_APERTURE);
        this.spnBPShutterSpeed.setSelectionByVal(DEF_SHUTTER_SPEED);
        this.spnBPAperture.setSelectionByVal(DEF_APERTURE);
        this.spnCalcPAperture.setSelectionByVal(DEF_APERTURE);
        this.spnCalcPEVStep.setSelectionByVal(DEF_EVSTEP);

        this.txtDPEVValue.setText(DF.format(EVFormula.calcEV(this.spnDPAperture.getSelectedAperture(),
                                                             this.spnDPShutterSpeed.getSelectedShutterSpeed())));
        this.txtBPEVValue.setText(DF.format(EVFormula.calcEV(this.spnBPAperture.getSelectedAperture(),
                                                             this.spnBPShutterSpeed.getSelectedShutterSpeed())));
        this.txtCalcPDeltaEV.setText(DF.format(this.bpEV + this.bpCorrection - (this.dpEV - this.dpCorrection)));
    }

    /**
     * Initiates the calculation of the exposure values according to the input parameters.
     */
    private void calculateExposures() {

        List<Exposure> exposureList;
        double calcPrmAperture = this.spnCalcPAperture.getSelectedAperture();
        double calcPrmEvStep = Double.valueOf(this.spnCalcPEVStep.getSelectedItem().toString());
        List<Double> allowedShutters = getShutterSpeeds();

        exposureList = ExposureFactory.calculateExposures(this, this.dpEV - this.dpCorrection,
                                                          this.bpEV + this.bpCorrection, calcPrmAperture, calcPrmEvStep,
                                                          this.fixBP, allowedShutters);

        this.resultList.setAdapter(new ExposureAdapter(this, exposureList));

    }

    /**
     * Retrieves the list of all shutter speeds in drop down list as Double's.
     *
     * @return  list of all shutter speeds in drop down list as Double's
     */
    private List<Double> getShutterSpeeds() {

        List<Double> shutterSpeeds = new ArrayList<Double>();

        for (int i = 0; i < this.spnBPShutterSpeed.getCount(); i++) {
            shutterSpeeds.add(this.spnBPShutterSpeed.getShutterSpeedAt(i));
        }

        return shutterSpeeds;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected Dialog onCreateDialog(int id) {
        return DialogFactory.createDialog(id, this);
    }

}
