package com.hyperling.apps.the45minuterule;

import android.app.Dialog;
import android.app.TimePickerDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity {

    // Primitive
    boolean debug, alarmSet, adsEnabled;
    int alarmHour, alarmMinute, currentHour, currentMinute;
    final int TIME_PICKER_DIALOG = 0;
    String TAG;

    // Java
    Timer timer;
    TimerTask timerTask;

    // Android
    Resources recs;

    // Shared Preferences
    private SharedPreferences sharedPreferences;
    private String keySharedPreferences, keyAdsEnabled;

    // Views
    Button btnTime;
    RadioGroup radioGroup;
    RadioButton rb1, rb2, rb3;
    TextView digitalClockHeader;
    TableLayout layClocks;
    ArrayList<TextView> clocks;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ////////////////////////////////////////////////////////////////////////////////////////////
        // Set up variables
        recs = getResources();

        debug = recs.getString(R.string.debug).toLowerCase().equals("true");

        alarmSet = false;

        updateCurrentTime();

        alarmHour = currentHour;
        alarmMinute = currentMinute;

        // Strings
        TAG = recs.getString(R.string.TAG);
        keySharedPreferences = recs.getString(R.string.keySharedPreferences);
        keyAdsEnabled = recs.getString(R.string.keyAdsEnabled);

        // Shared Preferences
        sharedPreferences = getSharedPreferences(keySharedPreferences, MODE_PRIVATE);

        adsEnabled = sharedPreferences.getBoolean(keyAdsEnabled, false);
        ////////////////////////////////////////////////////////////////////////////////////////////


        ////////////////////////////////////////////////////////////////////////////////////////////
        // Get the Views
        btnTime = (Button) findViewById(R.id.btnTime);

        radioGroup = (RadioGroup) findViewById(R.id.rgTired);

        rb1 = (RadioButton) findViewById(R.id.rb1);
        rb2 = (RadioButton) findViewById(R.id.rb2);
        rb3 = (RadioButton) findViewById(R.id.rb3);

        digitalClockHeader = (TextView) findViewById(R.id.tvDigitalClocksHeader);

        layClocks = (TableLayout) findViewById(R.id.layClocks);
        ////////////////////////////////////////////////////////////////////////////////////////////


        ////////////////////////////////////////////////////////////////////////////////////////////
        // Start manipulating stuff!
        btnTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Check if the time is already being shown
                showDialog(TIME_PICKER_DIALOG);
            }
        });

        rb2.setChecked(true);

        radioGroup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (debug) System.out.println("Radio group was clicked");
                startCheckTime(false);
            }
        });

        rb1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (debug) System.out.println("Radio 1 was clicked");
                startCheckTime(false);
            }
        });

        rb2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (debug) System.out.println("Radio 2 was clicked");
                startCheckTime(false);
            }
        });

        rb3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (debug) System.out.println("Radio 3 was clicked");
                startCheckTime(false);
            }
        });
        ////////////////////////////////////////////////////////////////////////////////////////////

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        if (id == R.id.action_tips) {
            startActivity(new Intent(MainActivity.this, Tips.class));
            return false;
        }

        if (id == R.id.action_settings) {
            Toast.makeText(this, "I can't do that, Jim", Toast.LENGTH_SHORT).show();
            return false;
        }

        if (id == R.id.action_about) {
            Toast.makeText(this, "I can't do that, Jim", Toast.LENGTH_SHORT).show();
            return false;
        }

        if (id == R.id.action_help) {
            Toast.makeText(this, "I can't do that, Jim", Toast.LENGTH_SHORT).show();
            return false;
        }

        if (id == R.id.action_exit) {
            finish();
            return false;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected Dialog onCreateDialog(int id){

        switch(id){
            case TIME_PICKER_DIALOG:
                if (debug) System.out.println("Showing time picker");

                TimePickerDialog.OnTimeSetListener timeSetListener = new TimePickerDialog.OnTimeSetListener() {
                    @Override
                    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                        if (debug) System.out.println("Time chosen is " + getTimeString(hourOfDay, minute));

                        alarmHour = hourOfDay;
                        alarmMinute = minute;

                        btnTime.setText(getTimeString(alarmHour, alarmMinute));
                        alarmSet = true;
                        startCheckTime(true);
                    }
                };

                TimePickerDialog timePickerDialog = new TimePickerDialog(this, timeSetListener, alarmHour, alarmMinute, DateFormat.is24HourFormat(getApplicationContext()));

                return timePickerDialog;
        }

        if (debug) System.out.println("Returning null, id was " + id);
        return null;
    }

    private void calculateTimes(){
        if (debug) System.out.println("Calculating times");
        if (alarmHour == currentHour && alarmMinute == currentMinute){
            if (debug) System.out.println("Alarm time not set");
            return;
        }
        else{
            ////////////////////////////////////////////////////////////////////////////////////////
            // Get how long we have until the alarm rings
            int hourDifference, minuteDifference, minutesUntilAlarm, sleepiness;

            hourDifference = alarmHour;
            minuteDifference = alarmMinute;

            if(alarmMinute < currentMinute){
                minuteDifference += 60;
                hourDifference -= 1;
            }

            if (alarmHour < currentHour){
                hourDifference += 24;
            }

            hourDifference -= currentHour;
            minuteDifference -= currentMinute;

            minutesUntilAlarm = (60*hourDifference) + minuteDifference;
            if (debug) System.out.println("Number of minutes until the alarm rings: " + minutesUntilAlarm);
            ////////////////////////////////////////////////////////////////////////////////////////


            ////////////////////////////////////////////////////////////////////////////////////////
            // Get sleepiness of the user
            switch(radioGroup.getCheckedRadioButtonId()){
                case R.id.rb1:
                    sleepiness = Integer.parseInt(recs.getString(R.string.rb_opt1_value));
                    break;
                case R.id.rb2:
                    sleepiness = Integer.parseInt(recs.getString(R.string.rb_opt2_value));
                    break;
                case R.id.rb3:
                    sleepiness = Integer.parseInt(recs.getString(R.string.rb_opt3_value));
                    break;
                default:
                    sleepiness = 0;
            }
            if (debug) System.out.println("Sleepiness is " + sleepiness);
            ////////////////////////////////////////////////////////////////////////////////////////


            ////////////////////////////////////////////////////////////////////////////////////////
            // Do math and set the clocks
            int bedHour, bedMinute, remainder;

            bedHour = currentHour;
            bedMinute = currentMinute;

            minutesUntilAlarm -= sleepiness;

            clocks = new ArrayList<TextView>();
            if ((minutesUntilAlarm) > 0){
                remainder = (minutesUntilAlarm%45);

                if (remainder < 0){
                    remainder += 45;
                }

                bedMinute += remainder;
                while (minutesUntilAlarm >= 45) {

                    if (bedMinute >= 60) {
                        bedMinute -= 60;
                        bedHour += 1;
                        if (bedHour >= 24) {
                            bedHour -= 24;
                        }
                    }

                    TextView newClock = new TextView(this);
                    newClock.setText(getTimeString(bedHour, bedMinute));

                    clocks.add(newClock);

                    minutesUntilAlarm -= 45;
                    bedMinute += 45;
                }
            }
            ////////////////////////////////////////////////////////////////////////////////////////


            ////////////////////////////////////////////////////////////////////////////////////////
            // Lay out the text views
            TableRow.LayoutParams params = new TableRow.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1);

            int loop = 0;
            TableRow newRow = new TableRow(this);

            layClocks.removeAllViews();

            if (clocks.size() > 0) {
                for (TextView clock : clocks) {
                    if (loop % 3 == 0) {
                        newRow = new TableRow(this);
                        layClocks.addView(newRow);
                    }

                    params.column = (loop % 3) + 1;

                    clock.setLayoutParams(params);
                    clock.setTextSize(18);
                    clock.setGravity(Gravity.CENTER);

                    newRow.addView(clock);

                    loop++;
                }

                while (loop % 3 != 0){
                    TextView blankClock = new TextView(this);

                    params.column = (loop % 3) + 1;

                    blankClock.setLayoutParams(params);
                    blankClock.setText(recs.getString(R.string.blank));
                    blankClock.setTextSize(18);
                    blankClock.setGravity(Gravity.CENTER);

                    newRow.addView(blankClock);

                    loop++;
                }

                // TODO: Remove temp string
                String temp = recs.getString(R.string.main_bedtimes_header) + ". Refreshed at " + getTimeString(currentHour, currentMinute);
                digitalClockHeader.setText(temp);
            }
            else{
                digitalClockHeader.setText(recs.getString(R.string.main_bedtimes_header_too_close));
            }
            ////////////////////////////////////////////////////////////////////////////////////////
        }

        return;
    }

    public void startCheckTime(boolean setTimer){
        if (debug) System.out.println("Checking time");

        updateCurrentTime();
        calculateTimes();

        if (setTimer) {
            timerTask = new TimerTask() {
                @Override
                public void run() {
                    startCheckTime(true);
                }
            };

            timer = new Timer();

            // TODO: Fix timer
            //timer.schedule(timerTask, 5000); // Recalculate time every 5 seconds
        }

        return;
    }

    private void updateCurrentTime(){
        Calendar now = Calendar.getInstance();

        currentHour = now.get(Calendar.HOUR_OF_DAY);
        currentMinute = now.get(Calendar.MINUTE);

        currentMinute = now.get(Calendar.MINUTE);
        currentHour = now.get(Calendar.HOUR_OF_DAY);
        if (debug) System.out.println("Current time is " + getTimeString(currentHour, currentMinute));
    }

    private String getTimeString(int hour, int minute){
        String time, hours, minutes, meridian;

        if (minute < 10){
            minutes = "0" + Integer.toString(minute);
        }
        else{
            minutes = Integer.toString(minute);
        }

        if (DateFormat.is24HourFormat(getApplicationContext())){
            hours = (hour < 10 ? "0"+Integer.toString(hour) : Integer.toString(hour));

            time = hours + ":" + minutes;
        }
        else {
            if (hour > 12){
                hour -= 12;
                meridian = "PM";
            }
            else{
                meridian = "AM";
            }

            hours = (hour == 0 ? "12" : Integer.toString(hour));

            time = hours + ":" + minutes  + meridian;
        }
        return time;
    }
}
