# Copyright (C) 2023 Stefy Lanza <stefy@nexlab.net> and SexHack.me
#
# 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 tkinter as tk
from tkinter import font as tkFont
import vlc
import webbrowser
import sys
import os
from utils import run_command, run_action
from guiutils import get_buttons
import queue
import logging

logging.getLogger(__name__)


class VideoPlayer:
    def __init__(self, master, video_url):
        self.master = master

        # VLC player setup
        args = []
        _isLinux = sys.platform.startswith('linux')
        if _isLinux:
            args.append('--vout=mmal_vout')

        # Create a VLC instance
        self.Instance = vlc.Instance(args)

        # Create a new MediaPlayer
        self.player = self.Instance.media_player_new()

        # Set the media
        media = self.Instance.media_new(video_url)
        self.player.set_media(media)

        # Create a frame for the video
        self.video_frame = self.master
        self.video_frame.pack(fill=tk.BOTH, expand=True)
        self.canvas = tk.Canvas(self.video_frame, width=800)
        self.canvas.pack(fill=tk.BOTH, expand=True)

        # Embed the VLC Video
        win_id = self.canvas.winfo_id()
        if _isLinux:
            self.player.set_xwindow(win_id)
        else:
            self.player.set_hwnd(win_id)

        # Play the video
        self.player.play()


def create_panel_gui():
    # Create the main window
    window = tk.Tk()
    window.title(config.get("Tkinter", "window_title", fallback="SHM CamStudio"))

    helv36 = tkFont.Font(family='Helvetica', size=config.get("Tkinter", "font_size", fallback=12), weight='bold')

    # Interval in ms to read the queue
    qinterval = 200 

    # Frame for the left side
    fleft = tk.Frame(window)
    fleft.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

    # URL of your RTMP stream
    video_url = config.get("General", "rtmp_url", fallback="rtmp://192.168.42.1/record/Live")
    VideoPlayer(fleft, video_url)

    # Frame for the right side
    fright = tk.Frame(window)
    fright.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)

    # Buttons configuration
    buttons, numrows = get_buttons()

    bh = int(55/numrows)
    if numrows > 0:
        row = 1
        bframes = {}
        outputs = {}
        inputs = {}
        feedbacks = {}
        while row <= numrows:
            # create the frame for this row
            bframes[row] = tk.Frame(fright)
            bframes[row].pack(fill=tk.BOTH, expand=True)

            # Calculate button width
            bw=int(100/len(buttons[row].keys()))
            
            # add the buttons
            col=0
            logging.info(buttons[row])
            for b in buttons[row].keys():
                #command=None
                #if config.has_section('ACTION:'+buttons[row][b]['action']):
                #    command=config.get('ACTION:'+buttons[row][b]['action'], 'execute', fallback=None)
                #    setstatus=config.get('ACTION:'+buttons[row][b]['action'], 'setstatus', fallback=None)
                color=buttons[row][b]['color']

                button = tk.Button(bframes[row], text=buttons[row][b]['title'], font=helv36, width=bw, height=bh, bg=color, fg="white", 
                                   command=lambda action=buttons[row][b]['action']: run_action(action))
                                   #command=lambda cmd=command,sts=setstatus: run_action(cmd,sts))
                button.grid(row=0, column=col, sticky='nsew')

                if 'output' in buttons[row][b].keys():
                    outputs[buttons[row][b]['output']] = {'btn': button, 'cfg': buttons[row][b]}

                elif 'input' in buttons[row][b].keys():
                    inputs[buttons[row][b]['input']] =  {'btn': button, 'cfg': buttons[row][b]}

                elif 'feedback' in buttons[row][b].keys():
                    if not buttons[row][b]['feedback'] in feedbacks.keys():
                        feedbacks[buttons[row][b]['feedback']] = [{'btn': button, 'cfg': buttons[row][b]}]
                    else:
                        feedbacks[buttons[row][b]['feedback']].append({'btn': button, 'cfg': buttons[row][b]})


                col = col+1

                # Configure the columns in the frame
                for i in range(len(buttons[row].keys())):
                    bframes[row].grid_columnconfigure(i, weight=1)
            row=row+1
    
    # Add a button to open web interface
    web_button = tk.Button(bframes[row-1], text="Open Web Interface",
                            command=lambda: webbrowser.open('http://localhost:5000'),
                            bg="purple", fg="white", font=helv36, height=2)
    web_button.grid(row=1, column=1, sticky='nsew')

    def read_queue():
       if not qpnl.empty():
           task=qpnl.get(block=True)
           if task:
              logging.info('TASK INCOMING FOR TK PANEL')
              logging.info(task)
              event = task['event']
              data = task['data']
              if event == 'OUTPUTCHANGE':
                 if data['output'] in outputs.keys():
                     logging.info('CHANGE THE COLOR OF THE BUTTON FOR '+str(data['output']))
                     btn = outputs[data['output']]['btn']
                     bcfg = outputs[data['output']]['cfg']
                     if 'color.'+str(data['status']) in bcfg.keys():
                        btn.config(bg=bcfg['color.'+str(data['status'])])
                     if 'title.'+str(data['status']) in bcfg.keys():
                        btn.config(text=bcfg['title.'+str(data['status'])])
              if event == 'INPUTSTATUSCHANGE':
                 if data['input'] in inputs.keys():
                    logging.info('CHANGE THE COLOR OF THE BUTTON FOR '+str(data['input'])+' ('+str(data['status']))
                    btn = inputs[data['input']]['btn']
                    bcfg = inputs[data['input']]['cfg']
                    if data['status']:
                       btn.config(bg=bcfg['color.enabled'])
                    else:
                       btn.config(bg=bcfg['color'])
              elif event == 'STATUSCHANGE':
                  if 'status' in feedbacks.keys():
                      for b in feedbacks['status']:
                          btn = b['btn']
                          bcfg = b['cfg']
                          if 'color.'+str(data['status']) in bcfg.keys():
                              btn.config(bg=bcfg['color.'+str(data['status'])])
                          if 'title.'+str(data['status']) in bcfg.keys():
                              btn.config(text=bcfg['title.'+str(data['status'])])

       window.after(qinterval, read_queue)

    window.after(qinterval, read_queue) # ms


    return window

