package com.kdanmobile.reader.view

import android.content.Context
import android.support.v4.content.ContextCompat
import android.support.v4.graphics.ColorUtils
import android.util.AttributeSet
import android.view.View
import android.widget.LinearLayout
import android.widget.SeekBar
import com.kdanmobile.reader.R
import com.kdanmobile.reader.annotationattribute.AnnotationAttribute
import com.kdanmobile.reader.annotationattribute.AnnotationColor
import com.kdanmobile.reader.annotationattribute.Brush
import com.kdanmobile.reader.annotationattribute.InkAttribute
import com.kdanmobile.reader.screen.view.ColorSelectView
import kotlinx.android.synthetic.main.view_reader_annotation_property.view.*

class AnnotationAttributeView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {

    companion object {
        const val DEFAULT_OPACITY = 50
        const val DEFAULT_THICKNESS = 5
    }


    init {
        inflate(context, R.layout.view_reader_annotation_property, this)
    }
    var inkAttribute: InkAttribute
        get() {
            return InkAttribute(color, alpha, thickness.toFloat(), brush)
        }
        set(value) {
            color = value.color
            alpha = value.alpha
            thickness = value.width.toInt()
            brush = value.brush
        }
    var annotationAttribute: AnnotationAttribute
        get() {
            return AnnotationAttribute(color, alpha)
        }
        set(value) {
            color = value.color
            alpha = value.alpha
        }
    var isSimpleMode = true
        set(value) {
            field = value
            update()
        }
    var onChangeListener: OnChangeListener? = null
    private var thickness: Int = DEFAULT_THICKNESS
        set(value) {
            field = value
            updateThickness()
        }
    /**
     * 1~255
     */
    private var alpha: Int
        get() {
            return Math.round(opacity.toFloat() / 100 * 255)
        }
        set(value) {
            val progress = Math.round(value.toFloat() / 255 * 100)
            seekBar_readerAnnotationProperty_opacity.progress = progress
        }
    /**
     * 1~100
     */
    private var opacity: Int = DEFAULT_OPACITY
    private var color: Int
        get() {
            return ContextCompat.getColor(context, colorEnum.colorResId)
        }
        set(value) {
            AnnotationColor.values().forEach {
                val c = ContextCompat.getColor(context, it.colorResId)
                if (c == value) {
                    colorEnum = it
                    return
                }
            }
        }
    private var colorEnum: AnnotationColor = AnnotationColor.Color1
        set(value) {
            if (field == value) return
            field = value
            updateColor()
            updateColorButtons()
            onChangeListener?.onChange(this)
        }
    private val colorWithAlpha: Int
        get() {
            return  ColorUtils.setAlphaComponent(color, alpha)
        }
    private var brush = Brush.Fountain
        set(value) {
            if (field == value) return
            field = value
            update()
            when (value) {
                Brush.Fountain -> if (thickness > brush.maxSize) thickness = brush.maxSize
                Brush.Marker -> thickness = brush.maxSize
            }
            onChangeListener?.onChange(this)
        }
    init {
        setupOpacitySeekBar()
        setupThicknessSeekBar()
        setupColorButtons()
        setupBrushes()
        update()
    }

    private fun setupBrushes() {
        iv_readerAnnotationProperty_brush1.setOnClickListener {
            brush = Brush.Fountain
        }
        iv_readerAnnotationProperty_brush2.setOnClickListener {
            brush = Brush.Marker
        }
    }

    private fun setupThicknessSeekBar() {
        seekBar_readerAnnotationProperty_thickness.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(p0: SeekBar?, progress: Int, p2: Boolean) {
                thickness = progress
                updateThickness()
            }

            override fun onStartTrackingTouch(p0: SeekBar?) {
            }

            override fun onStopTrackingTouch(p0: SeekBar?) {
                onChangeListener?.onChange(this@AnnotationAttributeView)
            }
        })
    }

    private fun setupColorButtons() {
        colorSelectView_readerAnnotationProperty.onColorSelectedListener = object : ColorSelectView.OnColorSelectedListener {
            override fun onColorSelected(color: Int) {
                AnnotationColor.values().forEach { annotationColor ->
                    val c = ContextCompat.getColor(context, annotationColor.colorResId)
                    if (c == color) {
                        colorEnum = annotationColor
                    }
                }
            }
        }
    }

    private fun setupOpacitySeekBar() {
        seekBar_readerAnnotationProperty_opacity.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            /** Hide display view now (1/5) **/
            /*
            val colorDisplayerView = ColorOpacityDisplayerView(context)
            val windowW = ViewGroup.LayoutParams.WRAP_CONTENT
            val windowH = ViewGroup.LayoutParams.WRAP_CONTENT
            val window = PopupWindow(colorDisplayerView, windowW, windowH).apply {
                animationStyle = android.R.style.Animation
            }
            val contentView = window.contentView.apply {
                val w = Utils.makeDropDownMeasureSpec(window.width)
                val h = Utils.makeDropDownMeasureSpec(window.height)
                measure(w, h)
            }
            */

            override fun onProgressChanged(seekBar: SeekBar, progress: Int, p2: Boolean) {
                opacity = progress
                updateOpacity()
                /** Hide display view now (2/5) **/
                /*
                val x = calculateOffsetX(seekBar)
                val y = calculateOffsetY(seekBar)
                window.update(seekBar, x, y, window.width, window.height)
                colorDisplayerView.color = colorWithAlpha
                */
            }

            override fun onStartTrackingTouch(seekBar: SeekBar) {
                /** Hide display view now (3/5) **/
                /*
                val x = calculateOffsetX(seekBar)
                val y = calculateOffsetY(seekBar)
                colorDisplayerView.color = colorWithAlpha
                window.showAsDropDown(seekBar, x, y)
                */
            }

            override fun onStopTrackingTouch(p0: SeekBar?) {
                /** Hide display view now (4/5) **/
                /*
                window.dismiss()
                */
                onChangeListener?.onChange(this@AnnotationAttributeView)
            }

            /** Hide display view now (5/5) **/
            /*
            private fun calculateOffsetX(seekBar: SeekBar): Int {
                val seekBarLineWidth = seekBar.width - seekBar.paddingLeft - seekBar.paddingRight
                val progress = seekBar.progress.toFloat() / seekBar.max.toFloat()
                return (seekBar.paddingLeft + seekBarLineWidth * progress - contentView.measuredWidth / 2).toInt()
            }

            private fun calculateOffsetY(seekBar: SeekBar): Int {
                return -seekBar.height - contentView.measuredHeight
            }
            */
        })
    }

    private fun update() {
        updateOpacity()
        updateThickness()
        updateColor()
        updateColorButtons()
        group_readerAnnotationProperty_brushMode.visibility = if (isSimpleMode) View.GONE else View.VISIBLE
        group_readerAnnotationProperty_brushMode.post {
            when (brush) {
                Brush.Fountain -> {
                    iv_readerAnnotationProperty_triangle1.visibility = View.VISIBLE
                    iv_readerAnnotationProperty_triangle2.visibility = View.INVISIBLE
                }
                Brush.Marker -> {
                    iv_readerAnnotationProperty_triangle1.visibility = View.INVISIBLE
                    iv_readerAnnotationProperty_triangle2.visibility = View.VISIBLE
                }
            }
        }
    }

    private fun updateOpacity() {
        seekBar_readerAnnotationProperty_opacity.progress = opacity
        tv_readerAnnotationProperty_opacityValue.text = opacity.toString()
        waveLineView_readerAnnotationProperty.setColor(colorWithAlpha)
    }

    private fun updateThickness() {
        when (brush) {
            Brush.Fountain -> {
                seekBar_readerAnnotationProperty_thickness.max = brush.maxSize
                seekBar_readerAnnotationProperty_thickness.isEnabled = true
            }
            Brush.Marker -> {
                seekBar_readerAnnotationProperty_thickness.max = brush.maxSize
                seekBar_readerAnnotationProperty_thickness.isEnabled = false
            }
        }
        seekBar_readerAnnotationProperty_thickness.progress = thickness
        tv_readerAnnotationProperty_thicknessValue.text = thickness.toString()
        waveLineView_readerAnnotationProperty.setThickness(thickness.toFloat())
    }

    private fun updateColor() {
        waveLineView_readerAnnotationProperty.setColor(colorWithAlpha)
    }

    private fun updateColorButtons() {
        val c = ContextCompat.getColor(context, colorEnum.colorResId)
        colorSelectView_readerAnnotationProperty.setSelectedColor(c)
    }

    interface OnChangeListener {
        fun onChange(annotationAttributeView: AnnotationAttributeView)
    }
}