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

import Cocoa

@objc protocol CDistanceSettingWindowControllerDelegate: AnyObject {
    @objc optional func distanceSettingWindowController(_ distanceSettingWindowController: CDistanceSettingWindowController, distanceMeasureInfo: CPDFDistanceMeasureInfo?)
    @objc optional func distanceSettingWindowController(_ distanceSettingWindowController: CDistanceSettingWindowController, perimeterMeasureInfo: CPDFPerimeterMeasureInfo?)
}

@objc class CDistanceSettingWindowController: NSWindowController, NSTextFieldDelegate {

    @IBOutlet weak var rulerBaseTexField: NSTextField!
    @IBOutlet weak var rulerBasePopButton: NSPopUpButton!
    @IBOutlet weak var rulerTranslateTextField: NSTextField!
    @IBOutlet weak var rulerTranslatePopButton: NSPopUpButton!
    @IBOutlet weak var precisionPopButton: NSPopUpButton!
    @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!
    
    @objc weak var delegate: CDistanceSettingWindowControllerDelegate?
    
    var distanceMeasureInfo: CPDFDistanceMeasureInfo?
    var perimeterMeasureInfo: CPDFPerimeterMeasureInfo?
    var modalSession: NSApplication.ModalSession?
    var isDistance: Bool = false
    
    @objc init(distanceMeasureInfo: CPDFDistanceMeasureInfo) {
        self.distanceMeasureInfo = distanceMeasureInfo
        self.isDistance = true
        super.init(window: nil)
        Bundle.main.loadNibNamed("CDistanceSettingWindowController", owner: self, topLevelObjects: nil)
        commonInit()
        configurationLanguage()
    }
    
    @objc init(perimeterMeasureInfo: CPDFPerimeterMeasureInfo) {
        self.perimeterMeasureInfo = perimeterMeasureInfo
        self.isDistance = false
        super.init(window: nil)
        Bundle.main.loadNibNamed("CDistanceSettingWindowController", owner: self, topLevelObjects: nil)
        commonInit()
        configurationLanguage()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    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: "")
        doneButton.title = NSLocalizedString("Done", comment: "")
        cancelButton.title = NSLocalizedString("Cancel", comment: "")

    }
    
    private func commonInit() {
        let measureInfo: CPDFMeasureInfo
        if isDistance {
            measureInfo = distanceMeasureInfo!
        } else {
            measureInfo = perimeterMeasureInfo!
        }
        
        rulerBaseTexField.stringValue = String(format: "%0.0f", measureInfo.rulerBase)
        rulerTranslateTextField.stringValue = String(format: "%0.0f", measureInfo.rulerTranslate)
        
        rulerBasePopButton.removeAllItems()
        rulerBasePopButton.addItems(withTitles: ["in", "cm", "mm"])
        
        if measureInfo.rulerBaseUnit == CPDFMeasureConstants.sharedInstance().cpdfIn {
            rulerBasePopButton.selectItem(withTitle: "in")
        } else if measureInfo.rulerBaseUnit == CPDFMeasureConstants.sharedInstance().cpdfCm {
            rulerBasePopButton.selectItem(withTitle: "cm")
        } else if measureInfo.rulerBaseUnit == CPDFMeasureConstants.sharedInstance().cpdfMm {
            rulerBasePopButton.selectItem(withTitle: "mm")
        }
        
        rulerTranslatePopButton.removeAllItems()
        rulerTranslatePopButton.addItems(withTitles: ["pt", "cm", "in", "mm", "m", "km", "ft", "yd", "mi"])
        
        if measureInfo.rulerTranslateUnit == CPDFMeasureConstants.sharedInstance().cpdfPt {
            rulerTranslatePopButton.selectItem(withTitle: "pt")
        } else if measureInfo.rulerTranslateUnit == CPDFMeasureConstants.sharedInstance().cpdfIn {
            rulerTranslatePopButton.selectItem(withTitle: "in")
        } else if measureInfo.rulerTranslateUnit == CPDFMeasureConstants.sharedInstance().cpdfCm {
            rulerTranslatePopButton.selectItem(withTitle: "cm")
        } else if measureInfo.rulerTranslateUnit == CPDFMeasureConstants.sharedInstance().cpdfMm {
            rulerTranslatePopButton.selectItem(withTitle: "mm")
        } else if measureInfo.rulerTranslateUnit == CPDFMeasureConstants.sharedInstance().cpdfM {
            rulerTranslatePopButton.selectItem(withTitle: "m")
        } else if measureInfo.rulerTranslateUnit == CPDFMeasureConstants.sharedInstance().cpdfKm {
            rulerTranslatePopButton.selectItem(withTitle: "km")
        } else if measureInfo.rulerTranslateUnit == CPDFMeasureConstants.sharedInstance().cpdfFt {
            rulerTranslatePopButton.selectItem(withTitle: "ft")
        } else if measureInfo.rulerTranslateUnit == CPDFMeasureConstants.sharedInstance().cpdfYd {
            rulerTranslatePopButton.selectItem(withTitle: "yd")
        } else if measureInfo.rulerTranslateUnit == CPDFMeasureConstants.sharedInstance().cpdfMi {
            rulerTranslatePopButton.selectItem(withTitle: "mi")
        }
        
        precisionPopButton.removeAllItems()
        precisionPopButton.addItems(withTitles: ["1", "0.1", "0.01", "0.001", "0.0001"])
        
        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
        }
        
        rulerBaseTexField.delegate = self
        rulerTranslateTextField.delegate = self
    }
    
    @IBAction func startModal(_ sender: Any) {
        NSApp.stopModal()
        var modalCode: NSApplication.ModalResponse
        modalSession = NSApp.beginModalSession(for: self.window!)
        repeat {
            modalCode = NSApp.runModalSession(modalSession!)
        } while modalCode == .continue
    }
    
    @IBAction func endModal(_ sender: Any) {
        if let modalSession = modalSession {
            NSApp.stopModal()
            NSApp.endModalSession(modalSession)
            self.window?.orderOut(self)
        }
    }
    
    func controlTextDidChange(_ obj: Notification) {
        if rulerBaseTexField.stringValue.count > 6 {
            rulerBaseTexField.stringValue = String(rulerBaseTexField.stringValue.prefix(6))
        } else if rulerTranslateTextField.stringValue.count > 6 {
            rulerTranslateTextField.stringValue = String(rulerTranslateTextField.stringValue.prefix(6))
        }
        
        let rulerBaseText = rulerBaseTexField.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
        var rulerBaseUnit = ""
        switch selectIndex {
        case 0:
            rulerBaseUnit = CPDFMeasureConstants.sharedInstance().cpdfIn
        case 1:
            rulerBaseUnit = CPDFMeasureConstants.sharedInstance().cpdfCm
        case 2:
            rulerBaseUnit = CPDFMeasureConstants.sharedInstance().cpdfMm
        default:
            break
        }
        
        if isDistance {
            distanceMeasureInfo?.rulerBaseUnit = rulerBaseUnit
        } else {
            perimeterMeasureInfo?.rulerBaseUnit = rulerBaseUnit
        }
    }
    
    @IBAction func buttonItemClick_Rulertranslate(_ sender: NSPopUpButton) {
        let selectIndex = sender.indexOfSelectedItem
        var rulerTranslateUnit = ""
        var factor: CGFloat = 0
        switch selectIndex {
        case 0:
            rulerTranslateUnit = CPDFMeasureConstants.sharedInstance().cpdfPt
            factor = CPDFMeasureConstants.sharedInstance().ptPt
        case 1:
            rulerTranslateUnit = CPDFMeasureConstants.sharedInstance().cpdfCm
            factor = CPDFMeasureConstants.sharedInstance().ptCm
        case 2:
            rulerTranslateUnit = CPDFMeasureConstants.sharedInstance().cpdfIn
            factor = CPDFMeasureConstants.sharedInstance().ptIn
        case 3:
            rulerTranslateUnit = CPDFMeasureConstants.sharedInstance().cpdfMm
            factor = CPDFMeasureConstants.sharedInstance().ptMm
        case 4:
            rulerTranslateUnit = CPDFMeasureConstants.sharedInstance().cpdfM
            factor = CPDFMeasureConstants.sharedInstance().ptM
        case 5:
            rulerTranslateUnit = CPDFMeasureConstants.sharedInstance().cpdfKm
            factor = CPDFMeasureConstants.sharedInstance().ptKm
        case 6:
            rulerTranslateUnit = CPDFMeasureConstants.sharedInstance().cpdfFt
            factor = CPDFMeasureConstants.sharedInstance().ptFt
        case 7:
            rulerTranslateUnit = CPDFMeasureConstants.sharedInstance().cpdfYd
            factor = CPDFMeasureConstants.sharedInstance().ptYd
        case 8:
            rulerTranslateUnit = CPDFMeasureConstants.sharedInstance().cpdfMi
            factor = CPDFMeasureConstants.sharedInstance().ptMi
        default:
            break
        }
        
        if isDistance {
            distanceMeasureInfo?.rulerTranslateUnit = rulerTranslateUnit
            distanceMeasureInfo?.factor = factor
        } else {
            perimeterMeasureInfo?.rulerTranslateUnit = rulerTranslateUnit
            perimeterMeasureInfo?.factor = factor
        }
    }
    
    @IBAction func buttonItemClick_Precision(_ sender: NSPopUpButton) {
        let selectIndex = sender.indexOfSelectedItem
        var precision: Int = 0
        switch selectIndex {
        case 0:
            precision = CPDFMeasureConstants.sharedInstance().precisionValueZero
        case 1:
            precision = CPDFMeasureConstants.sharedInstance().precisionValueOne
        case 2:
            precision = CPDFMeasureConstants.sharedInstance().precisionValueTwo
        case 3:
            precision = CPDFMeasureConstants.sharedInstance().precisionValueThree
        case 4:
            precision = CPDFMeasureConstants.sharedInstance().precisionValueFour
        default:
            break
        }
        
        if isDistance {
            distanceMeasureInfo?.precision = precision
        } else {
            perimeterMeasureInfo?.precision = precision
        }
    }
    
    @IBAction func buttonItemClick_Cancel(_ sender: Any) {
        if isDistance {
            delegate?.distanceSettingWindowController?(self, distanceMeasureInfo: nil)
        } else {
            delegate?.distanceSettingWindowController?(self, perimeterMeasureInfo: nil)
        }
        endModal("")
    }
    
    @IBAction func buttonItemClick_Done(_ sender: Any) {
        if isDistance {
            if let distanceMeasureInfo = distanceMeasureInfo {
                distanceMeasureInfo.rulerBase = CGFloat(Float(rulerBaseTexField.stringValue) ?? 0)
                distanceMeasureInfo.rulerTranslate = CGFloat(Float(rulerTranslateTextField.stringValue) ?? 0)
                delegate?.distanceSettingWindowController?(self, distanceMeasureInfo: distanceMeasureInfo)
            }
        } else {
            if let perimeterMeasureInfo = perimeterMeasureInfo {
                perimeterMeasureInfo.rulerBase = CGFloat(Float(rulerBaseTexField.stringValue) ?? 0)
                perimeterMeasureInfo.rulerTranslate = CGFloat(Float(rulerTranslateTextField.stringValue) ?? 0)
                delegate?.distanceSettingWindowController?(self, perimeterMeasureInfo: perimeterMeasureInfo)
            }
        }
        endModal("")
    }

}