package com.example.milestone.milestonemobilesdkplaybacksample

import android.app.Dialog
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.widget.Button
import android.widget.EditText
import com.milestonesys.xpmobilesdk.XPMobileSDK
import com.milestonesys.xpmobilesdk.callbacks.LiveMsgCallback
import com.milestonesys.xpmobilesdk.communication.CommunicationCommand
import java.net.URL
import com.milestonesys.xpmobilesdk.communication.CommunicationItem
import android.support.v7.app.AlertDialog
import android.view.Menu
import java.net.MalformedURLException
import android.view.MenuItem

/**
 * An activity that connects and get all the available cameras from server using XPMobileSDK
 */
class MainActivity : AppCompatActivity() {

    private var serverAddressField: EditText? = null
    private var serverPortField: EditText? = null
    private var loginButton: Button? = null
    private var usernameField: EditText? = null
    private var passwordField: EditText? = null
    private var applicationObject:SDKSampleApplication? = null
    private var loadingDialog:Dialog? = null

    //Alias for server connection
    private val communicationAlias = "XProtectMobile"


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        applicationObject = application as SDKSampleApplication?

        serverAddressField = findViewById<EditText>(R.id.la_serverAddress) as EditText
        serverPortField = findViewById<EditText>(R.id.la_serverPort) as EditText
        loginButton = findViewById<Button>(R.id.loginButton) as Button
        usernameField = findViewById<EditText>(R.id.la_username) as EditText
        passwordField = findViewById<EditText>(R.id.la_password) as EditText

        val builder = AlertDialog.Builder(this)
        builder.setMessage(R.string.loading)
        loadingDialog = builder.create()

        loginButton?.setOnClickListener{

            loadingDialog?.show()

            //Creating the URL for server connection
            var connectionUrl: URL? = null
            try {
                // For this sample, we assume using HTTP.
                connectionUrl = URL("http", serverAddressField?.text.toString(), serverPortField?.text.toString().toInt(), "")
            } catch (e: MalformedURLException) {
                e.printStackTrace()
            }

            // Instancing the SDK object and storing it in the application.
            // We're using HTTP so there is no need to specify HTTPS callback and certificate
            applicationObject?.xpMobileSDK = XPMobileSDK(this, connectionUrl, communicationAlias, null, null, false, object : LiveMsgCallback {
                override fun messageFromServer(p0: String?, p1: String?, p2: MutableList<String>?, p3: String?) {
                }

                override fun liveMessageResponse(communicationCommand: CommunicationCommand) {
                }

            }, false )

            //Execute connect command from a separate Thread
            Thread(Runnable {
                try {
                    applicationObject?.xpMobileSDK?.connect({
                        //On successful connect we login method is executed
                        login()
                    }, { handleError(it) })
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }).start()
        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        val inflater = menuInflater
        inflater.inflate(R.menu.main_menu, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        when(item?.itemId){
            R.id.about_menu_item -> showAboutDlg()
        }
        return super.onOptionsItemSelected(item)
    }

    private fun showAboutDlg() {
        val builder = AlertDialog.Builder(this)
        builder.setMessage("Playback Video Sample of Milestone MobileSDK.")
                .setTitle(R.string.app_long_name)
        val dialog = builder.create()
        dialog.show()
    }

    /**
     * Execute login command with username and password
     */
    private fun login() {
        applicationObject?.xpMobileSDK?.logIn(usernameField?.text.toString(), passwordField?.text.toString(),{
            //On success get getAllViewsAndCameras method is executed
            getAllViewsAndCameras()
        }, { handleError(it) })
    }

    /**
     * All vies and cameras command is executed
     */
    private fun getAllViewsAndCameras(){
        applicationObject?.xpMobileSDK?.getAllViewsAndCameras({
            //Filters the result and store it
            getCamerasOnly(it.itemsList, applicationObject?.allAvailableCameras!!)
            val intent = Intent(this, CameraListActivity::class.java)

            //Hide loading dialog
            if(loadingDialog?.isShowing!!){
                runOnUiThread(
                        object : Runnable {
                            override fun run() {
                                loadingDialog?.dismiss()
                            }
                        }
                )

            }
            //Starting camera list activity
            startActivity(intent)

        }, { handleError(it)})
    }


    /**
     * Recursive method for filtering cameras only from response
     */
    private fun getCamerasOnly(arrayToFilter: MutableList<CommunicationItem>,arrayListToReturn: MutableList<CommunicationItem>){
        //In the structure every item could be Camera, View or Folder and we are getting only the items with Camera type, if
        //its not camera but a container we execute the method with it
        arrayToFilter.forEach { currentItem:CommunicationItem ->
            if(currentItem.type != "Camera"){
                getCamerasOnly(currentItem.itemsList,arrayListToReturn)
            }else{
                var toAdd = true
                arrayListToReturn.forEach{  currentIteratedItem:CommunicationItem ->
                    if(currentIteratedItem.id.equals(currentItem.id)){
                        toAdd = false
                    }
                }
                if(toAdd) {
                    arrayListToReturn.add(currentItem)
                }

            }
        }

    }

    /**
     * Hides loading dialog and Logs the error
     */
    private fun handleError(communicationCommand:CommunicationCommand?){
        if(loadingDialog?.isShowing!!){
            runOnUiThread(
                    object : Runnable {
                        override fun run() {
                            loadingDialog?.dismiss()
                        }
                    }
            )
        }
        Log.e("XProtectSDK", communicationCommand?.errorCode.toString())
    }

}

