package ca.yorku.cse.mack.tiltmaze;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

public class TiltMazeSetup extends Activity
{
    // keys for setup preferences
    final static String PARTICIPANT_CODE_KEY = "participant_code";
    final static String SESSION_CODE_KEY = "session_code";
    final static String GROUP_CODE_KEY = "group_code";
    final static String CONDITION_CODE_KEY = "condition_code";
    final static String TRIALS_CODE_KEY = "trials_code";
    final static String ORDER_OF_CONTROL_KEY = "orderOfControl";
    final static String GAIN_KEY = "gain";
    final static String GAIN_LABEL_KEY = "gain_label";
    final static String SHOW_NOMINAL_PATH_KEY = "show_nominal_path";
    final static String SHOW_MINIMUM_PATH_KEY = "show_minimum_path";
    final static String SHOW_WALL_HITS_KEY = "show_wall_hits";
    final static String SOUND_ALARM_ON_WALL_HIT_KEY = "sound_alarm_on_wall_hit";

    // somewhat arbitrary mappings for gain by order of control
    final static int[] GAIN_ARG_POSITION_CONTROL = {20, 5, 10, 20, 40, 80};
    final static int[] GAIN_ARG_VELOCITY_CONTROL = {100, 25, 50, 100, 200, 400};

    // setup parameters (1st entry is overwritten from values saved in shared preferences, if any)
    String[] participantCode = {"P01", "P01", "P02", "P03", "P04", "P05", "P06", "P07",
            "P08", "P09", "P10", "P11", "P12", "P13", "P14", "P15", "P16"};
    String[] sessionCode = {"S01", "S01", "S02", "S03", "S04", "S05"};    // T for trials and S for sessions
    String[] blockCode = {"(auto)"}; // effectively disable spinner for block code
    String[] groupCode = {"G01", "G01", "G02", "G03", "G04"};    // Determines which Order of Control participant
    // completed first
    String[] trialsCode = {"5", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "15", "20", "25"};
    String[] order_of_control = {"Velocity", "Velocity", "Position"};
    String[] gain = {"Medium", "Very low", "Low", "Medium", "High", "Very high"};
    String conditionCode = "C01";
    boolean showNominalPath = false;
    boolean showMinimumPath = false;
    boolean showWallHits = false;
    boolean soundAlarmOnWallHit = false;

    // save settings
    SharedPreferences sp;
    SharedPreferences.Editor spe;
    Button ok, save, exit;

    // spinners, checkbox, and edit text UI components
    private Spinner spinParticipant, spinSession, spinGroup, spinTrials, spinOrderOfControl, spinGain;
    private CheckBox checkShowNominalPath, checkShowMinimumPath, checkShowWallHits, checkSoundAlarmOnWallHit;
    private EditText editConditionCode;

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

        sp = this.getPreferences(MODE_PRIVATE);
        participantCode[0] = sp.getString(PARTICIPANT_CODE_KEY, participantCode[0]);
        sessionCode[0] = sp.getString(SESSION_CODE_KEY, sessionCode[0]);
        // block code initialised in main activity (based on existing filenames)
        groupCode[0] = sp.getString(GROUP_CODE_KEY, groupCode[0]);
        conditionCode = sp.getString(CONDITION_CODE_KEY, conditionCode);
        trialsCode[0] = sp.getString(TRIALS_CODE_KEY, trialsCode[0]);
        order_of_control[0] = sp.getString(ORDER_OF_CONTROL_KEY, order_of_control[0]);
        gain[0] = sp.getString(GAIN_KEY, gain[0]);
        showNominalPath = sp.getBoolean(SHOW_NOMINAL_PATH_KEY, showNominalPath);
        showMinimumPath = sp.getBoolean(SHOW_MINIMUM_PATH_KEY, showMinimumPath);
        showWallHits = sp.getBoolean(SHOW_WALL_HITS_KEY, showWallHits);
        soundAlarmOnWallHit = sp.getBoolean(SOUND_ALARM_ON_WALL_HIT_KEY, soundAlarmOnWallHit);

        // get references to widget elements
        spinParticipant = (Spinner)findViewById(R.id.paramPart);
        spinSession = (Spinner)findViewById(R.id.paramSess);
        Spinner spinBlock = (Spinner)findViewById(R.id.paramBlock);
        spinGroup = (Spinner)findViewById(R.id.paramGroup);
        editConditionCode = (EditText)findViewById(R.id.conditionCode);
        spinTrials = (Spinner)findViewById(R.id.paramTrials);
        spinOrderOfControl = (Spinner)findViewById(R.id.paramOrderOfControl);
        spinGain = (Spinner)findViewById(R.id.paramGain);
        checkShowNominalPath = (CheckBox)findViewById(R.id.paramShowNominalPath);
        checkShowMinimumPath = (CheckBox)findViewById(R.id.paramShowMinimumPath);
        checkShowWallHits = (CheckBox)findViewById(R.id.paramShowWallHits);
        checkSoundAlarmOnWallHit = (CheckBox)findViewById(R.id.paramSoundAlarmOnWallHit);

        // get references to OK, SAVE, and EXIT buttons
        ok = (Button)findViewById(R.id.ok);
        save = (Button)findViewById(R.id.save);
        exit = (Button)findViewById(R.id.exit);

        // initialise spinner adapters
        ArrayAdapter<CharSequence> adapterPC = new ArrayAdapter<CharSequence>(this, R.layout.spinnerstyle,
                participantCode);
        spinParticipant.setAdapter(adapterPC);

        ArrayAdapter<CharSequence> adapterSS = new ArrayAdapter<CharSequence>(this, R.layout.spinnerstyle, sessionCode);
        spinSession.setAdapter(adapterSS);

        ArrayAdapter<CharSequence> adapterB = new ArrayAdapter<CharSequence>(this, R.layout.spinnerstyle, blockCode);
        spinBlock.setAdapter(adapterB);

        ArrayAdapter<CharSequence> adapterG = new ArrayAdapter<CharSequence>(this, R.layout.spinnerstyle, groupCode);
        spinGroup.setAdapter(adapterG);

        ArrayAdapter<CharSequence> adapterT = new ArrayAdapter<CharSequence>(this, R.layout.spinnerstyle, trialsCode);
        spinTrials.setAdapter(adapterT);

        ArrayAdapter<CharSequence> adapter2 = new ArrayAdapter<CharSequence>(this, R.layout.spinnerstyle,
                order_of_control);
        spinOrderOfControl.setAdapter(adapter2);

        ArrayAdapter<CharSequence> adapterGN = new ArrayAdapter<CharSequence>(this, R.layout.spinnerstyle, gain);
        spinGain.setAdapter(adapterGN);

        // initialize EditText setup items
        editConditionCode.setText(conditionCode);

        // initialize checkbox
        checkShowNominalPath.setChecked(showNominalPath);
        checkShowMinimumPath.setChecked(showMinimumPath);
        checkShowWallHits.setChecked(showWallHits);
        checkSoundAlarmOnWallHit.setChecked(soundAlarmOnWallHit);

        // prevent soft keyboard from popping up when activity launches
        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    }

    // called when the "OK", "Save", or "Exit" button is pressed
    public void onClick(View view)
    {
        if (view == ok)
        {
            // get user's choices...
            String part = participantCode[spinParticipant.getSelectedItemPosition()];
            String sess = sessionCode[spinSession.getSelectedItemPosition()];
            // block handled differently (auto generated from existing filenames)
            String group = groupCode[spinGroup.getSelectedItemPosition()];
            String cond = editConditionCode.getText().toString();
            int numberOfTrials = Integer.parseInt(trialsCode[spinTrials.getSelectedItemPosition()]);
            String orderOfControl = (String)spinOrderOfControl.getSelectedItem();
            boolean showNominalPath = checkShowNominalPath.isChecked();
            boolean showMinimumPath = checkShowMinimumPath.isChecked();
            boolean showWallHits = checkShowWallHits.isChecked();
            boolean soundAlarmOnWallHit = checkSoundAlarmOnWallHit.isChecked();

            // actual gain value depends on order of control
            int gain;
            if (orderOfControl.equals("Velocity"))
                gain = GAIN_ARG_VELOCITY_CONTROL[spinGain.getSelectedItemPosition()];
            else
                gain = GAIN_ARG_POSITION_CONTROL[spinGain.getSelectedItemPosition()];

            String gainLabel = (String)spinGain.getSelectedItem();

            // bundle up parameters to pass on to activity
            Bundle b = new Bundle();
            b.putString(PARTICIPANT_CODE_KEY, part);
            b.putString(SESSION_CODE_KEY, sess);
            b.putString(GROUP_CODE_KEY, group);
            b.putString(CONDITION_CODE_KEY, cond);
            b.putInt(TRIALS_CODE_KEY, numberOfTrials);
            b.putString(ORDER_OF_CONTROL_KEY, orderOfControl);
            b.putInt(GAIN_KEY, gain);
            b.putString(GAIN_LABEL_KEY, gainLabel);
            b.putBoolean(SHOW_NOMINAL_PATH_KEY, showNominalPath);
            b.putBoolean(SHOW_MINIMUM_PATH_KEY, showMinimumPath);
            b.putBoolean(SHOW_WALL_HITS_KEY, showWallHits);
            b.putBoolean(SOUND_ALARM_ON_WALL_HIT_KEY, soundAlarmOnWallHit);

            // start experiment activity
            Intent i = new Intent(getApplicationContext(), TiltMazeActivity.class);
            i.putExtras(b);
            startActivity(i);
            finish();

        } else if (view == save)
        {
            // save the user's choices
            spe = sp.edit();
            spe.putString(PARTICIPANT_CODE_KEY, participantCode[spinParticipant.getSelectedItemPosition()]);
            spe.putString(SESSION_CODE_KEY, sessionCode[spinSession.getSelectedItemPosition()]);
            spe.putString(GROUP_CODE_KEY, groupCode[spinGroup.getSelectedItemPosition()]);
            spe.putString(CONDITION_CODE_KEY, editConditionCode.getText().toString());
            spe.putString(TRIALS_CODE_KEY, trialsCode[spinTrials.getSelectedItemPosition()]);
            spe.putString(ORDER_OF_CONTROL_KEY, order_of_control[spinOrderOfControl.getSelectedItemPosition()]);
            spe.putString(GAIN_KEY, gain[spinGain.getSelectedItemPosition()]);
            spe.putBoolean(SHOW_NOMINAL_PATH_KEY, checkShowNominalPath.isChecked());
            spe.putBoolean(SHOW_MINIMUM_PATH_KEY, checkShowMinimumPath.isChecked());
            spe.putBoolean(SHOW_WALL_HITS_KEY, checkShowWallHits.isChecked());
            spe.putBoolean(SOUND_ALARM_ON_WALL_HIT_KEY, checkSoundAlarmOnWallHit.isChecked());
            spe.apply();
            Toast.makeText(this, "Preferences saved!", Toast.LENGTH_SHORT).show();

        } else if (view == exit)
        {
            this.finish(); // terminate
        }
    }
}
