package oppen.filters.ui

/*

    Lätt - fast image filtering app for Android
    Copyright (C) 2020  Öppenlab

    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, see <https://www.gnu.org/licenses/>.

 */


import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.text.SpannableStringBuilder
import android.text.style.ImageSpan
import android.util.Log
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.preference.PreferenceManager
import com.bumptech.glide.Glide
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.levels.*
import kotlinx.android.synthetic.main.welcome_layout.*
import oppen.filters.*
import oppen.filters.io.ImageIO
import oppen.filters.ui.filter_picker.FilterPickerDialog
import oppen.filters.ui.views.FilterMenu
import oppen.filters.ui.views.OverflowMenu
import java.io.File


const val CHOOSE_IMAGE_REQUEST = 1000
const val CREATE_FILE_REQUEST = 1001

class FilterActivity : AppCompatActivity(), FilterView {

    private lateinit var presenter: FilterPresenter
    private var thumbnailUri: Uri? = null
    lateinit var levelsWindow: LevelsWindow

    private var showBrightnessWarning = true

    @SuppressLint("ApplySharedPref")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)

        setContentView(R.layout.activity_main)


        //Set default preferences - has no effect if user has subsequently modified anything
        PreferenceManager.setDefaultValues(this, R.xml.app_preferences, false)

        version_label.text = versionName()

        val cacheFile = File(dataDir, "cache_image.png")
        if(cacheFile.exists()) {
            Glide.with(this)
                .load(cacheFile)
                .into(last_export_image)
        }else{
            last_export_image.hide()
        }

        presenter = FilterPresenter(this, FilterRepository(this, ImageIO(this)))

        empty_layout.setOnClickListener {
            val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
            intent.addCategory(Intent.CATEGORY_OPENABLE)
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            intent.type = "image/*"
            startActivityForResult(intent, CHOOSE_IMAGE_REQUEST)
        }

        overflow_button.setOnClickListener {
            OverflowMenu.show(this, overflow_button, floating_slider_layout, supportFragmentManager)
        }

        new_image_button.setOnClickListener {
            preview_image.reset()
            empty_layout.performClick()//trigger open image intent
        }

        levelsWindow = LevelsWindow(floating_slider_layout){
            presenter.rebuild {
                runOnUiThread {
                    preview_image.setImageBitmap(it)
                }
            }
        }

        image_tone_button.setOnClickListener {
            when {
                levelsWindow.isVisible() -> levelsWindow.hide()
                else -> levelsWindow.show()
            }
        }
        image_tone_button.setOnLongClickListener {
            levelsWindow.view.hide()
            val isControlsFloating = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("isControlsFloating", true)
            PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean("isControlsFloating", !isControlsFloating).commit()
            levelsWindow.show()
            true
        }

        export_button.setOnClickListener {
            val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
            intent.addCategory(Intent.CATEGORY_OPENABLE)
            intent.type = "image/*"
            intent.putExtra(Intent.EXTRA_TITLE, presenter.getSuggestedFilename())
            startActivityForResult(intent, CREATE_FILE_REQUEST)
        }

        filter_category_button.setOnClickListener {
            if(floating_slider_layout.isVisible) floating_slider_layout.fadeOut(250L)
            FilterMenu.show(this, filter_category_button){ luts, isUserSavedFilters ->
                showLuts(luts, isUserSavedFilters)
            }
        }

        handleIntent(intent)
    }

    private fun showLuts(luts: List<Pair<String, Int>>, isUserSavedFilters: Boolean){
        require(thumbnailUri != null) { "Image thumbnail Uri is null - cannot show filter picker" }

        FilterPickerDialog(this, thumbnailUri!!, luts, isUserSavedFilters) { lut ->
            uiLog(lut.first)
            presenter.filterSelected(lut) { bitmap ->
                runOnUiThread {
                    preview_image.setImageBitmap(bitmap)
                }
            }
        }.show(supportFragmentManager, "tag_filter_chooser2")
    }

    //Handle user sharing image to this app while it's still running
    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        if(intent != null) handleIntent(intent)
    }

    private fun handleIntent(intent: Intent){
        if(intent.action == Intent.ACTION_SEND && intent.type != null &&  intent.type!!.startsWith("image/")){
            val uri = intent.getParcelableExtra(Intent.EXTRA_STREAM) as Uri
            loadImage(uri)
        }
    }

    private fun uiLog(message: String){
        ui_log.text = message
    }

    private fun loadImage(uri: Uri){
        loading_layout.show()
        preview_image.setImageURI(null)
        val cacheDeleted = cacheDir.deleteRecursively()//todo - this behaviour should be elsewhere, new image so delete cache directory
        Log.d("FilterActivity", "cacheDeleted: $cacheDeleted")
        presenter.chooseImageResult(uri, resources.displayMetrics.widthPixels)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if(resultCode == RESULT_OK && requestCode == CHOOSE_IMAGE_REQUEST){
            if(data?.data != null) loadImage(data.data!!)
        }else if(resultCode == RESULT_OK && requestCode == CREATE_FILE_REQUEST){
            if(data?.data != null) {
                loading_layout.show()
                presenter.exportImage(data.data!!)
            }
        }
    }

    override fun showImage(previewUri: Uri, thumbnailUri: Uri) = runOnUiThread {
        this.thumbnailUri = thumbnailUri
        empty_layout.hide()
        loading_layout.hide()
        filter_layout.show()
        preview_image.setImageURI(previewUri)

        val screenBrightness = Settings.System.getInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS,-1)
        if(screenBrightness < 255 && showBrightnessWarning) {
            showBrightnessWarning = false

            val builder = SpannableStringBuilder()
            builder.append("X  Check screen brightness level").append(" ")
            builder.setSpan(ImageSpan(this, R.drawable.vector_warning), 0, 1, 0)
            Snackbar.make(root, builder, Snackbar.LENGTH_SHORT).setAction("Open") {
                startActivity(Intent(Settings.ACTION_DISPLAY_SETTINGS).apply {
                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                })
            }.show()
        }
    }

    override fun imageExported(uri: Uri) = runOnUiThread{
        loading_layout.hide()
        val shareIntent: Intent = Intent().apply {
            action = Intent.ACTION_SEND
            putExtra(Intent.EXTRA_STREAM, uri)
            type = "image/png"
        }
        startActivity(Intent.createChooser(shareIntent, "Send to:"))
    }
}
