//
//  CAreaSettingWindowController.swift
//  Cisdem PDFMaster
//
//  Created by wanjun on 2024/7/16.
//

import Cocoa

@objc protocol CAreaSettingWindowControllerDelegate: AnyObject {
    @objc optional func areaSettingWindowController(_ areaSettingWindowController: CAreaSettingWindowController, measureInfo: CPDFAreaMeasureInfo?)
}

class CAreaSettingWindowController: NSWindowController, NSTextFieldDelegate {

    @IBOutlet weak var rulerBaseTextField: NSTextField!
    @IBOutlet weak var rulerBasePopButton: NSPopUpButton!
    @IBOutlet weak var rulerTranslateTextField: NSTextField!
    @IBOutlet weak var rulerTranslatePopButton: NSPopUpButton!
    @IBOutlet weak var precisionPopButton: NSPopUpButton!
    @IBOutlet weak var isLengthCaptionButton: NSButton!
    @IBOutlet weak var isAreaCaptionButton: NSButton!
    @IBOutlet weak var doneButton: NSButton!
    @IBOutlet weak var cancelButton: NSButton!

    @IBOutlet weak var customLabel: NSTextField!
    @IBOutlet weak var drawingLabel: NSTextField!
    @IBOutlet weak var precisionLabel: NSTextField!
    @IBOutlet weak var showLabel: NSTextField!

    
    @objc weak var delegate: CAreaSettingWindowControllerDelegate?
    
    private var measureInfo: CPDFAreaMeasureInfo
    private var modalSession: NSApplication.ModalSession?
    
    @objc init(measureInfo: CPDFAreaMeasureInfo) {
        self.measureInfo = measureInfo
        super.init(window: nil)
//        self.windowNibName = "CAreaSettingWindowController"
        Bundle.main.loadNibNamed("CAreaSettingWindowController", owner: self, topLevelObjects: nil)
        commonInit()
        configurationLanguage()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func windowDidLoad() {
        super.windowDidLoad()

//        commonInit()
    }
    
    private func configurationLanguage() {
        self.window?.title = NSLocalizedString("Measure Settings", comment: "")
        customLabel.stringValue = NSLocalizedString("Custom Scale", comment: "")
        drawingLabel.stringValue = NSLocalizedString("Drawing Dimensions: Actual Size", comment: "")
        precisionLabel.stringValue = NSLocalizedString("Precision Setting", comment: "")
        showLabel.stringValue = NSLocalizedString("Show Caption", comment: "")
        
        isLengthCaptionButton.title = NSLocalizedString("Length", comment: "")
        isAreaCaptionButton.title = NSLocalizedString("Area", comment: "")
        doneButton.title = NSLocalizedString("Done", comment: "")
        cancelButton.title = NSLocalizedString("Cancel", comment: "")

    }
    
    private func commonInit() {
        let me = measureInfo
        switch me.captionType {
        case CPDFCaptionType(rawValue: 0):
            isAreaCaptionButton.state = .off
            isLengthCaptionButton.state = .off
        case .area:
            isAreaCaptionButton.state = .on
            isLengthCaptionButton.state = .off
        case .length:
            isAreaCaptionButton.state = .off
            isLengthCaptionButton.state = .on
        case [.area, .length]:
            isAreaCaptionButton.state = .on
            isLengthCaptionButton.state = .on
        default:
            break
        }
        rulerBaseTextField.stringValue = String(format: "%0.0f", me.rulerBase)
        rulerTranslateTextField.stringValue = String(format: "%0.0f", me.rulerTranslate)
        
        rulerBasePopButton.removeAllItems()
        rulerBasePopButton.addItems(withTitles: ["in", "cm", "mm"])
        selectRulerBasePopButton(measureInfo: me)
        
        rulerTranslatePopButton.removeAllItems()
        rulerTranslatePopButton.addItems(withTitles: ["pt", "cm", "in", "mm", "m", "km", "ft", "yd", "mi"])
        selectRulerTranslatePopButton(measureInfo: me)
        
        precisionPopButton.removeAllItems()
        precisionPopButton.addItems(withTitles: ["1", "0.1", "0.01", "0.001", "0.0001"])
        selectPrecisionPopButton(measureInfo: me)
        
        rulerBaseTextField.delegate = self
        rulerTranslateTextField.delegate = self
    }
    
    private func selectRulerBasePopButton(measureInfo: CPDFAreaMeasureInfo) {
        let constants = CPDFMeasureConstants.sharedInstance()
        if measureInfo.rulerBaseUnit == constants.cpdfIn {
            rulerBasePopButton.selectItem(withTitle: "in")
        } else if measureInfo.rulerBaseUnit == constants.cpdfCm {
            rulerBasePopButton.selectItem(withTitle: "cm")
        } else if measureInfo.rulerBaseUnit == constants.cpdfMm {
            rulerBasePopButton.selectItem(withTitle: "mm")
        }
    }

    private func selectRulerTranslatePopButton(measureInfo: CPDFAreaMeasureInfo) {
        let constants = CPDFMeasureConstants.sharedInstance()
        if measureInfo.rulerTranslateUnit == constants.cpdfPt {
            rulerTranslatePopButton.selectItem(withTitle: "pt")
        } else if measureInfo.rulerTranslateUnit == constants.cpdfIn {
            rulerTranslatePopButton.selectItem(withTitle: "in")
        } else if measureInfo.rulerTranslateUnit == constants.cpdfCm {
            rulerTranslatePopButton.selectItem(withTitle: "cm")
        } else if measureInfo.rulerTranslateUnit == constants.cpdfMm {
            rulerTranslatePopButton.selectItem(withTitle: "mm")
        } else if measureInfo.rulerTranslateUnit == constants.cpdfM {
            rulerTranslatePopButton.selectItem(withTitle: "m")
        } else if measureInfo.rulerTranslateUnit == constants.cpdfKm {
            rulerTranslatePopButton.selectItem(withTitle: "km")
        } else if measureInfo.rulerTranslateUnit == constants.cpdfFt {
            rulerTranslatePopButton.selectItem(withTitle: "ft")
        } else if measureInfo.rulerTranslateUnit == constants.cpdfYd {
            rulerTranslatePopButton.selectItem(withTitle: "yd")
        } else if measureInfo.rulerTranslateUnit == constants.cpdfMi {
            rulerTranslatePopButton.selectItem(withTitle: "mi")
        }
    }
    
    private func selectPrecisionPopButton(measureInfo: CPDFAreaMeasureInfo) {
        switch measureInfo.precision {
        case 1:
            precisionPopButton.selectItem(withTitle: "1")
        case 10:
            precisionPopButton.selectItem(withTitle: "0.1")
        case 100:
            precisionPopButton.selectItem(withTitle: "0.01")
        case 1000:
            precisionPopButton.selectItem(withTitle: "0.001")
        case 10000:
            precisionPopButton.selectItem(withTitle: "0.0001")
        default:
            break
        }
    }
    
    @IBAction func startModal(_ sender: Any) {
        NSApp.stopModal()
        self.modalSession = NSApp.beginModalSession(for: self.window!)
        var modalCode: NSApplication.ModalResponse
        repeat {
            modalCode = NSApp.runModalSession(self.modalSession!)
        } while modalCode == .continue
    }
    
    @IBAction func endModal(_ sender: Any) {
        if let session = modalSession {
            NSApp.stopModal()
            NSApp.endModalSession(session)
            self.window?.orderOut(self)
        }
    }
    
    func controlTextDidChange(_ obj: Notification) {
        if rulerBaseTextField.stringValue.count > 6 {
            rulerBaseTextField.stringValue = String(rulerBaseTextField.stringValue.prefix(6))
        } else if rulerTranslateTextField.stringValue.count > 6 {
            rulerTranslateTextField.stringValue = String(rulerTranslateTextField.stringValue.prefix(6))
        }
        
        let rulerBaseText = rulerBaseTextField.stringValue
        let rulerTranslateText = rulerTranslateTextField.stringValue
        let nonDigits = CharacterSet.decimalDigits.inverted
        
        if rulerBaseText.rangeOfCharacter(from: nonDigits) != nil ||
            rulerTranslateText.rangeOfCharacter(from: nonDigits) != nil ||
            rulerBaseText.isEmpty ||
            rulerTranslateText.isEmpty ||
            rulerBaseText == "0" ||
            rulerTranslateText == "0" {
            doneButton.isEnabled = false
        } else {
            doneButton.isEnabled = true
        }
    }
    
    @IBAction func buttonItemClick_Rulerbase(_ sender: NSPopUpButton) {
        let selectIndex = sender.indexOfSelectedItem
        let constants = CPDFMeasureConstants.sharedInstance()
        var rulerBaseUnit = ""
        switch selectIndex {
        case 0:
            rulerBaseUnit = constants.cpdfIn
        case 1:
            rulerBaseUnit = constants.cpdfCm
        case 2:
            rulerBaseUnit = constants.cpdfMm
        default:
            break
        }
        measureInfo.rulerBaseUnit = rulerBaseUnit
    }
    
    @IBAction func buttonItemClick_Rulertranslate(_ sender: NSPopUpButton) {
        let selectIndex = sender.indexOfSelectedItem
        let constants = CPDFMeasureConstants.sharedInstance()
        var rulerTranslateUnit = ""
        var factor: CGFloat = 0
        switch selectIndex {
        case 0:
            rulerTranslateUnit = constants.cpdfPt
            factor = constants.ptPt
        case 1:
            rulerTranslateUnit = constants.cpdfCm
            factor = constants.ptCm
        case 2:
            rulerTranslateUnit = constants.cpdfIn
            factor = constants.ptIn
        case 3:
            rulerTranslateUnit = constants.cpdfMm
            factor = constants.ptMm
        case 4:
            rulerTranslateUnit = constants.cpdfM
            factor = constants.ptM
        case 5:
            rulerTranslateUnit = constants.cpdfKm
            factor = constants.ptKm
        case 6:
            rulerTranslateUnit = constants.cpdfFt
            factor = constants.ptFt
        case 7:
            rulerTranslateUnit = constants.cpdfYd
            factor = constants.ptYd
        case 8:
            rulerTranslateUnit = constants.cpdfMi
            factor = constants.ptMi
        default:
            break
        }
        measureInfo.rulerTranslateUnit = rulerTranslateUnit
        measureInfo.factor = factor
    }
    
    @IBAction func buttonItemClick_Precision(_ sender: NSPopUpButton) {
        let selectIndex = sender.indexOfSelectedItem
        let constants = CPDFMeasureConstants.sharedInstance()
        var precision = 0
        switch selectIndex {
        case 0:
            precision = constants.precisionValueZero
        case 1:
            precision = constants.precisionValueOne
        case 2:
            precision = constants.precisionValueTwo
        case 3:
            precision = constants.precisionValueThree
        case 4:
            precision = constants.precisionValueFour
        default:
            break
        }
        measureInfo.precision = precision
    }
    
    @IBAction func buttonItemClick_Cancel(_ sender: Any) {
        delegate?.areaSettingWindowController?(self, measureInfo: nil)
        endModal("")
    }
    
    @IBAction func buttonItemClick_Done(_ sender: Any) {
        if let delegate = delegate {
            measureInfo.rulerBase = CGFloat(Float(rulerBaseTextField.stringValue) ?? 0)
            measureInfo.rulerTranslate = CGFloat(Float(rulerTranslateTextField.stringValue) ?? 0)
            let isLength = isLengthCaptionButton.state == .on
            let isArea = isAreaCaptionButton.state == .on
            if isLength && isArea {
                measureInfo.captionType = [.length, .area]
            } else if isLength {
                measureInfo.captionType = .length
            } else if isArea {
                measureInfo.captionType = .area
            } else {
                measureInfo.captionType = CPDFCaptionType(rawValue: 0)
            }
            delegate.areaSettingWindowController?(self, measureInfo: measureInfo)
        }
        endModal("")
    }
    
    @IBAction func buttonItemClick_Length(_ sender: Any) {}
    
    @IBAction func buttonItemClick_Area(_ sender: Any) {}
}