/**
 * ProjectLaogai
 *
 * Copyright 2019  <seil0@mosad.xyz>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 *
 */

package org.mosad.seil0.projectlaogai.fragments

import android.content.Context
import android.os.Bundle
import android.renderscript.Sampler
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.Switch
import androidx.fragment.app.Fragment
import com.afollestad.aesthetic.Aesthetic
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.color.colorChooser
import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.list.listItems
import com.afollestad.materialdialogs.list.listItemsSingleChoice
import de.psdev.licensesdialog.LicensesDialog
import kotlinx.android.synthetic.main.fragment_settings.*
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread
import org.mosad.seil0.projectlaogai.BuildConfig
import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.controller.CacheController
import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.coursesList
import org.mosad.seil0.projectlaogai.controller.PreferencesController
import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cColorAccent
import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cColorPrimary
import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cCourse
import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cShowBuffet
import org.mosad.seil0.projectlaogai.controller.TCoRAPIController
import org.mosad.seil0.projectlaogai.hsoparser.DataTypes
import java.util.*


/**
 * The settings controller class
 * contains all needed parts to display and the settings screen
 */
class SettingsFragment : Fragment() {

    private lateinit var linLayoutUser: LinearLayout
    private lateinit var linLayoutCourse: LinearLayout
    private lateinit var linLayoutAbout: LinearLayout
    private lateinit var linLayoutLicence: LinearLayout
    private lateinit var linLayoutTheme: LinearLayout
    private lateinit var linLayoutPrimaryColor: LinearLayout
    private lateinit var linLayoutAccentColor: LinearLayout
    private lateinit var switchBuffet: Switch

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        val view: View = inflater.inflate(R.layout.fragment_settings, container, false)

        linLayoutUser = view.findViewById(R.id.linLayout_User)
        linLayoutCourse = view.findViewById(R.id.linLayout_Course)
        linLayoutAbout = view.findViewById(R.id.linLayout_About)
        linLayoutLicence = view.findViewById(R.id.linLayout_Licence)
        linLayoutTheme = view.findViewById(R.id.linLayout_Theme)
        linLayoutPrimaryColor = view.findViewById(R.id.linLayout_PrimaryColor)
        linLayoutAccentColor = view.findViewById(R.id.linLayout_AccentColor)
        switchBuffet = view.findViewById(R.id.switch_buffet)

        initActions()

        // Inflate the layout for this fragment
        return view
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // initialize the settings gui
        txtView_Course.text = cCourse.courseName
        txtView_AboutDesc.text =  resources.getString(R.string.about_version, BuildConfig.VERSION_NAME, getString(R.string.build_time))
        switch_buffet.isChecked = cShowBuffet // init switch

        val outValue = TypedValue()
        activity!!.theme.resolveAttribute(R.attr.themeName, outValue, true)
        when(outValue.string) {
            "light" -> {
                switch_buffet.setTextColor(activity!!.resources.getColor(R.color.textPrimaryLight, activity!!.theme))
                txtView_SelectedTheme.text = resources.getString(R.string.themeLight)
            }
            "dark" -> {
                switch_buffet.setTextColor(activity!!.resources.getColor(R.color.textPrimaryDark, activity!!.theme))
                txtView_SelectedTheme.text = resources.getString(R.string.themeDark)
            }
            "black" -> {
                switch_buffet.setTextColor(activity!!.resources.getColor(R.color.textPrimaryDark, activity!!.theme))
                txtView_SelectedTheme.text = resources.getString(R.string.themeBlack)
            }
        }

    }

    /**
     * initialize some actions for SettingsFragment elements
     */
    private fun initActions() {
        linLayoutUser.setOnClickListener {
            // open a new dialog
        }

        linLayoutUser.setOnLongClickListener {
            PreferencesController.oGiants = true // enable easter egg
            return@setOnLongClickListener true
        }

        linLayoutCourse.setOnClickListener {
            selectCourse(context!!)
            txtView_Course.text = cCourse.courseName // update txtView
        }

        linLayoutAbout.setOnClickListener {
            // open a new info dialog
            MaterialDialog(context!!)
                .title(R.string.about_dialog_heading)
                .message(R.string.about_dialog_text)
                .show()
        }

        linLayoutLicence.setOnClickListener {
            // do the theme magic, as the lib's theme support is broken
            val outValue = TypedValue()
            context!!.theme.resolveAttribute(R.attr.themeName, outValue, true)

            val dialogCss = when (outValue.string) {
                "light" -> R.string.license_dialog_style_light
                else -> R.string.license_dialog_style_dark
            }

            val themeId = when (outValue.string) {
                "light" -> R.style.AppTheme_Light
                else -> R.style.LicensesDialogTheme_Dark
            }

            // open a new license dialog
            LicensesDialog.Builder(context!!)
                .setNotices(R.raw.notices)
                .setTitle(R.string.licenses)
                .setIncludeOwnLicense(true)
                .setThemeResourceId(themeId)
                .setNoticesCssStyle(dialogCss)
                .build()
                .show()
        }

        linLayoutTheme.setOnClickListener {
            val themes = listOf(
                resources.getString(R.string.themeLight),
                resources.getString(R.string.themeDark),
                resources.getString(R.string.themeBlack)
            )
            MaterialDialog(context!!).show {
                listItemsSingleChoice(items = themes) { _, index, _ ->
                    Aesthetic.config {
                        when (index) {
                            0 -> activityTheme(R.style.AppTheme_Light)
                            1 -> activityTheme(R.style.AppTheme_Dark)
                            2 -> activityTheme(R.style.AppTheme_Black)
                            else -> activityTheme(R.style.AppTheme_Light)
                        }
                    }
                }
            }
        }

        linLayoutPrimaryColor.setOnClickListener {
            // open a new color chooser dialog
            MaterialDialog(context!!)
                .title(R.string.primary_color)
                .colorChooser(DataTypes().primaryColors, allowCustomArgb = true, initialSelection = cColorPrimary) { _, color ->
                    view_PrimaryColor.setBackgroundColor(color)
                    Aesthetic.config {
                        colorPrimary(color)
                        colorPrimaryDark(color)
                        apply()
                    }

                    cColorPrimary = color
                    PreferencesController.save(context!!)
                }
                .positiveButton(R.string.select)
                .show()
        }

        linLayoutAccentColor.setOnClickListener {
            // open a new color chooser dialog
            MaterialDialog(context!!)
                .title(R.string.accent_color)
                .colorChooser(DataTypes().accentColors, allowCustomArgb = true, initialSelection = cColorAccent) { _, color ->
                    view_AccentColor.setBackgroundColor(color)
                    Aesthetic.config {
                        colorAccent(color)
                        apply()
                    }

                    cColorAccent = color
                    PreferencesController.save(context!!)
                }
                .positiveButton(R.string.select)
                .show()
        }

        switchBuffet.setOnClickListener {
            cShowBuffet = switchBuffet.isChecked
            PreferencesController.save(context!!)
            println(switchBuffet.isChecked)
        }

    }

    fun selectCourse(context: Context) {
        val courseNameList = ArrayList<String>()
        coursesList.forEach { (_, courseName) ->
            courseNameList.add(courseName)
        }

        // open a new dialog
        MaterialDialog(context)
            .title(R.string.select_course)
            .listItems(items = courseNameList) { _, index, _ ->

                val dialog = MaterialDialog(context).cancelable(false)
                    .cancelOnTouchOutside(false)
                    .customView(R.layout.dialog_loading)
                dialog.show()

                doAsync {
                    cCourse = coursesList[index] // set the course
                    PreferencesController.save(context)

                    // update current & next weeks timetable
                    TCoRAPIController.getTimetable(cCourse.courseName, 0, context).get() // blocking since we want the new data
                    TCoRAPIController.getTimetable(cCourse.courseName, 1, context).get() // blocking since we want the new data

                    CacheController.readTimetable(cCourse.courseName, 0, context)
                    CacheController.readTimetable(cCourse.courseName, 1, context)

                    uiThread {
                        dialog.dismiss()
                    }
                }

            }
            .show()
    }

}
