//
//  KMDesignButton.swift
//  Cisdem PDFMaster
//
//  Created by wanjun on 2023/2/18.
//

import Cocoa

@objc enum DesignButtonType : Int {
    case Text = 0       // 纯文本按钮
    case Image          // 纯图片按钮
    case TextImage      // 文本+图片按钮,区分图片在上左下右位置
    case PopUpButton    // PopUp按钮
    case RadioButton    // 单选按钮
    case CheckBox       // 多选按钮
}

@objcMembers class KMDesignButton: KMDesignBase {
    
    @IBOutlet weak var mainBox: NSBox!
    @IBOutlet weak var button   : NSButton!
    
    // Text
    @IBOutlet weak var textButtonBox: KMMoveBox!
    @IBOutlet weak var textButtonlabel : NSTextField!
    
    // Image
    @IBOutlet weak var imageButtonBox: KMMoveBox!
    @IBOutlet weak var imageView1: NSImageView!

    // TextImage
    @IBOutlet weak var textImageButtonBox: KMMoveBox!
    @IBOutlet weak var textImage_upView: NSView!
    @IBOutlet weak var textImage_leftView: NSView!
    @IBOutlet weak var textImage_downView: NSView!
    @IBOutlet weak var textImage_rightView: NSView!
    @IBOutlet weak var textImage_upImageView: NSImageView!
    @IBOutlet weak var textImage_leftImageView: NSImageView!
    @IBOutlet weak var textImage_downImageView: NSImageView!
    @IBOutlet weak var textImage_rightImageView: NSImageView!
    @IBOutlet weak var textImage_upTextfield: NSTextField!
    @IBOutlet weak var textImage_leftTextfield: NSTextField!
    @IBOutlet weak var textImage_downTextfield: NSTextField!
    @IBOutlet weak var textImage_rightTextfield: NSTextField!
    @IBOutlet weak var textImage_upPadding_spacing: NSLayoutConstraint!
    @IBOutlet weak var textImage_upImageHeight: NSLayoutConstraint!
    @IBOutlet weak var textImage_upImageWidth: NSLayoutConstraint!
    @IBOutlet weak var textImage_upItem_spacing: NSLayoutConstraint!
    @IBOutlet weak var textImage_leftPadding_spacing: NSLayoutConstraint!
    @IBOutlet weak var textImage_leftImageHeight: NSLayoutConstraint!
    @IBOutlet weak var textImage_leftImageWidth: NSLayoutConstraint!
    @IBOutlet weak var textImage_leftItem_spacing: NSLayoutConstraint!
    @IBOutlet weak var textImage_downPadding_spacing: NSLayoutConstraint!
    @IBOutlet weak var textImage_downImageHeight: NSLayoutConstraint!
    @IBOutlet weak var textImage_downImageWidth: NSLayoutConstraint!
    @IBOutlet weak var textImage_downItem_spacing: NSLayoutConstraint!
    @IBOutlet weak var textImage_rightPadding_spacing: NSLayoutConstraint!
    @IBOutlet weak var textImage_rightImageHeight: NSLayoutConstraint!
    @IBOutlet weak var textImage_rightImageWidth: NSLayoutConstraint!
    @IBOutlet weak var textImage_rightItem_spacing: NSLayoutConstraint!
    
    @IBOutlet weak var radioButton_mainBox: KMMoveBox!
    @IBOutlet weak var radioButton_imageView: NSImageView!
    @IBOutlet weak var radioButton_label: NSTextField!
    
    @IBOutlet weak var radio_label_spacing: NSLayoutConstraint!
    @IBOutlet weak var radio_imageViewWidth: NSLayoutConstraint!
    @IBOutlet weak var radio_imageViewHeight: NSLayoutConstraint!
    
    @IBOutlet weak var mainBoxHeight : NSLayoutConstraint! // mainBox 高度约束
    @IBOutlet weak var mainBoxWidth : NSLayoutConstraint! // mainBox 宽度约束
    var height: Float = 32.0    // 高度
    var width: Float = 80.0    // 宽度
    
    var textImage_imageWidth: Float = 20.0// 图片宽度
    var textImage_imageHeight: Float = 20.0// 图片高度
    var textImage_paddingSpacing: Float = 16.0
    var textImage_itemSpacing: Float = 8.0
    
//    var image: NSImage = NSImage(named: "KMRadioButtonUnSelect")! // imageView 图片
    var radio_imageWidth = 16.0   // 图片宽度
    var radio_imageHeight = 16.0 // 图片高度
    var radio_label = 8.0 // imageView、label 水平间距

    // button 通用属性
    var textImage_type: KMTextImageButtonType = .Left
    var textImage_state: KMDesignTokenState = .Norm
    
    init(withType type: DesignButtonType) {
        super.init(nibName: "KMDesignButton", bundle: nil)
        self.buttonType = type
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        
        if (buttonType == .Text) {
            mainBox.contentView = textButtonBox
        } else if (buttonType == .Image) {
            mainBox.contentView = imageButtonBox
        } else if (buttonType == .TextImage) {
            mainBox.contentView = textImageButtonBox
        } else if (buttonType == .PopUpButton) {
            mainBox.contentView = textImageButtonBox
        } else if (buttonType == .RadioButton) || (buttonType == .CheckBox) {
            mainBox.contentView = radioButton_mainBox
        }
        
        textButtonBox.move =  { [weak self](mouseEntered: Bool) -> Void in
            if self != nil {
                if mouseEntered {
                    if self!.state != .Sel && self!.canHover && (self!.state != .Disabled) && (self!.state != .Act) {
                        self!.state = .Hov
                        self!.updateUI()
                    }
                } else {
                    if self!.state != .Sel && self!.canHover && (self!.state != .Disabled) && (self!.state != .Act) {
                        self!.state = .Norm
                        self!.updateUI()
                    }
                }
            }
        }
        imageButtonBox.move =  { [weak self](mouseEntered: Bool) -> Void in
            if self != nil {
                if mouseEntered {
                    if self!.state != .Sel && self!.canHover && (self!.state != .Disabled) && (self!.state != .Act)  {
                        self!.state = .Hov
                        self!.updateUI()
                    }
                } else {
                    if self!.state != .Sel && self!.canHover && (self!.state != .Disabled) && (self!.state != .Act) {
                        self!.state = .Norm
                        self!.updateUI()
                    }
                }
            }
        }
        textImageButtonBox.move =  { [weak self](mouseEntered: Bool) -> Void in
            if self != nil {
                if mouseEntered {
                    if self!.state != .Sel && self!.canHover && (self!.state != .Disabled) && (self!.state != .Act) {
                        self!.state = .Hov
                        self!.updateUI()
                    }
                } else {
                    if self!.state != .Sel && self!.canHover && (self!.state != .Disabled) && (self!.state != .Act) {
                        self!.state = .Norm
                        self!.updateUI()
                    }
                }
            }
        }
        radioButton_mainBox.move =  { [weak self](mouseEntered: Bool) -> Void in
            if self != nil {
                if mouseEntered {
                    if self!.state != .Checked_dis && self!.canHover && (self!.state != .Disabled) && (self!.state != .Checked) {
                        self!.state = .Hov
                        self!.updateUI()
                    }
                } else {
                    if self!.state != .Checked_dis && self!.canHover && (self!.state != .Disabled) && (self!.state != .Checked) {
                        self!.state = .Norm
                        self!.updateUI()
                    }
                }
            }
        }

//        self.radioButton_mainBox.canHover = true
//        self.radioButton_mainBox.canClick = true
//        radioButton_mainBox.downCallback =  { [weak self](downEntered: Bool, mouseBox: KMBox) -> Void in
//            if self != nil {
//                if self!.enabled {
//                    if downEntered {
//                        self!.canHover = false
//                        self!.state = .Checked
//                        self!.updateUI()
//                    }
//                }
//            }
//        }
//        radioButton_mainBox.moveCallback = { [weak self](mouseEntered: Bool, mouseBox: KMBox) -> Void in
//            if self != nil {
//                if mouseEntered {
//                    if self!.state != .Checked_dis && self!.canHover && (self!.state != .Disabled) && (self!.state != .Checked) {
//                        self!.state = .Hov
//                        self!.updateUI()
//                    }
//                } else {
//                    if self!.state != .Checked_dis && self!.canHover && (self!.state != .Disabled) && (self!.state != .Checked) {
//                        self!.state = .Norm
//                        self!.updateUI()
//                    }
//                }
//            }
//        }
    }
    
    // MARK: Get、Set
    
    var action: Selector {
        get {
            return _action!
        }
        set {
            _action = newValue
            if _action != nil {
                button.action = _action
            }
        }
    }
    
    var target: AnyObject {
        get {
            return _target!
        }
        set {
            _target = newValue
            if _target != nil {
                button.target = _target
            }
        }
    }
    
    var state: KMDesignTokenState {
        get {
            return _state
        }
        set {
            _state = newValue
            updateUI()
        }
    }
    
    var enabled: Bool {
        get {
            return _enabled
        }
        set {
            _enabled = newValue
            self.button.isEnabled = _enabled
            if _enabled {
                state = .Norm
            } else {
                state = .Disabled
            }
            updateUI()
        }
    }
    
    var isHidden: Bool {
        get {
            return _isHidden
        }
        set {
            _isHidden = newValue
            self.view.isHidden = _isHidden
        }
    }

    var image: NSImage {
        get {
            return _image
        }
        set {
            _image = newValue
            updateUI()
        }
    }
    
    var image_hov: NSImage {
        get {
            if _image_hov == nil {
                return _image
            }
            return _image_hov!
        }
        set {
            _image_hov = newValue
            updateUI()
        }
    }
    
    var image_act: NSImage {
        get {
            if _image_act == nil {
                return _image
            }
            return _image_act!
        }
        set {
            _image_act = newValue
            updateUI()
        }
    }
    
    var image_disabled: NSImage {
        get {
            if _image_disabled == nil {
                return _image
            }
            return _image_disabled!
        }
        set {
            _image_disabled = newValue
            updateUI()
        }
    }
    
    var image_sel: NSImage {
        get {
            if (_image_sel == nil) {
                _image_sel = image
            }
            return _image_sel!
        }
        set {
            _image_sel = newValue
            updateUI()
        }
    }
    
    var image_checked: NSImage {
        get {
            if (_image_checked == nil) {
                _image_checked = image
            }
            return _image_checked!
        }
        set {
            _image_checked = newValue
            updateUI()
        }
    }
    
    var image_checkeddis: NSImage {
        get {
            if (_image_checkeddis == nil) {
                _image_checkeddis = image
            }
            return _image_checkeddis!
        }
        set {
            _image_checkeddis = newValue
            updateUI()
        }
    }
    
    var toolTip: String {
        get {
            return _toolTip
        }
        set {
            _toolTip = newValue
            if _toolTip != "" {
                button.toolTip = _toolTip
            }
        }
    }
    
    // MARK: Private Methods

    func updateUI() -> Void {
        if (buttonType == .Text) {
            let paragraphStyle = NSMutableParagraphStyle()
            if (state == .Norm) {
                textButtonBox.fillColor = background
                textButtonBox.borderWidth = CGFloat(borderWidth)
                textButtonBox.cornerRadius = CGFloat(cornerRadius)
                textButtonBox.borderColor = borderColor
                textButtonlabel.textColor = textColor
                textButtonlabel.font = font
                paragraphStyle.lineSpacing = lineHeight
            } else if (state == .Hov) {
                textButtonBox.fillColor = background_hov
                textButtonBox.borderWidth = CGFloat(borderWidth_hov)
                textButtonBox.cornerRadius = CGFloat(cornerRadius_hov)
                textButtonBox.borderColor = borderColor_hov
                textButtonlabel.textColor = textColor_hov
                textButtonlabel.font = font_hov
                paragraphStyle.lineSpacing = lineHeight_hov
            } else if (state == .Act) {
                textButtonBox.fillColor = background_act
                textButtonBox.borderWidth = CGFloat(borderWidth_act)
                textButtonBox.cornerRadius = CGFloat(cornerRadius_act)
                textButtonBox.borderColor = borderColor_act
                textButtonlabel.textColor = textColor_act
                textButtonlabel.font = font_act
                paragraphStyle.lineSpacing = lineHeight_act
            } else if (state == .Disabled) {
                textButtonBox.fillColor = background_disabled
                textButtonBox.borderWidth = CGFloat(borderWidth_disabled)
                textButtonBox.cornerRadius = CGFloat(cornerRadius_disabled)
                textButtonBox.borderColor = borderColor_disabled
                textButtonlabel.textColor = textColor_disabled
                textButtonlabel.font = font_disabled
                paragraphStyle.lineSpacing = lineHeight_disabled
            }
            textButtonlabel.attributedStringValue = NSAttributedString(string: stringValue, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
        } else if (buttonType == .Image) {
            if (state == .Norm) {
                imageButtonBox.fillColor = background
                imageButtonBox.borderWidth = CGFloat(borderWidth)
                imageButtonBox.borderColor = borderColor
                imageButtonBox.cornerRadius = CGFloat(cornerRadius)
                imageView1.image = image
            } else if (state == .Hov) {
                imageButtonBox.fillColor = background_hov
                imageButtonBox.borderWidth = CGFloat(borderWidth_hov)
                imageButtonBox.borderColor = borderColor_hov
                imageButtonBox.cornerRadius = CGFloat(cornerRadius_hov)
                imageView1.image = image_hov
            } else if (state == .Act) {
                imageButtonBox.fillColor = background_act
                imageButtonBox.borderWidth = CGFloat(borderWidth_act)
                imageButtonBox.borderColor = borderColor_act
                imageButtonBox.cornerRadius = CGFloat(cornerRadius_act)
                imageView1.image = image_act
            } else if (state == .Disabled) {
                imageButtonBox.fillColor = background_disabled
                imageButtonBox.borderWidth = CGFloat(borderWidth_disabled)
                imageButtonBox.borderColor = borderColor_disabled
                imageButtonBox.cornerRadius = CGFloat(cornerRadius_disabled)
                imageView1.image = image_disabled
            }
        }  else if (buttonType == .TextImage) {
            let paragraphStyle = NSMutableParagraphStyle()
            if textImage_type == .Up {
                textImageButtonBox.contentView = textImage_upView
                textImage_upTextfield.isEditable = editable
                textImage_upTextfield.font = font
            } else if textImage_type == .Left {
                textImageButtonBox.contentView = textImage_leftView
                textImage_leftTextfield.isEditable = editable
                textImage_leftTextfield.font = font
            } else if textImage_type == .Down {
                textImageButtonBox.contentView = textImage_downView
                textImage_downTextfield.isEditable = editable
                textImage_downTextfield.font = font
            } else if textImage_type == .Right {
                textImageButtonBox.contentView = textImage_rightView
                textImage_rightTextfield.isEditable = editable
                textImage_rightTextfield.font = font
            }
            
            if textImage_state == .Norm {
                textImageButtonBox.fillColor = background
                textImageButtonBox.borderColor = borderColor
                if textImage_type == .Up {
                    textImage_upImageView.image = image
                    textImage_upTextfield.textColor = textColor
                } else if textImage_type == .Left {
                    textImage_leftImageView.image = image
                    textImage_leftTextfield.textColor = textColor
                } else if textImage_type == .Down {
                    textImage_downImageView.image = image
                    textImage_downTextfield.textColor = textColor
                } else if textImage_type == .Right {
                    textImage_rightImageView.image = image
                    textImage_rightTextfield.textColor = textColor
                }
                
                textImageButtonBox.borderWidth = CGFloat(borderWidth)
                textImageButtonBox.cornerRadius = CGFloat(cornerRadius)
                paragraphStyle.lineSpacing = lineHeight
            } else if state == .Hov {
                textImageButtonBox.fillColor = background_hov
                textImageButtonBox.borderColor = borderColor_hov
                if textImage_type == .Up {
                    textImage_upImageView.image = image_hov
                    textImage_upTextfield.textColor = textColor_hov
                } else if textImage_type == .Left {
                    textImage_leftImageView.image = image_hov
                    textImage_leftTextfield.textColor = textColor_hov
                } else if textImage_type == .Down {
                    textImage_downImageView.image = image_hov
                    textImage_downTextfield.textColor = textColor_hov
                } else if textImage_type == .Right {
                    textImage_rightImageView.image = image_hov
                    textImage_rightTextfield.textColor = textColor_hov
                }
                textImageButtonBox.borderWidth = CGFloat(borderWidth_hov)
                textImageButtonBox.cornerRadius = CGFloat(cornerRadius_hov)
                paragraphStyle.lineSpacing = lineHeight_hov
            } else if state == .Act {
                textImageButtonBox.fillColor = background_act
                textImageButtonBox.borderColor = borderColor_act
                if textImage_type == .Up {
                    textImage_upImageView.image = image_act
                    textImage_upTextfield.textColor = textColor_act
                } else if textImage_type == .Left {
                    textImage_leftImageView.image = image_act
                    textImage_leftTextfield.textColor = textColor_act
                } else if textImage_type == .Down {
                    textImage_downImageView.image = image_act
                    textImage_downTextfield.textColor = textColor_act
                } else if textImage_type == .Right {
                    textImage_rightImageView.image = image_act
                    textImage_rightTextfield.textColor = textColor_act
                }
                textImageButtonBox.borderWidth = CGFloat(borderWidth_act)
                textImageButtonBox.cornerRadius = CGFloat(cornerRadius_act)
                paragraphStyle.lineSpacing = lineHeight_act
            } else if state == .Disabled {
                textImageButtonBox.fillColor = background_disabled
                textImageButtonBox.borderColor = borderColor_disabled
                if textImage_type == .Up {
                    textImage_upImageView.image = image_disabled
                    textImage_upTextfield.textColor = textColor_disabled
                } else if textImage_type == .Left {
                    textImage_leftImageView.image = image_disabled
                    textImage_leftTextfield.textColor = textColor_disabled
                } else if textImage_type == .Down {
                    textImage_downImageView.image = image_disabled
                    textImage_downTextfield.textColor = textColor_disabled
                } else if textImage_type == .Right {
                    textImage_rightImageView.image = image_disabled
                    textImage_rightTextfield.textColor = textColor_disabled
                }
                textImageButtonBox.borderWidth = CGFloat(borderWidth_disabled)
                textImageButtonBox.cornerRadius = CGFloat(cornerRadius_disabled)
                paragraphStyle.lineSpacing = lineHeight_disabled
            }
            
            textImage_upImageHeight.constant = CGFloat(textImage_imageHeight)
            textImage_upImageWidth.constant = CGFloat(textImage_imageWidth)
            textImage_leftImageHeight.constant = CGFloat(textImage_imageHeight)
            textImage_leftImageWidth.constant = CGFloat(textImage_imageWidth)
            textImage_downImageHeight.constant = CGFloat(textImage_imageHeight)
            textImage_downImageWidth.constant = CGFloat(textImage_imageWidth)
            textImage_rightImageHeight.constant = CGFloat(textImage_imageHeight)
            textImage_rightImageWidth.constant = CGFloat(textImage_imageWidth)
            
            if textImage_type == .Up {
                textImage_upTextfield.attributedStringValue = NSAttributedString(string: stringValue, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
                textImage_upPadding_spacing.constant = CGFloat(textImage_paddingSpacing)
                textImage_upItem_spacing.constant = CGFloat(textImage_itemSpacing)
            } else if textImage_type == .Left {
                textImage_leftTextfield.attributedStringValue = NSAttributedString(string: stringValue, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
                textImage_leftPadding_spacing.constant = CGFloat(textImage_paddingSpacing)
                textImage_leftItem_spacing.constant = CGFloat(textImage_itemSpacing)
            } else if textImage_type == .Down {
                textImage_downTextfield.attributedStringValue = NSAttributedString(string: stringValue, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
                textImage_downPadding_spacing.constant = CGFloat(textImage_paddingSpacing)
                textImage_downItem_spacing.constant = CGFloat(textImage_itemSpacing)
            } else if textImage_type == .Right {
                textImage_rightTextfield.attributedStringValue = NSAttributedString(string: stringValue, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
                textImage_rightPadding_spacing.constant = CGFloat(textImage_paddingSpacing)
                textImage_rightItem_spacing.constant = CGFloat(textImage_itemSpacing)
            }
        } else if (buttonType == .RadioButton) || (buttonType == .CheckBox) {
            let paragraphStyle = NSMutableParagraphStyle()
            if (state == .Norm) {
                if (buttonType == .RadioButton) {
                    radioButton_imageView.image = NSImage(named: "KMRadioButtonUnSelect")
                } else {
                    radioButton_imageView.image = NSImage(named: "icon_btn_checkbox_unsel")
                }
                radioButton_label.font = font
                radioButton_label.textColor = textColor
                paragraphStyle.lineSpacing = lineHeight
            } else if (state == .Hov) {
                if (buttonType == .RadioButton) {
                    radioButton_imageView.image = NSImage(named: "KMRadioButtonHov")
                } else {
                    radioButton_imageView.image = NSImage(named: "icon_btn_checkbox_hov")
                }
                radioButton_label.font = font_hov
                radioButton_label.textColor = textColor_hov
                paragraphStyle.lineSpacing = lineHeight_hov
            } else if (state == .Disabled) {
                if (buttonType == .RadioButton) {
                    radioButton_imageView.image = NSImage(named: "KMRadioButtonUnSel_Disabled")
                } else {
                    radioButton_imageView.image = NSImage(named: "icon_btn_checkbox_unsel_Disabled")
                }
                radioButton_label.font = font_disabled
                radioButton_label.textColor = textColor_disabled
                paragraphStyle.lineSpacing = lineHeight_disabled
            } else if (state == .Checked) {
                if (buttonType == .RadioButton) {
                    radioButton_imageView.image = NSImage(named: "KMRadioButtonSelect")
                } else {
                    radioButton_imageView.image = NSImage(named: "icon_btn_checkbox_sel")
                }
                radioButton_label.font = font_checked
                radioButton_label.textColor = textColor_checked
                paragraphStyle.lineSpacing = lineHeight_checked
            } else if (state == .Checked_dis) {
                if (buttonType == .RadioButton) {
                    radioButton_imageView.image = NSImage(named: "KMRadioButtonSel_Disabled")
                } else {
                    radioButton_imageView.image = NSImage(named: "icon_btn_checkbox_sel_Disabled")
                }
                radioButton_label.font = font_checkeddis
                radioButton_label.textColor = textColor_checkeddis
                paragraphStyle.lineSpacing = lineHeight_checkeddis
            }
            radioButton_label.attributedStringValue = NSAttributedString(string: stringValue, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])

            radio_label_spacing.constant = radio_label
            radio_imageViewWidth.constant = radio_imageWidth
            radio_imageViewHeight.constant = radio_imageHeight
        }
    }
}