package com.example.tfat.myapplication

import android.app.Activity
import android.content.DialogInterface
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import android.os.Bundle
import android.graphics.drawable.Drawable
import android.support.v7.widget.RecyclerView
import android.view.*
import android.widget.PopupWindow
import com.bomostory.sceneeditmodule.Config
import com.bomostory.sceneeditmodule.MovieEditActivity
import com.example.tfat.myapplication.navigationbar.NavigationBarView
import com.example.tfat.myapplication.navigationbar.actor.ActorAdapter
import com.example.tfat.myapplication.navigationbar.scene.AddSceneAdapter
import com.example.tfat.myapplication.navigationbar.scene.AddSceneView
import com.example.tfat.myapplication.navigationbar.scene.ControlSceneView
import com.example.tfat.myapplication.navigationbar.scene.SceneAdapter
import com.bomostory.sceneeditmodule.navigationbar.actor.SelectActorView
import com.google.gson.Gson
import kotlinx.android.synthetic.main.activity_scene_edit.*
import com.bomostory.sceneeditmodule.basicdata.*
import com.bomostory.sceneeditmodule.view.EditActorView
import com.bomostory.sceneeditmodule.view.OnTouchBoMoSceneListener
import com.bomostory.sceneeditmodule.view.SceneView1
import com.example.tfat.myapplication.navigationbar.RecordFinishView
import com.example.tfat.myapplication.navigationbar.actor.LayerManagementDialog
import kotlinx.android.synthetic.main.control_actor_dialog.view.*
import java.io.File
import java.io.FileWriter
import com.bomostory.sceneeditmodule.utils.FileUtils


class SceneEditActivity : AppCompatActivity(), ActorAdapter.OnActorDragListener, EditActorView.OnActorChangeListener,
        OnTouchBoMoSceneListener.OnSceneMoveListener, DialogInterface.OnDismissListener, FileUtils.OnSaveActorImage,
        LayerManagementDialog.OnLayerChange {

    private lateinit var project: Project
    private var currentSceneIndex = 0
    private var currentLayerIndex = 6
    private var startRecordTime = 0L
    private var record = Record()
    private var resourceThemeBitmap = ArrayList<String>()
    private var resourceActorBitmap = ArrayList<ArrayList<String>>()
    private lateinit var sceneAdapter: SceneAdapter
    private var isRecord = false
    private var layerManagementDialog = LayerManagementDialog()
    companion object {
        const val PHOTO_FROM_GALLERY = 1
        const val LAYER_MANAGEMENT = "layer_management"
        const val ACTOR_HEIGHT = 200
        const val ACTOR_WIDTH = 200
        const val ACTOR_INIT_POSITION_X = 200
        const val ACTOR_INIT_POSITION_Y = 200
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_scene_edit)
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN)
        actionBar?.hide()
        supportActionBar?.hide()
        project = Gson().fromJson<Project>(intent.getStringExtra("project"), Project::class.java)
        resourceThemeBitmap = project.sceneResource as ArrayList<String>
        resourceActorBitmap = project.actorResource as ArrayList<ArrayList<String>>
        project.story?.let {
            it.scenes?.let{
                sceneEditView.scene = it[0]
            }
        }
        ic_scene_edit_activity_back.setOnClickListener {
            this.onBackPressed()
        }
        initControlBarView()
        initNavigationBarView()
        initRecord()
    }

    override fun onResume() {
        super.onResume()
        window.decorView.apply {
            systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_LOW_PROFILE
                    or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
        }
    }

    private fun initControlBarView() {
        controlBarView.setBtnSelected(6)
        controlBarView.setonClickSwipeLayerBtn(View.OnClickListener {
            switchToPreViewLayer()
        })
        controlBarView.setonClickLayerSceneBtn(View.OnClickListener {
            layerManagementDialog = LayerManagementDialog()
            project.story?.let {
                it.scenes?.let{
                    layerManagementDialog.setData(it[currentSceneIndex])
                }
            }
            layerManagementDialog.setListener(this)
            layerManagementDialog.show(supportFragmentManager,LAYER_MANAGEMENT)
        })
        controlBarView.setonClickLayerBackgroundBtn(View.OnClickListener {
            switchLayer(4)
        })
        controlBarView.setonClickLayer4Btn(View.OnClickListener {
            switchLayer(3)
        })
        controlBarView.setonClickLayer3Btn(View.OnClickListener {
            switchLayer(2)
        })
        controlBarView.setonClickLayer2Btn(View.OnClickListener {
            switchLayer(1)
        })
        controlBarView.setonClickLayer1Btn(View.OnClickListener {
            switchLayer(0)
        })
    }

    private fun initNavigationBarView() {
        project.story?.let {
            it.scenes?.let {
                if (it[currentSceneIndex].record == null) {
                    var navigationBarView = NavigationBarView(this)
                    navigationBar.addView(navigationBarView)
                    navigationBarView.setonClickSceneBtn(View.OnClickListener {
                        initControlSceneView()
                    })
                    navigationBarView.setonClickActorBtn(View.OnClickListener {
                        initActorRecyclerView()
                    })
                    navigationBarView.setonClickBrushBtn(View.OnClickListener {

                    })
                    navigationBarView.setonClickDialogueBtn(View.OnClickListener {

                    })
                    navigationBarView.setonClickImageBtn(View.OnClickListener {
                        pickFromGallery()
                    })
                } else {
                    navigationBar.removeAllViews()
                    var recordFinishView = RecordFinishView(this)
                    recordFinishView.setOnNextSceneClickListener(View.OnClickListener {
                        switchScene(currentSceneIndex + 1)
                    })
                    recordFinishView.setOnFinishClickListener(View.OnClickListener {
                        project.story?.let {
                            it.scenes?.let {
                                when (it.size) {
                                    1 -> project.scene1 = it[0].backgroundPath
                                    else -> {
                                        project.scene1 = it[0].backgroundPath
                                        project.scene2 = it[1].backgroundPath
                                    }
                                }
                            }
                        }
                        val dir = File(Config.PROJECTS_FOLDER,"")
                        dir.mkdir()
                        val file = File(Config.PROJECTS_FOLDER, project.name + ".json")
                        try {
                            val fileWriter = FileWriter(file)
                            fileWriter.write(Gson().toJson(project))
                            fileWriter.flush()
                        } catch (e: Exception) {
                            e.printStackTrace()
                        }
                        val intent = Intent(this, MovieEditActivity::class.java)
                        intent.putExtra(MovieEditActivity.PROJECT_KEY, Gson().toJson(project))
                        startActivity(intent)
                    })
                    navigationBar.addView(recordFinishView)
                }
            }
        }
    }

    private fun initActorRecyclerView() {
        if (viewContainer.getChildAt(0) is SelectActorView) {
            viewContainer.removeAllViews()
            return
        }
        if (currentLayerIndex == 6){
            switchLayer(0)
            return
        }
        var selectActorView = SelectActorView(this)
        val layoutManager = LinearLayoutManager(this)
        layoutManager.orientation = LinearLayoutManager.HORIZONTAL
        var actorAdapter = ActorAdapter(this, resourceActorBitmap, sceneEditView.findViewById(currentLayerIndex), this)
        var actorRecyclerView = selectActorView.findViewById<RecyclerView>(R.id.select_actor_recycler_view)
        actorRecyclerView.layoutManager = layoutManager
        actorRecyclerView.adapter = actorAdapter
        viewContainer.addView(selectActorView)
    }

    private fun initControlSceneView() {
        if (viewContainer.getChildAt(0) is ControlSceneView) {
            viewContainer.removeAllViews()
            return
        }
        var projectBitmaps = ArrayList<Drawable>()
        var onSceneSelectedArrayList = ArrayList<View.OnClickListener>()
        project.story?.let {
            it.scenes?.let{
                for (i in 0 until it.size) {
                    onSceneSelectedArrayList.add(switchScene(i))
                    projectBitmaps.add(Drawable.createFromPath(it[i].backgroundPath))
                }
            }
        }
        sceneAdapter = SceneAdapter(this, projectBitmaps, onSceneSelectedArrayList, currentSceneIndex)
        var controlSceneView = ControlSceneView(this)
        controlSceneView.setonClickAddBtn(View.OnClickListener {
            viewContainer.removeAllViews()
            var addSceneView = AddSceneView(this)
            viewContainer.addView(addSceneView)
            val layoutManager = LinearLayoutManager(this)
            layoutManager.orientation = LinearLayoutManager.HORIZONTAL
            var onSceneSelectedArrayList = ArrayList<View.OnClickListener>()
            for (i in 0 until resourceThemeBitmap.size) {
                onSceneSelectedArrayList.add(addScene(i))
            }
            var addSceneAdapter = AddSceneAdapter(this, resourceThemeBitmap, onSceneSelectedArrayList)
            var newSceneRecyclerView = addSceneView.findViewById<RecyclerView>(R.id.new_scene_recycler_view)
            newSceneRecyclerView.layoutManager = layoutManager
            newSceneRecyclerView.adapter = addSceneAdapter
        })
        controlSceneView.setonClickDuplicateBtn(View.OnClickListener {
            project.story?.let {
                it.scenes?.let{
                    it.add(currentSceneIndex + 1 ,it[currentSceneIndex])
                }
            }
            var sceneAdapter = controlSceneView.findViewById<RecyclerView>(R.id.scene_recycler_view).adapter as SceneAdapter
            var projectBitmaps = ArrayList<Drawable>()
            var onSceneSelectedArrayList = ArrayList<View.OnClickListener>()
            project.story?.let {
                it.scenes?.let{
                    for (i in 0 until it.size) {
                        onSceneSelectedArrayList.add(switchScene(i))
                        projectBitmaps.add(Drawable.createFromPath(it[i].backgroundPath))
                    }
                }
            }
            sceneAdapter.update(projectBitmaps, onSceneSelectedArrayList)
        })
        val layoutManager = LinearLayoutManager(this)
        layoutManager.orientation = LinearLayoutManager.HORIZONTAL
        var sceneRecyclerView = controlSceneView.findViewById<RecyclerView>(R.id.scene_recycler_view)
        sceneRecyclerView.layoutManager = layoutManager
        sceneRecyclerView.adapter = sceneAdapter
        viewContainer.removeAllViews()
        viewContainer.addView(controlSceneView)
    }

    private fun initRecord(){
        startRecord.setOnClickListener(View.OnClickListener {
            if (!isRecord) {
                startRecord.setImageDrawable(resources.getDrawable(R.drawable.ic_btn_record_stop))
                startRecordTime = System.currentTimeMillis()
                isRecord = true
                switchToPreViewLayer()
                navigationBar.visibility = View.INVISIBLE
            } else {
                isRecord = false
                record.period = System.currentTimeMillis() - startRecordTime
                project.story?.let {
                    it.scenes?.let{
                        it[currentSceneIndex].record = record
                    }
                }
                startRecord.setImageDrawable(resources.getDrawable(R.drawable.ic_btn_record))
                navigationBar.visibility = View.VISIBLE
                initControlSceneView()
                initNavigationBarView()
            }
        })
    }


    private fun switchScene(position: Int): View.OnClickListener {
        return View.OnClickListener {
            currentSceneIndex = position
            switchLayer(6)
            project.story?.let {
                it.scenes?.let{
                    sceneEditView.scene = it[position]
                }
            }
            initControlBarView()
            initNavigationBarView()
        }
    }

    private fun switchLayer(layerIndex: Int){
        viewContainer.removeAllViews()
        currentLayerIndex = layerIndex
        controlBarView.setBtnSelected(4 - layerIndex)
        project.story?.let {
            it.scenes?.let {
                for (layer in it[currentSceneIndex].layers) {
                    when(it[currentSceneIndex].layers.indexOf(layer)) {
                        currentLayerIndex ->
                            for (actor in it[currentSceneIndex].layers[currentLayerIndex].actors) {
                                actor.isMoveable = true
                            }
                        else ->
                            for (actor in it[currentSceneIndex].layers[it[currentSceneIndex].layers.indexOf(layer)].actors) {
                                actor.isMoveable = false
                            }
                    }
                }
                sceneEditView.scene = it[currentSceneIndex]
            }
        }
        sceneEditView.setOnTouchListener(null)
        setActorDropLayer()
    }

    private fun switchToPreViewLayer(){
        viewContainer.removeAllViews()
        currentLayerIndex = 6
        controlBarView.setBtnSelected(currentLayerIndex)
        project.story?.let {
            it.scenes?.let {
                for (layer in it[currentSceneIndex].layers) {
                    for (actor in layer.actors) {
                        actor.isMoveable = false
                        actor.isSelect = false
                    }
                }
                sceneEditView.scene = it[currentSceneIndex]
            }
        }
        val boMoSceneListener = OnTouchBoMoSceneListener()
        boMoSceneListener.setCallBack(this)
        sceneEditView.setOnTouchListener(boMoSceneListener)
        if (viewContainer.getChildAt(0) is SelectActorView) {
            viewContainer.removeAllViews()
        }
    }


    private fun setActorDropLayer() {
        if (viewContainer.getChildAt(0) is SelectActorView) {
            var selectActorView = SelectActorView(this)
            val layoutManager = LinearLayoutManager(this)
            layoutManager.orientation = LinearLayoutManager.HORIZONTAL
            var actorAdapter = ActorAdapter(this, resourceActorBitmap, sceneEditView.findViewById(currentLayerIndex), this)
            var actorRecyclerView = selectActorView.findViewById<RecyclerView>(R.id.select_actor_recycler_view)
            actorRecyclerView.layoutManager = layoutManager
            actorRecyclerView.adapter = actorAdapter
            viewContainer.addView(selectActorView)
        }
    }

    private fun addScene(position: Int): View.OnClickListener {
        return View.OnClickListener {
            var scene = Scene()
            for (i in 0 until 5){
                val layer = Layer()
                layer.id = i
                scene.layers.add(layer)
            }
            scene.backgroundPath = resourceThemeBitmap[position]
            project.story?.let {
                it.scenes?.let{
                    it.add(scene)
                }
            }
            initControlSceneView()
            initNavigationBarView()
        }
    }

    private fun setActorPositionZ(actors: ArrayList<Actor>){
        for (actor in actors) {
            actor.positionZ = actors.indexOf(actor)
        }
    }

    private fun pickFromGallery() {
        val intent = Intent()
        intent.type = "image/*"
        intent.action = Intent.ACTION_GET_CONTENT
        startActivityForResult(intent, PHOTO_FROM_GALLERY)
    }

    private fun addActor(positionX: Int, positionY: Int, resourcePath: String) {
        project.story?.let {
            it.scenes?.let{
                val actorData = Actor()
                actorData.positionX = positionX
                actorData.positionY = positionY
                actorData.positionZ = it[currentSceneIndex].layers[currentLayerIndex].actors.size
                actorData.sideLength = ACTOR_WIDTH
                actorData.sideHeight = ACTOR_HEIGHT
                actorData.resourcePath = resourcePath
                actorData.parentLayerIndex = currentLayerIndex
                actorData.isMoveable = true
                it[currentSceneIndex].layers[currentLayerIndex].actors.add(actorData)
                sceneEditView.scene = it[currentSceneIndex]
            }
        }
        setActorDropLayer()
    }

    override fun onActorDropFinish(positionX: Int, positionY: Int, resourcePath: String) {
        addActor(positionX, positionY, resourcePath)
    }

    override fun onActorChange(actor: Actor) {
        project.story?.let {
            it.scenes?.let {
                it[currentSceneIndex].layers[currentLayerIndex].actors[actor.positionZ] = actor
                sceneEditView.scene = it[currentSceneIndex]
            }
        }
    }

    override fun onActorSelected(actor: Actor) {
        project.story?.let {
            it.scenes?.let {
                for(i in 0 until it[currentSceneIndex].layers[currentLayerIndex].actors.size){
                    if(actor.positionZ == i) {
                        it[currentSceneIndex].layers[currentLayerIndex].actors[i] = actor
                    } else {
                        it[currentSceneIndex].layers[currentLayerIndex].actors[i].isSelect = false
                    }
                }
                sceneEditView.scene = it[currentSceneIndex]
            }
        }
    }

    override fun onActorLongClick(actor: Actor) {
        project.story?.let {
            it.scenes?.let {
                for(i in 0 until it[currentSceneIndex].layers[currentLayerIndex].actors.size){
                    if(actor.positionZ == i) {
                        it[currentSceneIndex].layers[currentLayerIndex].actors[i] = actor
                    } else {
                        it[currentSceneIndex].layers[currentLayerIndex].actors[i].isSelect = false
                    }
                }
                sceneEditView.scene = it[currentSceneIndex]
            }
        }
        var popupWindow = PopupWindow(this)
        val popupView = LayoutInflater.from(this).inflate(R.layout.control_actor_dialog, null)
        popupView.duplicate.setOnClickListener{
            project.story?.let {
                it.scenes?.let {
                    val actorData = Actor().apply {
                        positionX = actor.positionX + 100
                        positionY = actor.positionY + 100
                        positionZ = it[currentSceneIndex].layers[currentLayerIndex].actors.size
                        sideLength = actor.sideLength
                        sideHeight = actor.sideHeight
                        resourcePath = actor.resourcePath
                        parentLayerIndex = currentLayerIndex
                        isMoveable = true
                    }
                    it[currentSceneIndex].layers[currentLayerIndex].actors.add(actorData)
                     setActorPositionZ(it[currentSceneIndex].layers[currentLayerIndex].actors)
                    sceneEditView.scene = it[currentSceneIndex]
                    popupWindow.dismiss()
                }
            }
        }
        popupView.bring_to_front.setOnClickListener{
            project.story?.let {
                it.scenes?.let {
                    it[currentSceneIndex].layers[currentLayerIndex].actors.remove(actor)
                    it[currentSceneIndex].layers[currentLayerIndex].actors.add(actor)
                    setActorPositionZ(it[currentLayerIndex].layers[currentLayerIndex].actors)
                    sceneEditView.scene = it[currentSceneIndex]
                    popupWindow.dismiss()
                }
            }
        }
        popupView.send_to_back.setOnClickListener{
            project.story?.let {
                it.scenes?.let {
                    it[currentSceneIndex].layers[currentLayerIndex].actors.remove(actor)
                    it[currentSceneIndex].layers[currentLayerIndex].actors.add(0, actor)
                    setActorPositionZ(it[currentLayerIndex].layers[currentLayerIndex].actors)
                    sceneEditView.scene = it[currentSceneIndex]
                    popupWindow.dismiss()
                }
            }
        }
        popupView.delete.setOnClickListener{
            project.story?.let {
                it.scenes?.let {
                    it[currentSceneIndex].layers[currentLayerIndex].actors.removeAt(actor.positionZ)
                    sceneEditView.scene = it[currentSceneIndex]
                    popupWindow.dismiss()
                }
            }
        }
        popupWindow.contentView = popupView
        popupWindow.width = ViewGroup.LayoutParams.WRAP_CONTENT
        popupWindow.height = ViewGroup.LayoutParams.WRAP_CONTENT
        popupWindow.isOutsideTouchable = true
        popupWindow.showAtLocation(sceneEditView, Gravity.START,actor.positionX,actor.positionY)
    }


    override fun onSceneMove(dX: Int) {
        sceneEditView.x = dX
        if (isRecord){
            record?.tracks.let {
                val track = Track()
                track.positionX = dX
                track.time = System.currentTimeMillis() - startRecordTime
                record.tracks.add(track)
            }
        }
    }

    override fun onDismiss(dialog: DialogInterface?) {
        project.story?.let {
            it.scenes?.let {
                sceneEditView.scene = it[currentSceneIndex]
            }
        }
        window.decorView.apply {
            systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_LOW_PROFILE
                    or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
        }
        initControlBarView()
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            PHOTO_FROM_GALLERY ->
                when (resultCode) {
                    Activity.RESULT_OK -> if (data != null) {
                        FileUtils.saveImageForActor(this, data.data, System.currentTimeMillis().toString())
                    }
                    Activity.RESULT_CANCELED -> {
                    }
                }
        }
    }

    override fun onSaveActorImage(filePath: String) {
        addActor(ACTOR_INIT_POSITION_X, ACTOR_INIT_POSITION_Y, filePath)
    }

    override fun onLayerChange(layerFrom: Int, layerTo: Int, position: Int){
        project.story?.let {
            it.scenes?.let {
                var actor = it[currentSceneIndex].layers[layerFrom - 1].actors[position]
                it[currentSceneIndex].layers[layerTo - 1].actors.add(actor)
                it[currentSceneIndex].layers[layerFrom - 1].actors.removeAt(position)
                layerManagementDialog.setData(it[currentSceneIndex])
                setActorPositionZ(it[currentSceneIndex].layers[layerFrom - 1].actors)
                setActorPositionZ(it[currentSceneIndex].layers[layerTo - 1].actors)
                sceneEditView.scene = it[currentSceneIndex]
            }
        }
    }
}
