//
//  ToolBarController.swift
//  Steve ][
//
//  Created by Tamas Rudnai on 6/30/20.
//  Copyright © 2019, 2020 Tamas Rudnai. All rights reserved.
//
// This file is part of Steve ][ -- The Apple ][ Emulator.
//
// Steve ][ 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.
//
// Steve ][ 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 Steve ][.  If not, see <https://www.gnu.org/licenses/>.
//

import Cocoa


class ToolBarController: NSWindowController, NSWindowDelegate {
    
    static var current : ToolBarController? = nil
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        ToolBarController.current = self
    }

    func window(_ window: NSWindow, willUseFullScreenPresentationOptions proposedOptions: NSApplication.PresentationOptions = []) -> NSApplication.PresentationOptions {
        return [.autoHideToolbar, .autoHideMenuBar, .fullScreen]
    }
    
    var sideBarWidth = CGFloat()

    
    func setDisplaySize(
        leading: CGFloat,
        trailing: CGFloat,
        top: CGFloat,
        bottom: CGFloat,
        sidePanelSize: CGFloat,
        sidePanelHidden: Bool
    ) {
        if let view = window?.contentView {
            for constraint in view.constraints {
                switch constraint.identifier {
                case "Display Background Trailing":
                    constraint.constant = sidePanelSize
                case "Display Margin Leading":
                    constraint.constant = leading
                case "Display Margin Trailing":
                    constraint.constant = trailing
                case "Display Margin Top":
                    constraint.constant = top
                case "Display Margin Bottom":
                    constraint.constant = bottom
                default:
                    continue
                }
            }
            
            for subview in view.subviews {
                if subview.identifier?.rawValue == "Side Panel" {
                    subview.isHidden = sidePanelHidden
                }
            }
        }
    }
    
    func setDisplayFullscreen() {
        print("setDisplayFullscreen")
        setDisplaySize(
            leading: 0,
            trailing: 0,
            top: 0,
            bottom: 0,
            sidePanelSize: 0,
            sidePanelHidden: true
        )
    }
    
    func setDisplayWindowed() {
        print("setDisplayWindowed")
        setDisplaySize(
            leading: 11,
            trailing: -11,
            top: 16,
            bottom: -16,
            sidePanelSize: 136,
            sidePanelHidden: false
        )
    }
    
    func windowWillEnterFullScreen(_ notification: Notification) {
        setDisplayFullscreen()
    }
    
    func windowWillExitFullScreen(_ notification: Notification) {
        setDisplayWindowed()
    }


    let offLabel = "Off\u{A0}\u{A0}\u{A0}\u{A0}\u{A0}\u{A0}\u{A0}\u{A0}"
    let pauseLabel = "Pause\u{A0}\u{A0}\u{A0}"
    let resumeLabel = "Resume"


    override func windowDidLoad() {
        let isWindowFullscreen = window?.styleMask.contains(.fullSizeContentView) ?? false
        if isWindowFullscreen {
            window?.toggleFullScreen(self)
        }
        
        if let PauseToolbarItem = PauseToolbarItem {
            PauseToolbarItem.isEnabled = false;
            PauseToolbarItem.label = offLabel
        }
        if let PauseButton = PauseButton {
            PauseButton.state = .off
        }
    }
        
    @IBAction func PowerOn(_ sender: Any) {
        switch cpuState {
        case cpuState_inited, cpuState_unknown:
            if let PauseToolbarItem = PauseToolbarItem {
                PauseToolbarItem.isEnabled = true;
                PauseToolbarItem.label = pauseLabel
            }
            if let PauseButton = PauseButton {
                PauseButton.state = .on
            }

            ViewController.shared?.PowerOn(sender)

        default:
            if let PauseToolbarItem = PauseToolbarItem {
                PauseToolbarItem.isEnabled = false;
                PauseToolbarItem.label = offLabel
            }
            if let PauseButton = PauseButton {
                PauseButton.state = .off
            }

            ViewController.shared?.PowerOff(sender)
        }
    }

    @IBOutlet weak var PauseToolbarItem: NSToolbarItem!
    @IBOutlet weak var PauseButton: NSButton!

    func PauseButtonUpdate(needUpdateDebugToolbar: Bool = true) {
        DispatchQueue.main.async {
            switch cpuState {
            case cpuState_halted:
                if let PauseButton = self.PauseButton {
                    PauseButton.state = .off
                }
                if let PauseToolbarItem = self.PauseToolbarItem {
                    PauseToolbarItem.label = self.resumeLabel
                }

            case cpuState_running:
                if let PauseButton = self.PauseButton {
                    PauseButton.state = .on
                }
                if let PauseToolbarItem = self.PauseToolbarItem {
                    PauseToolbarItem.label = self.pauseLabel
                }

            default: // OFF
                if let PauseToolbarItem = self.PauseToolbarItem {
                    PauseToolbarItem.isEnabled = false;
                    PauseToolbarItem.label = self.offLabel
                }
                if let PauseButton = self.PauseButton {
                    PauseButton.state = .off
                }
                break
            }
        }

        if needUpdateDebugToolbar {
            if let debugger = DebuggerWindowController.shared {
                debugger.PauseButtonUpdate(needUpdateMainToolbar: false)
            }
        }
    }

    @IBAction func Pause(_ sender: Any) {
        switch cpuState {
        case cpuState_halted:
            ViewController.shared?.Pause(sender)

        case cpuState_running:
            ViewController.shared?.Pause(sender)
            
        default:
            break
        }

        PauseButtonUpdate()

        if let debugger = DebuggerWindowController.shared {
            debugger.PauseButtonUpdate(needUpdateMainToolbar: false)
        }
    }
    
    @IBAction func Reset(_ sender: Any) {
        ViewController.shared?.Reset(sender)
    }
    
    @IBAction func SelectAll(_ sender: Any) {
//        ViewController.current?.displayField.currentEditor()?.selectAll(nil)
//        ViewController.current?.displayField.selectText(nil)
        ViewController.shared?.textDisplay.setSelectedRange(NSRange())
    }
    
    @IBAction func Copy(_ sender: Any) {
        ViewController.shared?.Copy()
    }
    
    @IBAction func Paste(_ sender: Any) {
        ViewController.shared?.Paste()
    }
    
    @IBAction func Green(_ sender: Any) {
//        print("NSToolbarItem:", sender.tag)
        ViewController.shared?.MonoMonitorChange(color: "Green")
    }
    
    @IBAction func Amber(_ sender: Any) {
//        print("NSToolbarItem:", sender.tag)
        ViewController.shared?.MonoMonitorChange(color: "Amber")
    }
    
    @IBAction func White(_ sender: Any) {
//        print("NSToolbarItem:", sender.tag)
        ViewController.shared?.MonoMonitorChange(color: "White")
    }
    
    @IBAction func Color(_ sender: Any) {
        ViewController.shared?.ColorMonitorSelector(color: true)
    }
    
    @IBOutlet weak var SpeedSelector: NSToolbarItem!
    
    @IBAction func SpeedSelected(_ slider: NSSliderCell) {
        switch slider.intValue {
        case 1:
            ViewController.shared?.setCPUClockSpeed(freq: 0.25)
            SpeedSelector.label = "0.25 MHz"
            
        case 2:
            ViewController.shared?.setCPUClockSpeed(freq: 0.5)
            SpeedSelector.label = "0.5 MHz"
            
        case 4:
            ViewController.shared?.setCPUClockSpeed(freq: 1.5)
            SpeedSelector.label = "1.5 MHz"
            
        case 5:
            ViewController.shared?.setCPUClockSpeed(freq: 2)
            SpeedSelector.label = "2 MHz"
            
        case 6:
            ViewController.shared?.setCPUClockSpeed(freq: 2.8)
            SpeedSelector.label = "2.8 MHz"
            
        case 7:
            ViewController.shared?.setCPUClockSpeed(freq: 4)
            SpeedSelector.label = "4 MHz"
            
        case 8:
            ViewController.shared?.setCPUClockSpeed(freq: 10)
            SpeedSelector.label = "10 MHz"
            
        case 9:
            ViewController.shared?.setCPUClockSpeed(freq: 100)
            SpeedSelector.label = "100 MHz"
            
        case 10:
            ViewController.shared?.setCPUClockSpeed(freq: 2000)
            SpeedSelector.label = "MAX Speed"
            
        default:
            ViewController.shared?.setCPUClockSpeed(freq: 14.31818 / 14.0)
            SpeedSelector.label = "1.023 MHz"
        }
    }
    
    @IBAction func Mute(_ sender: Any) {
        spkr_mute()
    }
    
    @IBAction func VolDn(_ sender: Any) {
        spkr_vol_dn()
    }
    
    @IBAction func VolUp(_ sender: Any) {
        spkr_vol_up()
    }
    
    
    @IBAction func GamePort(_ sender: NSPopUpButton) {
        switch sender.selectedItem?.tag {
        case 1: // "Keyboard -> Joystick"
            if let state = ViewController.shared?.Keyboard2Joystick {
                ViewController.shared?.Keyboard2Joystick = !state
                sender.selectedItem?.state = state ? .off : .on
            }
            break
            
        case 2: // "Mouse -> Joystick"
            if let state = ViewController.shared?.Mouse2Joystick {
                ViewController.shared?.Mouse2Joystick = !state
                sender.selectedItem?.state = state ? .off : .on
                
                ViewController.shared?.mouseCursor(hide: !state)                
            }
            break
            
        case 3: // "Mouse Enabled"
            if let state = ViewController.shared?.MouseInterface {
                ViewController.shared?.MouseInterface = !state
                sender.selectedItem?.state = state ? .off : .on
            }
            break
            
        default:
            break
        }
    }
    
    @IBOutlet weak var MouseToJoystickMenuItem: NSMenuItem!
    
    @IBAction func DiskOptions(_ sender: NSPopUpButton) {
        switch sender.selectedItem?.tag {
        case 1: // "Quick Disk"
            if diskAccelerator_enabled == 0 {
                diskAccelerator_enabled = 1;
            }
            else {
                diskAccelerator_enabled = 0;
            }

            sender.selectedItem?.state = diskAccelerator_enabled == 1 ? .on : .off
            break
            
        case 2: // "Disk Sound"
            if disk_sfx_enabled == 0 {
                disk_sfx_enabled = 1;
            }
            else {
                disk_sfx_enabled = 0;
            }
            
            sender.selectedItem?.state = disk_sfx_enabled == 1 ? .on : .off
            break
            
        case 3: // "Write Enabled"
            break
            
        default:
            break
        }
    }

    @IBAction func CPUMode(_ sender: NSPopUpButton) {
        switch sender.selectedItem?.tag {
        case 1: // "Normal Mode"
            ViewController.shared?.setSimulationMode( mode: "Normal" )
            for i in sender.itemArray {
                i.state = .off
            }
            sender.selectedItem?.state = .on
            break
            
        case 2: // "Eco Mode"
            ViewController.shared?.setSimulationMode( mode: "Eco" )
            for i in sender.itemArray {
                i.state = .off
            }
            sender.selectedItem?.state = .on
            break

        case 3: // "Write Enabled"
            ViewController.shared?.setSimulationMode( mode: "Game" )
            for i in sender.itemArray {
                i.state = .off
            }
            sender.selectedItem?.state = .on
            break

        default:
            break
        }
    }
    
    @IBAction func CRTModeOnOff(_ sender: NSButton) {
        ViewController.shared?.CRTMonitorOnOff(sender)
    }
    
    @IBAction func Debugger(_ sender: Any) {
        if DebuggerWindowController.shared == nil {
            let debuggerStoryboard = NSStoryboard.init(name: NSStoryboard.Name("Debugger"), bundle: nil)
            debuggerStoryboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("debuggerWindowController"))
        }

        if let debugger = DebuggerWindowController.shared {
            debugger.showWindow(self)
        }
    }

}
