//
//  KMGeneralAnnotationViewController.swift
//  PDF Master
//
//  Created by wanjun on 2023/12/1.
//

import Cocoa

/**
 NSString *SKNFreeTextString = @"FreeText";
 NSString *SKNTextString = @"Text";
 NSString *SKNNoteString = @"Note";
 NSString *SKNCircleString = @"Circle";
 NSString *SKNSquareString = @"Square";
 NSString *SKNMarkUpString = @"MarkUp";
 NSString *SKNHighlightString = @"Highlight";
 NSString *SKNUnderlineString = @"Underline";
 NSString *SKNStrikeOutString = @"StrikeOut";
 NSString *SKNLineString = @"Line";
 NSString *SKNInkString = @"Ink";

 NSString *SKNPDFAnnotationTypeKey = @"type";
 NSString *SKNPDFAnnotationBoundsKey = @"bounds";
 NSString *SKNPDFAnnotationPageKey = @"page";
 NSString *SKNPDFAnnotationPageIndexKey = @"pageIndex";
 NSString *SKNPDFAnnotationContentsKey = @"contents";
 NSString *SKNPDFAnnotationStringKey = @"string";
 NSString *SKNPDFAnnotationColorKey = @"color";
 NSString *SKNPDFAnnotationBorderKey = @"border";
 NSString *SKNPDFAnnotationLineWidthKey = @"lineWidth";
 NSString *SKNPDFAnnotationBorderStyleKey = @"borderStyle";
 NSString *SKNPDFAnnotationDashPatternKey = @"dashPattern";
 NSString *SKNPDFAnnotationModificationDateKey = @"modificationDate";
 NSString *SKNPDFAnnotationUserNameKey = @"userName";

 NSString *SKNPDFAnnotationInteriorColorKey = @"interiorColor";

 NSString *SKNPDFAnnotationStartLineStyleKey = @"startLineStyle";
 NSString *SKNPDFAnnotationEndLineStyleKey = @"endLineStyle";
 NSString *SKNPDFAnnotationStartPointKey = @"startPoint";
 NSString *SKNPDFAnnotationEndPointKey = @"endPoint";

 NSString *SKNPDFAnnotationFontKey = @"font";
 NSString *SKNPDFAnnotationFontColorKey = @"fontColor";
 NSString *SKNPDFAnnotationFontNameKey = @"fontName";
 NSString *SKNPDFAnnotationFontSizeKey = @"fontSize";
 NSString *SKNPDFAnnotationAlignmentKey = @"alignment";
 NSString *SKNPDFAnnotationRotationKey = @"rotation";

 NSString *SKNPDFAnnotationQuadrilateralPointsKey = @"quadrilateralPoints";

 NSString *SKNPDFAnnotationIconTypeKey = @"iconType";

 NSString *SKNPDFAnnotationPointListsKey = @"pointLists";
 */

enum KMActiveAnnotationType: UInt {
    case highlight = 0
    case strikeOut
    case underline
    case inkAndLine
    case text
    case squareAndCircle
    case freeText
    case selfSignFreeText
}

enum KMFreeTextAnnotationAlignmentType: UInt {
    case left = 0
    case center
    case right
}

let KMColorPickerViewHeight: CGFloat = 64

@objcMembers class KMGeneralAnnotationViewController: NSViewController, NSTextViewDelegate {
    
    var _annotations: [CPDFAnnotation]?
    var subType: KMSelfSignAnnotationFreeTextSubType = .none
    var _activeAnnotationType: KMActiveAnnotationType = .highlight
    var pdfView: CPDFListView?
    var annotationModel: CPDFAnnotationModel?
//    var annotationCallback: ((CPDFAnnotation) -> Void)?
    
    @IBOutlet private weak var imageBox: NSBox!
    @IBOutlet private weak var imageBoxLayoutConstraint: NSLayoutConstraint!

    @IBOutlet private weak var textImageBoxView: NSView!
    @IBOutlet private weak var textImageBox: KMBox!
    @IBOutlet private weak var textAnnotationImageView: NSImageView!
    @IBOutlet private weak var textImageBoxButton: NSButton!
    @IBOutlet private weak var textImageUpDateButton: NSButton!

    @IBOutlet private weak var generalImageBoxView: NSView!
    @IBOutlet private weak var generalImageView: NSImageView!

    @IBOutlet private weak var fontView: NSView!  // 字体
    @IBOutlet private weak var fontLabel: NSTextField!
    @IBOutlet private weak var fontButton: NSButton!
    @IBOutlet private weak var fontPopUpButton: KMPopUpButton!
    @IBOutlet private weak var fontSizeComboBox: KMComboBox!
    @IBOutlet private weak var fontStylePopUpButton: KMPopUpButton!
    @IBOutlet private weak var leftAlignButton: NSButton!
    @IBOutlet private weak var centerAlignButton: NSButton!
    @IBOutlet private weak var rightAlignButton: NSButton!
    @IBOutlet private weak var fontViewTopConstant: NSLayoutConstraint!

    @IBOutlet private weak var fontViewCorloPV: KMColorPickerView!
    @IBOutlet private weak var fontViewColorPVConstraint: NSLayoutConstraint!

    @IBOutlet private weak var rotateView: NSView!  // 旋转
    @IBOutlet private weak var rotateLabel: NSTextField!
    @IBOutlet private weak var leftRotateBox: KMBox!
    @IBOutlet private weak var leftRotateButton: NSButton!
    @IBOutlet private weak var rightRotateBox: KMBox!
    @IBOutlet private weak var rightRotateButton: NSButton!
    @IBOutlet private weak var rotateViewTopConstant: NSLayoutConstraint!

    @IBOutlet private weak var typeView: NSView!  // 类型
    @IBOutlet private weak var typeLabel: NSTextField!
    @IBOutlet private weak var tureTypeButton: NSButton!
    @IBOutlet private weak var falseTypeButton: NSButton!
    @IBOutlet private weak var circletypeButton: NSButton!
    @IBOutlet private weak var lineTypeButton: NSButton!
    @IBOutlet private weak var dotTypeButton: NSButton!
    @IBOutlet private weak var typeViewTopConstant: NSLayoutConstraint!

    @IBOutlet private weak var dateView: NSView!  // 日期
    @IBOutlet private weak var dateLabel: NSTextField!
    @IBOutlet private weak var datePopUpButton: KMPopUpButton!
    @IBOutlet private weak var dateCheckButton: NSButton!
    @IBOutlet private weak var dateViewTopConstant: NSLayoutConstraint!

    @IBOutlet private weak var iconView: NSView!  // 图标
    @IBOutlet private weak var iconLabel: NSTextField!
    @IBOutlet private weak var commentBox: NSBox!
    @IBOutlet private weak var commentButton: NSButton!
    @IBOutlet private weak var noteBox: NSBox!
    @IBOutlet private weak var noteButton: NSButton!
    @IBOutlet private weak var keyBox: NSBox!
    @IBOutlet private weak var keyButton: NSButton!
    @IBOutlet private weak var helpBox: NSBox!
    @IBOutlet private weak var helpButton: NSButton!
    @IBOutlet private weak var paragraphBox: NSBox!
    @IBOutlet private weak var paragraphButton: NSButton!
    @IBOutlet private weak var insertBox: NSBox!
    @IBOutlet private weak var insertButton: NSButton!
    @IBOutlet private weak var addParagraphBox: NSBox!
    @IBOutlet private weak var addParagraphButton: NSButton!
    @IBOutlet private weak var iconViewTopConstant: NSLayoutConstraint!
    @IBOutlet private weak var iconButtonHeightConstant: NSLayoutConstraint!

    @IBOutlet private weak var borderAndLineView: NSView!  // 边框
    @IBOutlet private weak var borderLabel: NSTextField!
    @IBOutlet private weak var borderButton: NSButton!
    @IBOutlet private weak var lineWidthComboBox: KMComboBox!
    @IBOutlet private weak var lineWidthSlider: NSSlider!
    @IBOutlet private weak var lineTypeLabel: NSTextField!
    @IBOutlet private weak var lineStyleButton: KMButton!
    @IBOutlet private weak var dottedLineStyleButton: KMButton!
    @IBOutlet private weak var rightArrowStyleButton: KMButton!

    @IBOutlet private weak var lineStyleBox: NSBox!
    @IBOutlet private weak var dottedLineStyleBox: NSBox!
    @IBOutlet private weak var rightArrowStyleBox: NSBox!

    @IBOutlet private weak var borderViewTopConstant: NSLayoutConstraint!

    @IBOutlet private weak var fillColorView: NSView!
    @IBOutlet private weak var fillColorLabel: NSTextField!
    @IBOutlet private weak var fillColorPickerView: KMColorPickerView!
    @IBOutlet private weak var fillColorViewTopConstraint: NSLayoutConstraint!

    @IBOutlet private weak var opacityView: NSView!  // 透明度
    @IBOutlet private weak var opacityLabel: NSTextField!
    @IBOutlet private weak var opacitySlider: NSSlider!
    @IBOutlet private weak var opacityComboBox: KMComboBox!
    @IBOutlet private weak var opacityViewTopConstant: NSLayoutConstraint!

    @IBOutlet private weak var noteView: NSView!  // 笔记
    @IBOutlet private weak var noteViewLabel: NSTextField!
    @IBOutlet private var noteTextView: NSTextView!
    @IBOutlet private weak var noteViewTopConstant: NSLayoutConstraint!

    @IBOutlet private weak var colorView: NSView!  // 颜色
    @IBOutlet private weak var colorTitleLabel: NSTextField!
    @IBOutlet private weak var textColorBox: NSBox!
    @IBOutlet private weak var textColorBoxConstraint: NSLayoutConstraint!
    @IBOutlet private weak var textColorPickerView: KMColorPickerView!
    @IBOutlet private weak var borderColorBox: NSBox!
    @IBOutlet private weak var borderColorPickerView: KMColorPickerView!
    @IBOutlet private weak var borderColorBoxConstraint: NSLayoutConstraint!
    @IBOutlet private weak var lineWidthBox: NSBox!
    @IBOutlet private weak var widthLabel: NSTextField!
    @IBOutlet private weak var widthComboBox: KMComboBox!
    @IBOutlet private weak var widthSlider: NSSlider!
    @IBOutlet private weak var ColorViewTopConstant: NSLayoutConstraint!
    @IBOutlet private weak var textColorPickerViewConstant: NSLayoutConstraint!

    var isannotationMode: Bool = false
    var selectedAlignmentButtonLayer: CALayer?
    var iconButtonArray: [NSBox] = []
    var lineStyleCount: Int = 0
    var isTextEdit: Bool = false
    var fonts: [[String : [String]]]!
    
    var noteIcons: [NSImage?] = [nil, nil, nil, nil, nil, nil, nil]
    
    private func makeNoteIcons() {
        if noteIcons[0] != nil { return }

        let bounds = CGRect(origin: .zero, size: NSMakeSize(16, 16))
        let annotation = CPDFTextAnnotation()
        annotation.bounds = bounds
        annotation.color = NSColor.clear
        let page = CPDFPage()
        page.setBounds(bounds, for: .mediaBox)
        page.addAnnotation(annotation)

        for i in 0..<7 {
            annotation.setIconType(CPDFTextAnnotationIconType(rawValue: i) ?? .comment)
            noteIcons[i] = NSImage.bitmapImage(with: NSMakeSize(16, 16), drawingHandler: { rect in
                page.draw(with: .mediaBox, to: (NSGraphicsContext.current?.cgContext))
            })
        }
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
        if ((annotationModel?.annotation) != nil) && annotationModel?.annotations.count == 1 {
            let keys = ["contents", "markupText"]
            for key in keys {
                annotationModel?.annotation.removeObserver(self, forKeyPath: key)
            }
        }

        textColorPickerView.target = nil
        textColorPickerView.action = nil
        borderColorPickerView.target = nil
        borderColorPickerView.action = nil
        fillColorPickerView.target = nil
        fillColorPickerView.action = nil
        
        NSColorPanel.shared.setTarget(nil)
        NSColorPanel.shared.setAction(nil)
    }
    
    // MARK: View Methods
    
    override func loadView() {
        super.loadView()
        
        DispatchQueue.main.async {
            if NSColorPanel.shared.isVisible {
                NSColorPanel.shared.close()
            }
        }
        
        isannotationMode = true
        
        fonts = (CPDFAnnotationModel.supportFonts() as! [[String : [String]]])
        
        imageBox.borderColor = KMAppearance.Interactive.s0Color()
        imageBox.borderWidth = 1.0
        imageBox.fillColor = KMAppearance.Layout.l1Color()
        textImageBox.fillColor = KMAppearance.Layout.l1Color()
        fontLabel.stringValue = NSLocalizedString("Fonts", comment: "")
        fontLabel.textColor = KMAppearance.Layout.h0Color()
        colorTitleLabel.stringValue = NSLocalizedString("Color", comment: "")
        colorTitleLabel.textColor = KMAppearance.Layout.h0Color()
        opacityLabel.stringValue = NSLocalizedString("Opacity", comment: "")
        opacityLabel.textColor = KMAppearance.Layout.h1Color()
        noteViewLabel.stringValue = NSLocalizedString("Note", comment: "")
        noteViewLabel.textColor = KMAppearance.Layout.h0Color()
        rotateLabel.stringValue = NSLocalizedString("Rotate", comment: "")
        rotateLabel.textColor = KMAppearance.Layout.h0Color()
        typeLabel.stringValue = NSLocalizedString("Type", comment: "")
        typeLabel.textColor = KMAppearance.Layout.h0Color()
        dateLabel.stringValue = NSLocalizedString("Date", comment: "")
        dateLabel.textColor = KMAppearance.Layout.h0Color()
        iconLabel.stringValue = NSLocalizedString("Icon", comment: "")
        iconLabel.textColor = KMAppearance.Layout.h0Color()
        borderLabel.stringValue = NSLocalizedString("Line and Border Style", comment: "")
        borderLabel.textColor = KMAppearance.Layout.h0Color()
        fillColorLabel.stringValue = NSLocalizedString("Fill", comment: "")
        fillColorLabel.textColor = KMAppearance.Layout.h0Color()
        
        lineStyleCount = 0
        
        if annotationType == .highlight {
            activeAnnotationType = .highlight
        } else if annotationType == .strikeOut {
            activeAnnotationType = .strikeOut
        } else if annotationType == .underline {
            activeAnnotationType = .underline
        } else if annotationType == .ink || annotationType == .line || annotationType == .arrow {
            activeAnnotationType = .inkAndLine
        } else if annotationType == .anchored {
            activeAnnotationType = .text
        } else if annotationType == .circle || annotationType == .square {
            borderColorPickerView.isCallColorPanelAction = isannotationMode
            textColorPickerView.isCallColorPanelAction = isannotationMode
            activeAnnotationType = .squareAndCircle
        } else if annotationType == .freeText {
            if subType == .date {
                colorTitleLabel.stringValue = NSLocalizedString("Fill Color", comment: "")
                activeAnnotationType = .selfSignFreeText
            } else {
                activeAnnotationType = .freeText
            }
            
            fontViewCorloPV.isCallColorPanelAction = isannotationMode
            
            var alignmentType: KMFreeTextAnnotationAlignmentType = .left
            if annotationModel?.alignment() == .left {
                alignmentType = .left
            } else if annotationModel?.alignment() == .center {
                alignmentType = .center
            } else if annotationModel?.alignment() == .right {
                alignmentType = .right
            }
            alignmentTypeSelected(alignmentType)
        }
        
        textColorPickerView.isCallColorPanelAction = isannotationMode
        borderColorPickerView.isCallColorPanelAction = isannotationMode
        
        if annotationType == .freeText {
            fontViewCorloPV.isFreeText = true
        } else {
            fontViewCorloPV.isFreeText = false
        }
        
        if annotationType == .ink || annotationType == .line || annotationType == .arrow || annotationType == .square || annotationType == .circle {
            let lineType = annotationModel?.style()
            if lineType == .dashed {
                let lineType = annotationModel?.dashPattern()
//                if lineType.count == 0 {
//                    let number = NSNumber(value: Float(4))
//                    annotation.setDashPattern([number])
//                    
//                    let userDefaults = UserDefaults.standard
//                    if annotationType == .ink {
//                        userDefaults.set(annotationModel?.dashPattern(), forKey: SKInkNoteDashPatternKey)
//                    } else if annotationType == .line {
//                        userDefaults.set(annotationModel?.dashPattern(), forKey: SKLineNoteDashPatternKey)
//                    } else if annotationType == .square {
//                        userDefaults.set(annotationModel?.dashPattern(), forKey: SKSquareNoteDashPatternKey)
//                    } else if annotationType == .circle {
//                        userDefaults.set(annotationModel?.dashPattern(), forKey: SKCircleNoteDashPatternKey)
//                    } else if annotationType == .freeText {
//                        userDefaults.set(annotationModel?.dashPattern(), forKey: CFreeTextNoteDashPatternKey)
//                    }
//                }
            }
        }
        
        opacityComboBox.type = .none
        opacityComboBox.comboxRect = opacityComboBox.bounds
        
        lineWidthComboBox.type = .none
        lineWidthComboBox.comboxRect = lineWidthComboBox.bounds
        
        widthComboBox.type = .none
        widthComboBox.comboxRect = widthComboBox.bounds
        
        fontPopUpButton.type = .arrowDown
        fontSizeComboBox.type = .none
        fontSizeComboBox.comboxRect = fontSizeComboBox.bounds
        
        fontStylePopUpButton.type = .arrowUpDown
        datePopUpButton.type = .arrowUpDown
        
        noteTextView.backgroundColor = KMAppearance.Layout.l1Color()
        
        let views: [NSView] = [fontPopUpButton, fontSizeComboBox, fontStylePopUpButton, lineWidthComboBox, opacityComboBox, widthComboBox, datePopUpButton, noteTextView]
        for view in views {
            view.wantsLayer = true
            view.layer?.borderWidth = 1.0
            view.layer?.cornerRadius = 1.0
        }
        
        refreshLineTypeUI()
        rightArrowStyleButton.isHidden = true
        rightArrowStyleBox.isHidden = true
        
        annotationFontReload()
        reloadData()
        updateViewColor()
        
        if ((annotationModel?.annotation) != nil) && annotationModel?.annotations.count == 1 {
            let annotation = annotationModel?.annotation
            let keys = ["contents", "markupText"]
            for key in keys {
                annotation?.addObserver(self, forKeyPath: key, options: [.new, .old], context: nil)
            }
        }
//        NotificationCenter.default.addObserver(self, selector: #selector(alignmentTypeNotification(_:)), name: "KMAnnotationAlignmentTypeNotification1", object: nil)
//        NotificationCenter.default.addObserver(self, selector: #selector(loadingUIAndLocalization(_:)), name: "KMPreferenceDidChangeNotificationName", object: nil)
//        NotificationCenter.default.addObserver(self, selector: #selector(annotationChangeNotification(_:)), name: CPDFListViewAnnotationsAttributeHasChangeNotification, object: nil)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
    }
    
    override func viewDidAppear() {
        super.viewDidAppear()
        
        let showConvertDetails = KMPropertiesViewPopController.showChangeColorDetails()
        let fileURL = (self.view.window?.windowController?.document as? NSDocument)?.fileURL
        if showConvertDetails && (fileURL != nil)  {
            KMPropertiesViewPopController.defaultManager().showChangeColorDetailsView(self.textColorPickerView.firstButton)
        }
    }
    
    func reloadData() {
        var annotationColor = annotationModel?.color()
        if annotationType == .signFalse ||
            annotationType == .signTure ||
            annotationType == .signDot ||
            annotationType == .signCircle ||
            annotationType == .signLine {
            annotationColor = annotationModel?.color()
        } else if annotationType == .square ||
                    annotationType == .circle {
            annotationColor = annotationModel?.color()
        } else if annotationType == .freeText || annotationType == .signDate || annotationType == .signText {
            annotationColor = annotationModel?.interiorColor()
        } else {
            annotationColor = annotationModel?.color()
        }
        guard let color = annotationColor else { return }
        var opacity: CGFloat = 1.0
        color.usingColorSpaceName(.calibratedRGB)?.getRed(nil, green: nil, blue: nil, alpha: &opacity)
        if annotationType == .signFalse ||
            annotationType == .signTure ||
            annotationType == .signDot ||
            annotationType == .signCircle ||
            annotationType == .signLine {
            opacity = (annotationModel?.opacity())!
        } else if annotationType == .square ||
                    annotationType == .circle {
            opacity = (annotationModel?.opacity())!
        } else if annotationType == .freeText || annotationType == .signDate || annotationType == .signText {
            opacity = (annotationModel?.interiorOpacity())!
        } else {
            opacity = (annotationModel?.opacity())!
        }

        
        opacitySlider.floatValue = Float(opacity)
        opacitySlider.toolTip = "\(Int(opacity * 100))%"
        opacityComboBox.stringValue = "\(Int(opacity * 100))%"
        
        if annotationModel?.annotations != nil {
            let contextString = annotation.string() ?? ""
            noteTextView.string = contextString
            noteTextView.textColor = NSColor.labelColor
            noteTextView.delegate = self
        }
        
        if annotationType == .freeText {
            imageBox.contentView = textImageBoxView
            textAnnotationImageView.image = annotationModel?.annotationImage
        } else if annotationType == .signText || annotationType == .signDate {
            imageBox.contentView = generalImageBoxView
            generalImageView.image = annotationModel?.annotationImage
        } else {
            imageBox.contentView = generalImageBoxView
            generalImageView.image = annotationModel?.annotationImage
        }
        
        if annotationType == .square || annotationType == .circle || annotationType == .line || annotationType == .arrow || annotationType == .ink {
            if annotationType == .ink {
                textColorPickerView.setColor(color)
            } else if annotationType == .square || annotationType == .circle {
                var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
                let modelColor = annotationModel?.interiorColor() ?? .black
                modelColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
                let interiorColor = NSColor(red: red, green: green, blue: blue, alpha: (annotationModel?.interiorOpacity())!)
                
                textColorPickerView.setColor(interiorColor)
                textColorPickerView.isFillColor = true
                borderColorPickerView.setColor(color)
            } else if annotationType == .line || annotationType == .arrow {
                var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
                let modelColor = annotationModel?.interiorColor() ?? .black
                modelColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
                let interiorColor = NSColor(red: red, green: green, blue: blue, alpha: (annotationModel?.interiorOpacity())!)

                textColorPickerView.setColor(interiorColor)
                textColorPickerView.isFillColor = true
                borderColorPickerView.setColor(color)
            }
            lineWidthSlider.floatValue = Float(annotationModel?.lineWidth() ?? 1.0)
            lineWidthSlider.toolTip = "\(annotationModel?.lineWidth() ?? 1.0) pt"
            lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
        } else if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
            if annotationType == .signText || annotationType == .signDate {
                if subType == .date {
                    dateView.isHidden = false
                    datePopUpButton.removeAllItems()
                    let freeText = annotation as! KMSelfSignAnnotationFreeText
    //                    self.datePopUpButton.addItems(withTitles: KMSelfSignAnnotationFreeText.fetchAllDateString(includeTime: <#T##Bool#>))
                    if freeText.dateFormatIndex >= 0, freeText.dateFormatIndex < datePopUpButton.numberOfItems {
                        datePopUpButton.selectItem(at: freeText.dateFormatIndex)
                    } else {
                        datePopUpButton.selectItem(at: 0)
                    }
                    dateCheckButton.state = freeText.includeTime ? NSControl.StateValue.on : NSControl.StateValue.off
                    textColorPickerView.setColor(annotation.color)
                }
            } else {
                lineWidthSlider.minValue = 0.0
                lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
                lineWidthSlider.toolTip = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
                lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
                var alignmentType: KMFreeTextAnnotationAlignmentType = .left
                if annotationModel?.alignment() == .left {
                    alignmentType = .left
                } else if annotationModel?.alignment() == .center {
                    alignmentType = .center
                } else if annotationModel?.alignment() == .right {
                    alignmentType = .right
                }
                alignmentTypeSelected(alignmentType)
                annotationFontReload()
                fillColorPickerView.color = annotationModel?.color()
            }
            fontViewCorloPV.color = annotationModel?.fontColor()
            fontSizeComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.fontSize())!)
        } else if annotationType == .highlight || annotationType == .strikeOut || annotationType == .underline || annotationType == .anchored {
            textColorPickerView.setColor(color)
        }
        
        noteView.isHidden = isannotationMode
        
        if annotationType == .signText || annotationType == .signDate {
            if subType == .date {
                noteView.isHidden = true
            } else {
                noteView.isHidden = false
            }
        }
        
        if annotationModel?.annotations != nil {
            noteView.isHidden = annotationModel?.annotation==nil
        } else {
            if annotationType == .stamp ||
                annotationType == .ink ||
                annotationType == .square ||
                annotationType == .circle ||
                annotationType == .arrow ||
                annotationType == .line ||
                annotationType == .highlight ||
                annotationType == .strikeOut ||
                annotationType == .underline ||
                annotationType == .freeText {
                noteView.isHidden = true
            } else {
                noteView.isHidden = annotationModel?.annotation==nil
            }
        }
    }
    
    // MARK: Set & Get
    
    var annotations: [CPDFAnnotation] {
        get {
            return annotationModel?.annotations as! [CPDFAnnotation]
        }
    }
    
    var annotation: CPDFAnnotation {
        get {
            return (annotationModel?.annotation)!
        }
    }
    
    var annotationType: CAnnotationType {
        get {
            return (annotationModel?.annotationType as? CAnnotationType)!
        }
    }
    
    func updateannotationMode() {
        let defaults = UserDefaults.standard
        if annotationType == .freeText {
//            if ([annotation isKindOfClass:[SKNPDFAnnotationNote class]]) {
//                [sud setColor:self.annotation.color forKey:SKNPDFAnnotationColorKey];
//                [sud setInteger:self.annotation.iconType forKey:SKAnchoredNoteIconTypeKey];
//            }
            if annotation.isKind(of: CPDFFreeTextAnnotation.self) {
                defaults.setColor(annotation.color, forKey: CFreeTextNoteColorKey)
                defaults.setColor((annotation as! CPDFFreeTextAnnotation).fontColor, forKey: CFreeTextNoteFontColorKey)
                defaults.set((annotation as! CPDFFreeTextAnnotation).alignment, forKey: CFreeTextNoteFontNameKey)
                defaults.set((annotation as! CPDFFreeTextAnnotation).fontName(), forKey: CFreeTextNoteFontNameKey)
                defaults.set((annotation as! CPDFFreeTextAnnotation).fontSize(), forKey: CFreeTextNoteFontSizeKey)
                defaults.set(annotation.lineWidth(), forKey: CFreeTextNoteLineWidthKey)
                defaults.set(annotation.borderStyle(), forKey: CFreeTextNoteLineStyleKey)
                defaults.set(annotation.dashPattern(), forKey: CFreeTextNoteDashPatternKey)
            }
        } else if annotationType == .circle {
            defaults.setColor(annotation.color, forKey: CCircleNoteColorKey)
            defaults.setColor((annotation as! CPDFCircleAnnotation).interiorColor, forKey: CCircleNoteInteriorColorKey)
            defaults.set(annotation.lineWidth(), forKey: CCircleNoteLineWidthKey)
            defaults.set((annotation as! CPDFCircleAnnotation).borderStyle(), forKey: CCircleNoteLineStyleKey)
            defaults.set((annotation as! CPDFCircleAnnotation).dashPattern(), forKey: CCircleNoteDashPatternKey)
        } else if annotationType == .square {
            defaults.setColor(annotation.color, forKey: CSquareNoteColorKey)
            defaults.setColor((annotation as! CPDFSquareAnnotation).interiorColor, forKey: CSquareNoteInteriorColorKey)
            defaults.set(annotation.lineWidth(), forKey: CSquareNoteLineWidthKey)
            defaults.set((annotation as! CPDFSquareAnnotation).borderStyle(), forKey: CSquareNoteLineStyleKey)
            defaults.set((annotation as! CPDFSquareAnnotation).dashPattern(), forKey: CSquareNoteDashPatternKey)
        } else if annotationType == .highlight {
            defaults.setColor(annotation.color, forKey: SKHighlightNoteColorKey)
        } else if annotationType == .underline {
            defaults.setColor(annotation.color, forKey: CUnderlineNoteColorKey)
        } else if annotationType == .strikeOut {
            defaults.setColor(annotation.color, forKey: CStrikeOutNoteColorKey)
        } else if annotationType == .line || annotationType == .arrow {
            defaults.setColor(annotation.color, forKey: CLineNoteColorKey)
            defaults.set(annotation.lineWidth(), forKey: CLineNoteLineWidthKey)
            defaults.set(annotation.borderStyle(), forKey: CLineNoteLineStyleKey)
            defaults.set(annotation.dashPattern(), forKey: CLineNoteDashPatternKey)
            defaults.setColor((annotation as! CPDFLineAnnotation).interiorColor, forKey: CLineNoteInteriorColorKey)
            defaults.set((annotation as! CPDFLineAnnotation).startLineStyle, forKey: CLineNoteStartLineStyleKey)
            defaults.set((annotation as! CPDFLineAnnotation).endLineStyle, forKey: CLineNoteEndLineStyleKey)
        } else if annotationType == .ink {
            defaults.setColor(annotation.color, forKey: CInkNoteColorKey)
            defaults.set(annotation.lineWidth(), forKey: CInkNoteLineWidthKey)
            defaults.set(annotation.borderStyle(), forKey: CInkNoteLineStyleKey)
            defaults.set(annotation.dashPattern(), forKey: CInkNoteDashPatternKey)
        } else if annotationType == .anchored {
//            [sud setColor:self.annotation.color forKey:SKNPDFAnnotationColorKey];
//            [sud setInteger:self.annotation.iconType forKey:SKAnchoredNoteIconTypeKey];

        }
    }
    
    var activeAnnotationType: KMActiveAnnotationType {
        set {
            _activeAnnotationType = newValue
            switch self.activeAnnotationType {
            case .highlight, .strikeOut, .underline:
                self.fontView.isHidden = true
                self.borderAndLineView.isHidden = true
                self.fillColorView.isHidden = true
                self.rotateView.isHidden = true
                self.typeView.isHidden = true
                self.dateView.isHidden = true
                self.iconView.isHidden = true
                self.createMarkupProperties()
            case .inkAndLine:
                self.fontView.isHidden = true
                self.fillColorView.isHidden = true
                self.rotateView.isHidden = true
                self.typeView.isHidden = true
                self.dateView.isHidden = true
                self.iconView.isHidden = true
                self.createInkAndLineProperties()
            case .text:
                self.fontView.isHidden = true
                self.borderAndLineView.isHidden = true
                self.fillColorView.isHidden = true
                self.rotateView.isHidden = true
                self.typeView.isHidden = true
                self.dateView.isHidden = true
                self.createTextProperties()
            case .squareAndCircle:
                self.fontView.isHidden = true
                self.rotateView.isHidden = true
                self.typeView.isHidden = true
                self.dateView.isHidden = true
                self.iconView.isHidden = true
                self.fillColorView.isHidden = true
                self.createSquareAndCircleProperties()
            case .freeText:
                self.colorView.isHidden = true
                self.rotateView.isHidden = true
                self.typeView.isHidden = true
                self.dateView.isHidden = true
                self.iconView.isHidden = true
                self.createFreeTextProperties()
            case .selfSignFreeText:
                self.rotateView.isHidden = true
                self.borderAndLineView.isHidden = true
                self.fillColorView.isHidden = true
                self.typeView.isHidden = true
                self.iconView.isHidden = true
                self.createSelfSignFreeTextProperties()
            default:
                break
            }
        }
        get {
            return _activeAnnotationType
        }
    }

    // MARK: private
    
    func updateViewColor() {
        if KMAppearance.isDarkMode() {
            let darkColor = NSColor(red: 57/255.0, green: 60/255.0, blue: 62/255.0, alpha: 1.0).cgColor
            let borderColor = NSColor(red: 86/255.0, green: 88/255.0, blue: 90/255.0, alpha: 1.0).cgColor
            
            setViewColor(fontPopUpButton, darkColor, borderColor)
            setViewColor(fontSizeComboBox, darkColor, borderColor)
            setViewColor(fontStylePopUpButton, darkColor, borderColor)
            setViewColor(lineWidthComboBox, darkColor, borderColor)
            setViewColor(opacityComboBox, darkColor, borderColor)
            setViewColor(datePopUpButton, darkColor, borderColor)
            setViewColor(widthComboBox, darkColor, borderColor)
            setViewColor(noteTextView, darkColor, borderColor)
        } else {
            let lightColor = NSColor.white.cgColor
            let borderColor = NSColor(red: 218/255.0, green: 219/255.0, blue: 222/255.0, alpha: 1.0).cgColor
            
            setViewColor(fontPopUpButton, lightColor, borderColor)
            setViewColor(fontSizeComboBox, lightColor, borderColor)
            setViewColor(fontStylePopUpButton, lightColor, borderColor)
            setViewColor(lineWidthComboBox, lightColor, borderColor)
            setViewColor(opacityComboBox, lightColor, borderColor)
            setViewColor(datePopUpButton, lightColor, borderColor)
            setViewColor(widthComboBox, lightColor, borderColor)
            setViewColor(noteTextView, lightColor, borderColor)
        }
    }

    func setViewColor(_ view: NSView, _ backgroundColor: CGColor, _ borderColor: CGColor) {
        view.layer?.backgroundColor = backgroundColor
        view.layer?.borderColor = borderColor
    }
    
    func refreshLineTypeUI() {
        lineStyleBox.borderColor = KMAppearance.Interactive.s0Color()
        dottedLineStyleBox.borderColor = KMAppearance.Interactive.s0Color()
        rightArrowStyleBox.borderColor = KMAppearance.Interactive.s0Color()
        lineStyleBox.fillColor = KMAppearance.Layout.l1Color()
        dottedLineStyleBox.fillColor = KMAppearance.Layout.l1Color()
        rightArrowStyleBox.fillColor = KMAppearance.Layout.l1Color()
        lineStyleBox.borderWidth = 1
        dottedLineStyleBox.borderWidth = 1
        rightArrowStyleBox.borderWidth = 1
        
        if lineStyleCount == 0 {
            lineStyleBox.fillColor = KMAppearance.Status.selColor()
            lineStyleBox.borderWidth = 0.0
        } else if lineStyleCount == 1 {
            dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
            dottedLineStyleBox.borderWidth = 0
        } else if lineStyleCount == 2 {
            rightArrowStyleBox.fillColor = KMAppearance.Status.selColor()
            rightArrowStyleBox.borderWidth = 0
        }
    }

    func hiddenSubviews() {
        fontViewTopConstant.constant = fontView.isHidden ? -(fontView.bounds.size.height) - 20 : 10
        ColorViewTopConstant.constant = colorView.isHidden ? -(colorView.bounds.size.height) : 10
        borderViewTopConstant.constant = borderAndLineView.isHidden ? -(borderAndLineView.bounds.size.height) : 20
        opacityViewTopConstant.constant = opacityView.isHidden ? -opacityView.bounds.size.height : 20
        rotateViewTopConstant.constant = rotateView.isHidden ? -(rotateView.bounds.size.height) : 20
        typeViewTopConstant.constant = typeView.isHidden ? -(typeView.bounds.size.height) : 20
        dateViewTopConstant.constant = dateView.isHidden ? -(dateView.bounds.size.height) : 20
        iconViewTopConstant.constant = iconView.isHidden ? -(iconView.bounds.size.height) : 20
        noteViewTopConstant.constant = noteView.isHidden ? -(noteView.bounds.size.height) : 20
        fillColorViewTopConstraint.constant = fillColorView.isHidden ? -fillColorView.bounds.size.height : 20
        fontViewColorPVConstraint.constant = fontViewCorloPV.isHidden ? -fontViewCorloPV.bounds.size.height : 10
    }
    
    func setActiveAnnotationType(_ activeAnnotationType: KMActiveAnnotationType) {
        self.activeAnnotationType = activeAnnotationType
        
        switch activeAnnotationType {
        case .highlight, .strikeOut, .underline:
            fontView.isHidden = true
            borderAndLineView.isHidden = true
            fillColorView.isHidden = true
            rotateView.isHidden = true
            typeView.isHidden = true
            dateView.isHidden = true
            iconView.isHidden = true
            createMarkupProperties()
        case .inkAndLine:
            fontView.isHidden = true
            fillColorView.isHidden = true
            rotateView.isHidden = true
            typeView.isHidden = true
            dateView.isHidden = true
            iconView.isHidden = true
            createInkAndLineProperties()
        case .text:
            fontView.isHidden = true
            borderAndLineView.isHidden = true
            fillColorView.isHidden = true
            rotateView.isHidden = true
            typeView.isHidden = true
            dateView.isHidden = true
            createTextProperties()
        case .squareAndCircle:
            fontView.isHidden = true
            rotateView.isHidden = true
            typeView.isHidden = true
            dateView.isHidden = true
            iconView.isHidden = true
            fillColorView.isHidden = true
            createSquareAndCircleProperties()
        case .freeText:
            colorView.isHidden = true
            rotateView.isHidden = true
            typeView.isHidden = true
            dateView.isHidden = true
            iconView.isHidden = true
            createFreeTextProperties()
        case .selfSignFreeText:
            rotateView.isHidden = true
            borderAndLineView.isHidden = true
            fillColorView.isHidden = true
            typeView.isHidden = true
            iconView.isHidden = true
            createSelfSignFreeTextProperties()
        default:
            break
        }
    }
    
    func createMarkupProperties() {
        let colorViewHeight = colorTitleLabel.frame.height + KMColorPickerViewHeight + 30
        colorView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: colorViewHeight)
        textColorBoxConstraint.constant = 10
        borderColorBoxConstraint.constant = 0
        textColorBox.isHidden = true
        lineWidthBox.isHidden = true
        imageBoxLayoutConstraint.constant = generalImageBoxView.frame.height
        
        hiddenSubviews()
        textColorPickerView.noContentString = true
        
        if activeAnnotationType == .highlight {
            textColorPickerView.annotationTypeString = NSLocalizedString("Highlight", comment: "Description for export")
        } else if activeAnnotationType == .strikeOut {
            textColorPickerView.annotationTypeString = NSLocalizedString("Strikethrough", comment: "Description for export")
        } else if activeAnnotationType == .underline {
            textColorPickerView.annotationTypeString = NSLocalizedString("Underline", comment: "Description for export")
        }
        
        textColorPickerView.annotationType = (activeAnnotationType == .highlight) ? .markupHighlightColors : .markupOtherColors
    }
    
    func openFreeTextStylesViewController() {
//        let vc = KMFreeTextStylesViewController()
//        vc.annotations = self.annotations
//        vc.view.frame = CGRect(x: 0, y: 0, width: 280, height: CGRectGetHeight(self.view.window?.frame ?? CGRect.zero) - 300)
//        
//        let createFilePopover = NSPopover()
//        createFilePopover.contentViewController = vc
//        createFilePopover.animates = true
//        createFilePopover.behavior = .transient
//        createFilePopover.show(relativeTo: CGRect(x: _textImageBox.bounds.origin.x, y: 10, width: _textImageBox.bounds.size.width, height: _textImageBox.bounds.size.height), of: _textImageBox, preferredEdge: .minY)
//        
//        // Assuming _textImageBox is an NSView instance
//        createFilePopover.show(relativeTo: _textImageBox.bounds, of: _textImageBox, preferredEdge: .minY)
        
        // Release is not needed in Swift due to automatic reference counting (ARC)
    }

    func changeStoredFontInfo(_ sender: Any) {
//        if let senderFont = sender as? NSFont {
//            for tAnnotation in self.annotations {
//                tAnnotation.removeAllAppearanceStreams()
//                let font = senderFont.convert(tAnnotation.font)
//                if let validFont = font {
//                    tAnnotation.font = validFont
//                }
//            }
//        }
    }
    
    private func updateAnnotation() {
        if annotationModel?.annotation != nil {
            if annotation is CPDFFreeTextAnnotation {
                let textNote = (annotation as! CPDFFreeTextAnnotation)
                if let isEdit = pdfView?.isEdit(withCurrentFreeText: textNote), isEdit {
                    pdfView?.commitEditAnnotationFreeText(textNote)
                }
                
                pdfView?.setNeedsDisplay(pdfView?.activeAnnotation)
            }
            for tAnnotation in annotations {
                if tAnnotation is CPDFStampAnnotation {
                    (tAnnotation as? KMSelfSignAnnotation)?.updateAppearanceStream()
                }
                
                if tAnnotation is CPDFMarkupAnnotation {
                    pdfView?.setNeedsDisplayFor(tAnnotation.page)
                } else {
                    pdfView?.setNeedsDisplayAnnotationViewFor(tAnnotation.page)
                }
            }
        }
        
        if annotationType == .freeText {
            textAnnotationImageView.image = annotationModel?.annotationImage
        } else {
            generalImageView.image = annotationModel?.annotationImage
        }
    }
    
    // MARK: Line Note
    
    func createInkAndLineProperties() {
        if annotationType == .ink {
            let colorViewHeight = CGRectGetHeight(colorTitleLabel.frame) + KMColorPickerViewHeight + 30
            colorView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: colorViewHeight)
            textColorBoxConstraint.constant = 10
            borderColorBoxConstraint.constant = 0
            textColorBox.isHidden = true
            lineWidthBox.isHidden = true

            imageBoxLayoutConstraint.constant = CGRectGetHeight(generalImageBoxView.frame)
            hiddenSubviews()
            textColorPickerView.noContentString = true

            textColorPickerView.annotationTypeString = NSLocalizedString("Line Color", comment: "")
            textColorPickerView.annotationType = .inkColors

        } else if annotationType == .line || annotationType == .arrow {
            let colorViewHeight = CGRectGetHeight(colorTitleLabel.frame) + KMColorPickerViewHeight * 2 + 40
            colorView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: colorViewHeight)
            textColorBoxConstraint.constant = KMColorPickerViewHeight + 20
            borderColorBoxConstraint.constant = 0
            lineWidthBox.isHidden = true
            textColorPickerViewConstant.constant = 57

            imageBoxLayoutConstraint.constant = CGRectGetHeight(generalImageBoxView.frame)

            hiddenSubviews()

            borderColorPickerView.annotationTypeString = NSLocalizedString("Line Color", comment: "")
            textColorPickerView.annotationTypeString = NSLocalizedString("Fill Color", comment: "")
            borderColorPickerView.annotationType = .lineColors
            textColorPickerView.annotationType = .lineFillColors

            borderColorPickerView.annotationTypeString = NSLocalizedString("Line Color", comment: "")
            borderColorPickerView.annotationType = .lineColors
        }

        lineTypeLabel.stringValue = NSLocalizedString("Line and Border Style", comment: "")
        lineTypeLabel.textColor = KMAppearance.Layout.h0Color()
        lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
        lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)

        lineStyleButton.wantsLayer = true
        dottedLineStyleButton.wantsLayer = true
        rightArrowStyleButton.wantsLayer = true
        lineStyleButton.image = borderStyleSolid(false)
        dottedLineStyleButton.image = borderStyleDashed(false)
        rightArrowStyleButton.image = lineStyleRightArrow(false)

        if annotationModel?.style() == .solid {
            lineStyleCount = 0
            lineStyleButton.image = borderStyleSolid(true)
            lineStyleBox.borderWidth = 0
            lineStyleBox.fillColor = KMAppearance.Status.selColor()
        } else if annotationModel?.style() == .dashed {
            lineStyleCount = 1
            dottedLineStyleButton.image = borderStyleDashed(true)
            dottedLineStyleBox.borderWidth = 0
            dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
        }
        
        if (annotationType == .line || annotationType == .arrow) && annotationModel?.endLineStyle() == .closedArrow {
            lineStyleCount = 2
            rightArrowStyleButton.image = lineStyleRightArrow(true)
            rightArrowStyleBox.borderWidth = 0
            rightArrowStyleBox.fillColor = KMAppearance.Status.selColor()
        }
    }
    
    func createTextProperties() {
        makeNoteIcons()

        let colorViewHeight = colorTitleLabel.frame.height + KMColorPickerViewHeight + 30
        colorView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: colorViewHeight)
        textColorBoxConstraint.constant = 10
        borderColorBoxConstraint.constant = 0
        textColorBox.isHidden = true
        lineWidthBox.isHidden = true

        imageBoxLayoutConstraint.constant = generalImageBoxView.frame.height
        hiddenSubviews()

        textColorPickerView.annotationTypeString = NSLocalizedString("Anchored Note", comment: "Description for export")
        commentButton.title = NSLocalizedString("Comment", tableName: "NoteWindow", comment: "")
        commentButton.toolTip = NSLocalizedString("Comment", tableName: "NoteWindow", comment: "")
        commentButton.setTitleColor(KMAppearance.Layout.h0Color())
        paragraphButton.title = NSLocalizedString("Paragraph", tableName: "NoteWindow", comment: "")
        paragraphButton.toolTip = NSLocalizedString("Paragraph", tableName: "NoteWindow", comment: "")
        paragraphButton.setTitleColor(KMAppearance.Layout.h0Color())
        insertButton.title = NSLocalizedString("Insert", tableName: "NoteWindow", comment: "")
        insertButton.toolTip = NSLocalizedString("Insert", tableName: "NoteWindow", comment: "")
        insertButton.setTitleColor(KMAppearance.Layout.h0Color())
        addParagraphButton.title = NSLocalizedString("New Paragraph", tableName: "NoteWindow", comment: "")
        addParagraphButton.toolTip = NSLocalizedString("New Paragraph", tableName: "NoteWindow", comment: "")
        addParagraphButton.setTitleColor(KMAppearance.Layout.h0Color())
        keyButton.title = NSLocalizedString("Key", tableName: "NoteWindow", comment: "")
        keyButton.toolTip = NSLocalizedString("Key", tableName: "NoteWindow", comment: "")
        keyButton.setTitleColor(KMAppearance.Layout.h0Color())
        noteButton.title = NSLocalizedString("Note", tableName: "NoteWindow", comment: "")
        noteButton.toolTip = NSLocalizedString("Note", tableName: "NoteWindow", comment: "")
        noteButton.setTitleColor(KMAppearance.Layout.h0Color())
        helpButton.title = NSLocalizedString("Help", tableName: "NoteWindow", comment: "")
        helpButton.toolTip = NSLocalizedString("Help", tableName: "NoteWindow", comment: "")
        helpButton.setTitleColor(KMAppearance.Layout.h0Color())

        let languages = NSLocale.preferredLanguages
        var currentLocaleLanguageCode = "en"
        if let firstLanguage = languages.first {
            currentLocaleLanguageCode = firstLanguage
            if currentLocaleLanguageCode.hasPrefix("zh") {
                currentLocaleLanguageCode = "zh"
            }
        }

        let buttonArray: [NSButton] = [commentButton, keyButton, noteButton, helpButton, addParagraphButton, paragraphButton, insertButton]
        for button in buttonArray {
            button.wantsLayer = true
            button.layer?.cornerRadius = 6.0
            if currentLocaleLanguageCode == "zh" {
                iconButtonHeightConstant.constant = 56.0
                button.imagePosition = .imageAbove
            } else {
                iconButtonHeightConstant.constant = 50.0
                button.imagePosition = .imageOnly
            }
        }

        iconButtonArray = [commentBox, keyBox, noteBox, helpBox, addParagraphBox, paragraphBox, insertBox]

//        let iconType = annotation.iconType
//        clickAnnotationTextIconButtonAction(iconType: iconType, boxArr: iconButtonArray)

        textColorPickerView.annotationType = .anchoredNoteColors
        textColorPickerView.isCallColorPanelAction = true
    }
    
    func clickAnnotationTextIconButtonAction(iconType: UInt, boxArr buttonArr: [NSBox]) {
        for i in 0..<buttonArr.count {
            if iconType == 0 {
                commentButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
                commentButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteAnnotationSel)
            } else {
                commentButton.layer?.backgroundColor = NSColor.clear.cgColor
                commentButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteAnnotationNor)
            }
            
            if iconType == 1 {
                keyButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
                keyButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteKeywordSel)
            } else {
                keyButton.layer?.backgroundColor = NSColor.clear.cgColor
                keyButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteKeywordNor)
            }
            
            if iconType == 2 {
                noteButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
                noteButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteNotesSel)
            } else {
                noteButton.layer?.backgroundColor = NSColor.clear.cgColor
                noteButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteNotesNor)
            }
            
            if iconType == 3 {
                helpButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
                helpButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteHelpSel)
            } else {
                helpButton.layer?.backgroundColor = NSColor.clear.cgColor
                helpButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteHelpNor)
            }
            
            if iconType == 4 {
                addParagraphButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
                addParagraphButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteNewparagraphSel)
            } else {
                addParagraphButton.layer?.backgroundColor = NSColor.clear.cgColor
                addParagraphButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteNewparagraphNor)
            }
            
            if iconType == 5 {
                paragraphButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
                paragraphButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteParagraphSel)
            } else {
                paragraphButton.layer?.backgroundColor = NSColor.clear.cgColor
                paragraphButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteParagraphNor)
            }
            
            if iconType == 6 {
                insertButton.layer?.backgroundColor = KMAppearance.Status.selColor().cgColor
                insertButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteInsertSel)
            } else {
                insertButton.layer?.backgroundColor = NSColor.clear.cgColor
                insertButton.image = NSImage(named: KMImageNameUXIconPropertybarNoteInsertNor)
            }
        }
    }
    
    func borderStyleSolid(_ isSelect: Bool) -> NSImage {
        let size = NSSize(width: 49.0, height: 12.0)
        let image = NSImage(size: size, flipped: false, drawingHandler: { rect in
            let path = NSBezierPath(rect: NSRect(x: 15.0, y: 5.0, width: 20.0, height: 1.0))
            path.lineWidth = 2.0
            isSelect ? KMAppearance.Layout.m_1Color().setStroke() : KMAppearance.Layout.m_1Color().setStroke()
            path.stroke()
            return true
        })
        return image
    }

    func borderStyleDashed(_ isSelect: Bool) -> NSImage {
        let size = NSSize(width: 49.0, height: 12.0)
        let image = NSImage(size: size, flipped: false, drawingHandler: { rect in
            let path = NSBezierPath()
            path.move(to: NSPoint(x: 15.0, y: 5.0))
            path.line(to: NSPoint(x: 19.0, y: 5.0))
            path.move(to: NSPoint(x: 23.0, y: 5.0))
            path.line(to: NSPoint(x: 27.0, y: 5.0))
            path.move(to: NSPoint(x: 31.0, y: 5.0))
            path.line(to: NSPoint(x: 35.0, y: 5.0))
            path.lineWidth = 2.0
            isSelect ? KMAppearance.Layout.m_1Color().setStroke() : KMAppearance.Layout.m_1Color().setStroke()
            path.stroke()
            return true
        })
        return image
    }
    
    func lineStyleRightArrow(_ isSelect: Bool) -> NSImage {
        let size = NSSize(width: 49.0, height: 12.0)
        
        let image = NSImage(size: size, flipped: false, drawingHandler: { rect in
            let path = NSBezierPath()
            path.move(to: NSPoint(x: 6.0, y: 6.0))
            path.line(to: NSPoint(x: 43.0, y: 6.0))
            path.move(to: NSPoint(x: 32.0, y: 3.0))
            path.line(to: NSPoint(x: 43.0, y: 6.0))
            path.line(to: NSPoint(x: 32.0, y: 9.0))
            path.close()
            path.lineWidth = 2.0
            
            if isSelect {
                KMAppearance.Layout.l0Color().setStroke()
            } else {
                KMAppearance.Interactive.s0Color().setStroke()
            }
            path.stroke()
            return true
        })
        return image
    }

    
    // MARK: SKSquareNote、SKCircleNote、SKArrowNote Properties
    
    func createSquareAndCircleProperties() {
        let colorViewHeight = CGRectGetHeight(colorTitleLabel.frame) + KMColorPickerViewHeight * 2 + 40
        colorView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: colorViewHeight)
        textColorBoxConstraint.constant = KMColorPickerViewHeight + 20
        borderColorBoxConstraint.constant = 0
        lineWidthBox.isHidden = true
        textColorPickerViewConstant.constant = 57
        
        imageBoxLayoutConstraint.constant = CGRectGetHeight(generalImageBoxView.frame)
        
        hiddenSubviews()
        
        lineTypeLabel.stringValue = NSLocalizedString("Line and Border Style", comment: "")
        lineTypeLabel.textColor = KMAppearance.Layout.h0Color()
        lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
        lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
        
        textColorPickerView.annotationTypeString = NSLocalizedString("Fill Color", comment: "")
        borderColorPickerView.annotationTypeString = NSLocalizedString("Line Color", comment: "")
        textColorPickerView.annotationType = .lineFillColors
        borderColorPickerView.annotationType = .lineColors
        
        lineStyleButton.wantsLayer = true
        dottedLineStyleButton.wantsLayer = true
        rightArrowStyleButton.wantsLayer = true
        lineStyleButton.image = borderStyleSolid(false)
        dottedLineStyleButton.image = borderStyleDashed(false)
        if annotationModel?.annotation != nil {
            if annotationModel?.annotation.borderStyle() == .solid {
                lineStyleCount = 0
                lineStyleButton.image = borderStyleSolid(true)
                
                lineStyleBox.borderWidth = 0
                lineStyleBox.fillColor = KMAppearance.Status.selColor()
            } else if annotationModel?.annotation.borderStyle() == .dashed {
                lineStyleCount = 1
                dottedLineStyleButton.image = borderStyleDashed(true)
                
                dottedLineStyleBox.borderWidth = 1
                dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
            }
        } else {
            if annotationModel?.style() == .solid {
                lineStyleCount = 0
                lineStyleButton.image = borderStyleSolid(true)
                
                lineStyleBox.borderWidth = 0
                lineStyleBox.fillColor = KMAppearance.Status.selColor()
            } else if annotationModel?.style() == .dashed {
                lineStyleCount = 1
                dottedLineStyleButton.image = borderStyleDashed(true)
                
                dottedLineStyleBox.borderWidth = 1
                dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
            }
        }
    }
    
    // MARK: SKFreeTextNote、PDFAnnotationFreeText Properties
    
    func createFreeTextProperties() {
        imageBox.fillColor = KMAppearance.Layout.w0Color()
        
        textColorBox.isHidden = true
        lineWidthBox.isHidden = true
        
        imageBoxLayoutConstraint.constant = CGRectGetHeight(textImageBoxView.frame)
        
        textImageBox.downCallback = { [weak self] downEntered, mouseBox, event in
            if downEntered {
                self?.openFreeTextStylesViewController()
            }
        }
        
        textImageUpDateButton.wantsLayer = true
        textImageBoxButton.image = NSImage(named: KMImageNameUXIconBtnTriDownNor)
        textImageBoxButton.isEnabled = true
        textImageUpDateButton.title = NSLocalizedString("Click to refresh", comment: "")
        textImageUpDateButton.setTitleColor(KMAppearance.Layout.w0Color())
        textImageUpDateButton.layer?.cornerRadius = 1.0
        textImageUpDateButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
        textImageUpDateButton.isHidden = true
        
        hiddenSubviews()
        
        fontViewCorloPV.noContentString = true
        fontViewCorloPV.annotationTypeString = NSLocalizedString("Color", comment: "")
        fillColorPickerView.noContentString = true
        fillColorPickerView.annotationTypeString = NSLocalizedString("Color", comment: "")
        lineTypeLabel.stringValue = NSLocalizedString("Line and Border Style", comment: "")
        lineTypeLabel.textColor = KMAppearance.Layout.h0Color()
        leftAlignButton.toolTip = NSLocalizedString("Left Alignment", comment: "")
        centerAlignButton.toolTip = NSLocalizedString("Center", comment: "")
        rightAlignButton.toolTip = NSLocalizedString("Right Alignment", comment: "")
        lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
        lineWidthComboBox.stringValue = String(format: "%0.1f pt", Float((annotationModel?.lineWidth())!))

        leftRotateBox.borderColor = KMAppearance.Interactive.s0Color()
        leftRotateBox.borderWidth = 0.5
        leftRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateCounterclockwiseNor)
        leftRotateBox.downCallback = { [weak self] downEntered, mouseBox, event in
            if downEntered {
                self?.leftRotateBox.fillColor = KMAppearance.Status.selColor()
                self?.leftRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateCounterclockwisePre)
            } else {
                self?.leftRotateBox.fillColor = KMAppearance.Layout.w0Color()
                self?.leftRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateCounterclockwiseNor)
            }
        }
        
        rightRotateBox.borderColor = KMAppearance.Interactive.s0Color()
        rightRotateBox.borderWidth = 0.5
        rightRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateClockwiseNor)
        
        rightRotateBox.downCallback = { [weak self] downEntered, mouseBox, event in
            if downEntered {
                self?.rightRotateBox.fillColor = KMAppearance.Status.selColor()
                self?.rightRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateClockwisePre)
            } else {
                self?.rightRotateBox.fillColor = KMAppearance.Layout.w0Color()
                self?.rightRotateButton.image = NSImage(named: KMImageNameUXIconPropertybarRotateClockwiseNor)
            }
        }
        
        lineStyleButton.wantsLayer = true
        dottedLineStyleButton.wantsLayer = true
        rightArrowStyleButton.wantsLayer = true
        lineStyleButton.image = borderStyleSolid(false)
        dottedLineStyleButton.image = borderStyleDashed(false)
        if annotationModel?.style() == .solid {
            lineStyleCount = 0
            lineStyleButton.image = borderStyleSolid(true)
            lineStyleBox.borderWidth = 0
            lineStyleBox.fillColor = KMAppearance.Status.selColor()
            lineStyleBox.borderWidth = 0
        } else if annotationModel?.style() == .dashed {
            lineStyleCount = 1
            dottedLineStyleButton.image = borderStyleDashed(true)
            dottedLineStyleBox.fillColor = KMAppearance.Status.selColor()
            dottedLineStyleBox.borderWidth = 0
        } else {
            lineStyleCount = 0
            lineStyleButton.image = borderStyleSolid(true)
            lineStyleBox.borderWidth = 0
            lineStyleBox.fillColor = KMAppearance.Status.selColor()
            lineStyleBox.borderWidth = 0
        }
        
        fontViewCorloPV.annotationType = .freeTextColors
        fillColorPickerView.annotationType = .freeTextFillColors
    }
    
    func alignmentTypeSelected(_ type: KMFreeTextAnnotationAlignmentType) {
        selectedAlignmentButtonLayer?.removeFromSuperlayer()
        selectedAlignmentButtonLayer = CALayer()

        selectedAlignmentButtonLayer?.cornerRadius = 6.0
        leftAlignButton.wantsLayer = true
        centerAlignButton.wantsLayer = true
        rightAlignButton.wantsLayer = true
        selectedAlignmentButtonLayer?.bounds = leftAlignButton.layer?.bounds ?? CGRect.zero
        selectedAlignmentButtonLayer?.anchorPoint = CGPoint(x: 0, y: 0)

        var color = NSColor(red: 71/255.0, green: 126/255.0, blue: 222/255.0, alpha: 0.16)
        if #available(macOS 10.14, *) {
            let appearanceName = NSApp.effectiveAppearance.bestMatch(from: [.aqua, .darkAqua])
            if appearanceName == .darkAqua {
                color = NSColor(red: 34/255.0, green: 122/255.0, blue: 255/255.0, alpha: 0.3)
            }
        }
        selectedAlignmentButtonLayer?.backgroundColor = color.cgColor

        leftAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignLeftNor)
        centerAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignCenterNor)
        rightAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignRightNor)

        if type == .left {
            leftAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignLeftSel)
        } else if type == .center {
            centerAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignCenterSel)
        } else if type == .right {
            rightAlignButton.image = NSImage(named: KMImageNameUXIconPropertybarTextalignRightSel)
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { [weak self] in
            guard let self = self else { return }
            if type == .left {
                self.leftAlignButton.layer?.insertSublayer(self.selectedAlignmentButtonLayer!, at: 0)
            } else if type == .center {
                self.centerAlignButton.layer?.insertSublayer(self.selectedAlignmentButtonLayer!, at: 0)
            } else if type == .right {
                self.rightAlignButton.layer?.insertSublayer(self.selectedAlignmentButtonLayer!, at: 0)
            }
        }
    }
    
    // MARK: SKFreeTextNote、KMSelfSignAnnotationFreeText Properties
    
    func createSelfSignFreeTextProperties() {
        let colorViewHeight = CGRectGetHeight(colorTitleLabel.frame) + KMColorPickerViewHeight + 30
        colorView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: colorViewHeight)
        textColorBoxConstraint.constant = 10
        borderColorBoxConstraint.constant = 0
        textColorBox.isHidden = true
        lineWidthBox.isHidden = true

        imageBoxLayoutConstraint.constant = CGRectGetHeight(generalImageBoxView.frame)
        hiddenSubviews()

        fontViewTopConstant.constant = colorView.frame.size.height + opacityView.frame.size.height - 10 + 10
        ColorViewTopConstant.constant = -(fontView.frame.size.height + fontViewTopConstant.constant)
        dateViewTopConstant.constant = fontView.frame.size.height + 30

        fontViewCorloPV.noContentString = true
        fontViewCorloPV.annotationTypeString = ""
        textColorPickerView.annotationTypeString = NSLocalizedString("Background", comment: "")
        dateCheckButton.title = NSLocalizedString("Time", comment: "")
        
        if let attrTitle = dateCheckButton.attributedTitle.mutableCopy() as? NSMutableAttributedString {
            let len = attrTitle.length
            let range = NSRange(location: 0, length: len)
            attrTitle.addAttribute(.foregroundColor, value: KMAppearance.Layout.h1Color(), range: range)
            attrTitle.fixAttributes(in: range)
            dateCheckButton.attributedTitle = attrTitle
        }

        if activeAnnotationType == .selfSignFreeText { // 添加日期 字体默认颜色不要透明色
            textColorPickerView.annotationType = .freeTextFillColors
            fontViewCorloPV.annotationType = .freeTextColors
        } else {
            textColorPickerView.annotationType = .freeTextColors
            fontViewCorloPV.annotationType = .freeTextFillColors
        }
    }

    func setFontStyle(fontName: String, currentStyle style: String?) -> UInt {
        var selectIndex: UInt = 0
        let menu = NSMenu()
        if let fontFamily = NSFontManager.shared.availableMembers(ofFontFamily: fontName) {
            for i in 0..<fontFamily.count {
                let array = fontFamily[i]
                if let styleName = array[1] as? String {
                    if style == styleName {
                        selectIndex = UInt(i)
                    }
                    let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: fontName, NSFontDescriptor.AttributeName.face: styleName])
                    let font = NSFont(descriptor: attributeFontDescriptor, size: 12.0)
                    let attrited = [NSAttributedString.Key.font: font]
                    let string = NSAttributedString(string: styleName, attributes: attrited)
                    let item = NSMenuItem()
                    item.attributedTitle = string
                    
                    menu.addItem(item)
                }
            }
        }
        
        if style == nil {
            selectIndex = 0
        }
        
        fontStylePopUpButton.menu = menu
        
        return selectIndex
    }
    
    // MARK: UI Action
    
    @IBAction func colorPickerViewAction(_ sender: Any) {
        var fillColor: NSColor = NSColor.clear
        var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
        
        if let textColor = textColorPickerView.color {
            textColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
            if fabs(opacity - 0) < 0.001 {
                if annotationType == .square || annotationType == .circle || annotationType == .line || annotationType == .arrow {
                    annotationModel?.setInteriorOpacity(0)
                    annotationModel?.setInteriorColor(.black)
                } else if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
                    annotationModel?.setOpacity(0)
                    annotationModel?.setFontColor(.black)
                } else {
                    annotationModel?.setOpacity(0)
                    annotationModel?.setFontColor(.black)
                }
            } else {
                if annotationType == .square || annotationType == .circle || annotationType == .line || annotationType == .arrow {
                    annotationModel?.setInteriorOpacity(opacity)
                    annotationModel?.setInteriorColor(textColor)
                } else if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
                    annotationModel?.setOpacity(opacity)
                    annotationModel?.setFontColor(textColor)
                } else {
                    annotationModel?.setOpacity(opacity)
                    annotationModel?.setColor(textColor)
                }
            }
            
            opacitySlider.floatValue = Float(opacity)
            let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
            fillColor = color
            
            if annotationModel?.annotations != nil {
                if annotationModel?.annotation is CPDFFreeTextAnnotation {
                    let textNote = (annotationModel?.annotation as! CPDFFreeTextAnnotation)
                    if let isEdit = pdfView?.isEdit(withCurrentFreeText: textNote), isEdit {
                        pdfView?.setEditAnnotationFreeTextColor(textColor, freeText: textNote)
                    } else {
                        updateAnnotation()
                    }
                } else {
                    updateAnnotation()
                }
                generalImageView.image = annotationModel?.annotationImage
            } else {
                updateAnnotation()
            }
        }
    }

    @IBAction func fillColorPickerViewAction(_ sender: Any) {
        var fillColor = NSColor.clear
        var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0

        if let borderColor = borderColorPickerView.color {
            borderColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
            opacitySlider.floatValue = Float(opacity)
            let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
            fillColor = color
        }
        
        if annotationType == .freeText {
            if let fillColorPickerColor = fillColorPickerView.color {
                fillColorPickerColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
                opacitySlider.floatValue = Float(opacity)
                let color = NSColor(calibratedRed: red, green: green, blue: blue, alpha: opacity)
                annotationModel?.setColor(color)
                annotationModel?.setOpacity(opacity)
            }
        } else {
            annotationModel?.setColor(fillColor)
            annotationModel?.setOpacity(opacity)
        }
        updateAnnotation()
    }
    
    @IBAction func fontViewCorloPVAction(_ sender: Any) {
//        var fillColor: NSColor = NSColor.clear
//        var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, opacity: CGFloat = 0.0
//        
//        if let textColor = fontViewCorloPV.color {
//            textColor.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
//            if fabs(opacity - 0) < 0.001 {
//                if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
//                    annotationModel?.setOpacity(0)
//                    annotationModel?.setFontColor(.black)
//                } else {
//                    annotationModel?.setOpacity(0)
//                    annotationModel?.setFontColor(.black)
//                }
//            } else {
//                if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
//                    annotationModel?.setOpacity(opacity)
//                    annotationModel?.setFontColor(textColor)
//                } else {
//                    annotationModel?.setOpacity(opacity)
//                    annotationModel?.setColor(textColor)
//                }
//            }
//            
//            opacitySlider.floatValue = Float(opacity)
//            
//            if annotationModel?.annotation != nil {
//                if annotationModel?.annotation is CPDFFreeTextAnnotation {
//                    let textNote = (annotationModel?.annotation as! CPDFFreeTextAnnotation)
//                    if let isEdit = pdfView?.isEdit(withCurrentFreeText: textNote), isEdit {
//                        pdfView?.setEditAnnotationFreeTextColor(textColor, freeText: textNote)
//                    } else {
//                        updateAnnotation()
//                    }
//                } else {
//                    updateAnnotation()
//                }
//                generalImageView.image = annotationModel?.annotationImage
//            } else {
//                updateAnnotation()
//            }
//        }
        
        if annotationType == .freeText {
            annotationModel?.setFontColor(fontViewCorloPV.color)
        } else {
            annotationModel?.setColor(fontViewCorloPV.color)
        }
        updateAnnotation()
    }

    @IBAction func opacitySliderAction(_ sender: Any) {
        var opcity = CGFloat(opacitySlider.floatValue)
        if opcity == 0 {
            opcity = 0.0001
        }
        if annotationType == .signFalse ||
            annotationType == .signTure ||
            annotationType == .signDot ||
            annotationType == .signCircle ||
            annotationType == .signLine {
            annotationModel?.setOpacity(opcity)
        } else if annotationType == .square ||
                    annotationType == .circle {
            if opcity != 0 {
                annotationModel?.setOpacity(opcity)
                annotationModel?.setInteriorOpacity(opcity)
            } else {
                annotationModel?.setColor(nil)
                annotationModel?.setInteriorColor(nil)
            }
        } else if annotationType == .freeText || annotationType == .signDate || annotationType == .signText {
            annotationModel?.setOpacity(opcity)
            
            var color = annotationModel?.fontColor()
            if annotationModel?.opacity() != 0 {
                var red: CGFloat = 0.0
                var green: CGFloat = 0.0
                var blue: CGFloat = 0.0
                var opacity: CGFloat = 0.0
                color?.usingColorSpaceName(.calibratedRGB)?.getRed(&red, green: &green, blue: &blue, alpha: &opacity)
                color = NSColor(red: red, green: green, blue: blue, alpha: (annotationModel?.opacity())!)
            } else {
                color = .clear
            }
        } else {
            annotationModel?.setOpacity(opcity)
        }
        opacityComboBox.stringValue = "\(Int(opcity * 100))%"
        updateAnnotation()
    }
    
    @IBAction func opacityComboBoxAction(_ sender: Any) {
        opacitySlider.floatValue = Float(opacityComboBox.floatValue / 100)
        var opcity = CGFloat(opacitySlider.floatValue)
        if opcity == 0 {
            opcity = 0.0001
        }
        if annotationType == .signFalse ||
            annotationType == .signTure ||
            annotationType == .signDot ||
            annotationType == .signCircle ||
            annotationType == .signLine {
            annotationModel?.setOpacity(opcity)
        } else if annotationType == .square ||
                    annotationType == .circle {
            if opcity != 0 {
                annotationModel?.setOpacity(opcity)
                annotationModel?.setInteriorOpacity(opcity)
            } else {
                annotationModel?.setColor(nil)
                annotationModel?.setInteriorColor(nil)
            }
        } else if annotationType == .freeText || annotationType == .signDate || annotationType == .signText {
            annotationModel?.setInteriorOpacity(opcity)
        } else {
            annotationModel?.setOpacity(opcity)
        }
        opacitySlider.floatValue = Float(opcity)
        opacitySlider.toolTip = "\(Int(opcity * 100))%"
        updateAnnotation()
    }
    
    @IBAction func lineWidthSliderAction(_ sender: Any) {
        annotationModel?.setLineWidth(CGFloat(lineWidthSlider.floatValue))
        lineWidthComboBox.stringValue = String(format: "%0.1f pt", (annotationModel?.lineWidth())!)
        
        updateAnnotation()
    }

    @IBAction func lineWidthComboBoxAction(_ sender: Any) {
        var lineWidth = lineWidthComboBox.floatValue
        if lineWidth > 18 {
            lineWidth = 18
        } else if lineWidth < 0.5 {
            lineWidth = 0.5
        }
        annotationModel?.setLineWidth(CGFloat(lineWidth))
        lineWidthSlider.floatValue = Float((annotationModel?.lineWidth())!)
        
        updateAnnotation()
    }

    @IBAction func alignButtonAction(_ sender: NSButton) {
        var alignmentType: KMFreeTextAnnotationAlignmentType = .left
        
        if annotationModel?.annotations != nil {
            for tAnnotation in self.annotations {
                switch sender.tag {
                case 0:
                    if tAnnotation is CPDFFreeTextAnnotation {
                        (tAnnotation as! CPDFFreeTextAnnotation).alignment = .left
                    }
                    alignmentType = .left
                case 1:
                    if tAnnotation is CPDFFreeTextAnnotation {
                        (tAnnotation as! CPDFFreeTextAnnotation).alignment = .center
                    }
                    alignmentType = .center
                case 2:
                    if tAnnotation is CPDFFreeTextAnnotation {
                        (tAnnotation as! CPDFFreeTextAnnotation).alignment = .right
                    }
                    alignmentType = .right
                default:
                    break
                }
            }
        } else {
            switch sender.tag {
            case 0:
                annotationModel?.setAlignment(.left)
                alignmentType = .left
            case 1:
                annotationModel?.setAlignment(.center)
                alignmentType = .center
            case 2:
                annotationModel?.setAlignment(.right)
                alignmentType = .right
            default:
                break
            }
        }
        alignmentTypeSelected(alignmentType)
        updateAnnotation()
        
        NotificationCenter.default.post(name: NSNotification.Name("KMAnnotationAlignmentTypeNotification"),
                                        object: "\(alignmentType.rawValue)")
    }
    
    @IBAction func currentFontColorButtonAction(_ sender: NSButton) {
//        if ([_annotation isKindOfClass:[PDFAnnotationFreeText class]]) {
//            KMFontColorViewController *vc = [[[KMFontColorViewController alloc] initWithNibName:@"KMFontColorViewController" bundle:[NSBundle mainBundle]] autorelease];
//            vc.annotationFontColor = _annotation.fontColor;
//            __block typeof(self) blockSelf = self;
//            vc.fontColorChangeCallback = ^(NSColor *fontColor) {
//                for (PDFAnnotation *tAnnotation in blockSelf.annotations) {
//                    tAnnotation.fontColor = fontColor;
//                }
//            };
//            NSPopover *popover = [[NSPopover alloc] init];
//            popover.delegate = self;
//            popover.contentViewController = vc;
//            popover.animates = YES;
//            popover.behavior = NSPopoverBehaviorTransient;
//            [popover showRelativeToRect:CGRectMake([sender bounds].origin.x, 0, [sender bounds].size.width, [sender bounds].size.height) ofView:sender preferredEdge:CGRectMaxYEdge];
//            [popover release];
//        }
    }
    
    @IBAction func borderButtonAction(_ sender: NSButton) {
        let fontWindowController = KMAnnotationLineWindowController.sharedAnnotationLine
        guard let window = fontWindowController.window else { return }
        fontWindowController.annotations = annotations
        fontWindowController.annotationLineChangeBlock = { [weak self] lineNote in
            if lineNote.borderStyle() == .solid {
                self!.lineTypeButtonAction(self!.lineStyleButton)
            } else if lineNote.borderStyle() == .dashed {
                self!.lineTypeButtonAction(self!.dottedLineStyleButton)
                for tAnnotation in self!.annotations {
                    tAnnotation.setDashPattern(lineNote.dashPattern())
                }
            }
        }
        
        window.orderFront(sender)
    }
    
    func lineTypePopAction() {
        annotationModel?.setStyle(CPDFBorderStyle(rawValue: lineStyleCount) ?? .solid)
        updateAnnotation()
    }

    @IBAction func lineTypeButtonAction(_ sender: NSButton) {
        let tag = sender.tag
        
        switch tag {
        case 0:
            lineStyleCount = 0
            refreshLineTypeUI()
            lineStyleButton.image = borderStyleSolid(true)
            dottedLineStyleButton.image = borderStyleDashed(false)
            rightArrowStyleButton.image = lineStyleRightArrow(false)
            lineTypePopAction()
            
        case 1:
            lineStyleCount = 1
            refreshLineTypeUI()
            lineStyleButton.image = borderStyleSolid(false)
            dottedLineStyleButton.image = borderStyleDashed(true)
            rightArrowStyleButton.image = lineStyleRightArrow(false)
            lineTypePopAction()
            
        case 2:
            lineStyleCount = 2
            refreshLineTypeUI()
            lineStyleButton.image = borderStyleSolid(false)
            dottedLineStyleButton.image = borderStyleDashed(false)
            rightArrowStyleButton.image = lineStyleRightArrow(true)
            
            for tAnnotation in annotations {
                if tAnnotation is CPDFLineAnnotation {
                    (tAnnotation as! CPDFLineAnnotation).endLineStyle = .closedArrow
                }
            }
            
        default:
            break
        }
    }
    
    @IBAction func iconButtonAction(_ sender: NSButton) {
        var type: CPDFTextAnnotationIconType = .comment
        
        switch sender.tag {
        case 0:
            type = .comment
        case 1:
            type = .key
        case 2:
            type = .note
        case 3:
            type = .help
        case 4:
            type = .newParagraph
        case 5:
            type = .paragraph
        case 6, _:
            type = .insert
        }
        
        if annotationModel?.annotations != nil {
            for tAnnotation in self.annotations {
                if tAnnotation is CPDFTextAnnotation {
                    (tAnnotation as! CPDFTextAnnotation).setIconType(type)
                }
            }
        } else {
            annotationModel?.setAnchoredIconType(type)
        }
        
        generalImageView.image = annotationModel?.annotationImage
        updateannotationMode()
        
        clickAnnotationTextIconButtonAction(iconType: UInt(sender.tag), boxArr: iconButtonArray)
    }
    
    @IBAction func textImageBoxButtonAction(_ sender: Any) {
        openFreeTextStylesViewController()
    }
    
    // MARK: Font、FontSize Action
    
    @IBAction func fontButtonAction(_ sender: NSButton) {
        let fontWindowController = KMAnnotationFontWindowController.sharedAnnotationFont
        let window = fontWindowController.window
        fontWindowController.annotations = annotations
        fontWindowController.annotationAlignCallback = { [weak self] selectedCount in
            var alignmentType: KMFreeTextAnnotationAlignmentType = .left
            if selectedCount == NSTextAlignment.left.rawValue {
                alignmentType = .left
            } else if selectedCount == NSTextAlignment.center.rawValue {
                alignmentType = .center
            } else if selectedCount == NSTextAlignment.right.rawValue {
                alignmentType = .right
            }
            self!.alignmentTypeSelected(alignmentType)
        }
        
        fontWindowController.annotationCallback = { [weak self] annotation in
            if annotation is CPDFFreeTextAnnotation {
                if let family = (annotation as! CPDFFreeTextAnnotation).font?.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
                   let style = (annotation as! CPDFFreeTextAnnotation).font?.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
                    
                    DispatchQueue.main.async {
                        let selectedStyleIndex = self!.setFontStyle(fontName: family, currentStyle: style)
                        self!.fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
                    }
                    
                    DispatchQueue.global(qos: .default).async {
                        let fonts = NSFontManager.shared.availableFontFamilies
                        let menu = NSMenu()
                        var selectedIndex = 0
                        
                        for (index, fontName) in fonts.enumerated() {
                            if let font = NSFont(name: fontName, size: 12.0) {
                                let attributedString = NSAttributedString(string: fontName, attributes: [.font: font])
                                let item = NSMenuItem()
                                item.attributedTitle = attributedString
                                menu.addItem(item)
                                if (annotation as! CPDFFreeTextAnnotation).font?.fontName == font.fontName {
                                    selectedIndex = index
                                }
                            }
                        }
                        DispatchQueue.main.async {
                            self!.fontPopUpButton.menu = menu
                            self!.fontPopUpButton.selectItem(at: selectedIndex)
                        }
                    }
                }
            }
        }
        
        window?.orderFront(sender)
    }
    
    @IBAction func fontPopUpButtonAction(_ sender: NSPopUpButton) {
        guard let selectedItem = fontPopUpButton.selectedItem else { return }
        
        let resultAtt = NSMutableAttributedString(attributedString: selectedItem.attributedTitle!)
        let familyString = resultAtt.string
        let selectIndex = setFontStyle(fontName: familyString, currentStyle: nil)
        guard let styleString = fontStylePopUpButton.selectedItem?.title else { return }
        
        fontStylePopUpButton.selectItem(at: Int(selectIndex))
        
        if annotationModel?.annotations != nil {
            for tAnnotation in annotations {
                if tAnnotation is CPDFFreeTextAnnotation {
                    let newAnnotation = (tAnnotation as! CPDFFreeTextAnnotation)
                    if let font = newAnnotation.font {
                        if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? String {
                            let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
                            if let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSize.stringToCGFloat()) {
                                newAnnotation.font = newFont
                            }
                        }
                        
                        if let tFont = newAnnotation.font {
                            if let family = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
                               let style = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
                                DispatchQueue.main.async {
                                    let selectedStyleIndex = self.setFontStyle(fontName: family, currentStyle: style)
                                    self.fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
                                }
                            }
                        }
                    }
                } else if tAnnotation is KMSelfSignAnnotationFreeText {
                    let newAnnotation = (tAnnotation as! KMSelfSignAnnotationFreeText)
                    if let font = newAnnotation.font {
                        if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? String {
                            let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
                            if let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSize.stringToCGFloat()) {
                                newAnnotation.font = newFont
                            }
                        }
                        
                        newAnnotation.updateBounds()
                        
                        if let tFont = newAnnotation.font {
                            if let family = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
                               let style = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
                                DispatchQueue.main.async {
                                    let selectedStyleIndex = self.setFontStyle(fontName: family, currentStyle: style)
                                    self.fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
                                }
                            }
                        }
                    }
                }
            }
        } else {
            if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
                let font = NSFont(name: (annotationModel?.fontName())!, size: (annotationModel?.fontSize())!) ?? NSFont.systemFont(ofSize: 16)
                if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? String {
                    let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
                    if let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSize.stringToCGFloat()) {
                        annotationModel?.setFontName(newFont.fontName)
                        annotationModel?.setFontSize(newFont.pointSize)
                    }
                }
                
                let tFont = NSFont(name: (annotationModel?.fontName())!, size: (annotationModel?.fontSize())!) ?? NSFont.systemFont(ofSize: 16)
                if let family = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
                   let style = tFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
                    DispatchQueue.main.async {
                        let selectedStyleIndex = self.setFontStyle(fontName: family, currentStyle: style)
                        self.fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
                    }
                }
            }
        }
        updateAnnotation()
    }
    
    @IBAction func fontSizeComboBoxAction(_ sender: NSComboBox) {
        if annotationModel?.annotations != nil {
            for tAnnotation in annotations {
                if tAnnotation is CPDFFreeTextAnnotation {
                    let newAnnotation = (tAnnotation as! CPDFFreeTextAnnotation)
                    if let font = newAnnotation.font {
                        let newFont = NSFont(name: font.fontName, size: CGFloat(fontSizeComboBox.floatValue))
                        if let newFont = newFont {
                            newAnnotation.font = newFont
                        }
                    }
                } else if tAnnotation is KMSelfSignAnnotationFreeText {
                    let newAnnotation = (tAnnotation as! KMSelfSignAnnotationFreeText)
                    if let font = newAnnotation.font {
                        let newFont = NSFont(name: font.fontName, size: CGFloat(fontSizeComboBox.floatValue))
                        if let newFont = newFont {
                            newAnnotation.font = newFont
                        }
                    }
                    newAnnotation.updateBounds()
                }
            }
        } else {
            if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
                let font = NSFont(name: (annotationModel?.fontName()!)!, size: (annotationModel?.fontSize())!) ?? NSFont.systemFont(ofSize: 16)
                let newFont = NSFont(name: font.fontName, size: CGFloat(fontSizeComboBox.floatValue))
                if let newFont = newFont {
                    annotationModel?.setFontName(newFont.fontName)
                    annotationModel?.setFontSize(newFont.pointSize)
                }
            }
        }
        updateAnnotation()
        NotificationCenter.default.post(name: NSNotification.Name("KMAnnotationFontTypeNotification"),
                                        object: pdfView)
        adjustFreeText()
    }
    
    //字重 NSFontWeight
    @IBAction func fontStylePopUpButtonAction(_ sender: NSPopUpButton) {
        if let styleString = self.fontStylePopUpButton.selectedItem?.title {
            if annotationModel?.annotations != nil {
                for tAnnotation in self.annotations {
                    if tAnnotation is CPDFFreeTextAnnotation {
                        let newAnnotation = (tAnnotation as! CPDFFreeTextAnnotation)
                        if let font = newAnnotation.font {
                            if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? String,
                               let familyString = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String {
                                
                                let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
                                if let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSize.stringToCGFloat()) {
                                    newAnnotation.font = newFont
                                }
                            }
                        }
                    } else if tAnnotation is KMSelfSignAnnotationFreeText {
                        let newAnnotation = (tAnnotation as! KMSelfSignAnnotationFreeText)
                        if let font = newAnnotation.font {
                            if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? String,
                               let familyString = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String {
                                
                                let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
                                if let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSize.stringToCGFloat()) {
                                    newAnnotation.font = newFont
                                }
                                newAnnotation.updateBounds()
                            }
                        }
                    }
                }
            } else {
                if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
                    let font = NSFont(name: (annotationModel?.fontName())!, size: (annotationModel?.fontSize())!) ?? NSFont.systemFont(ofSize: 16)
                    if let fontSize = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.size) as? String,
                       let familyString = font.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String {
                        
                        let attributeFontDescriptor = NSFontDescriptor(fontAttributes: [NSFontDescriptor.AttributeName.family: familyString, NSFontDescriptor.AttributeName.face: styleString])
                        if let newFont = NSFont(descriptor: attributeFontDescriptor, size: fontSize.stringToCGFloat()) {
                            annotationModel?.setFontName(newFont.fontName)
                            annotationModel?.setFontSize(newFont.pointSize)
                        }
                    }
                }
            }
        }
        updateAnnotation()
    }
    
    @IBAction func buttonClicked_SwitchIncludeTime(_ sender: NSButton) {
        for case let tAnnotation as KMSelfSignAnnotationFreeText in annotations {
            tAnnotation.includeTime = sender.state == .on ? true : false
            
            let index = datePopUpButton.indexOfSelectedItem
            datePopUpButton.removeAllItems()
            datePopUpButton.addItems(withTitles: KMSelfSignAnnotationFreeText.fetchAllDateString(includeTime: false))
            datePopUpButton.selectItem(at: index)
            
            if self.subType == .date && isannotationMode {
                UserDefaults.standard.set(sender.state == .on ? true : false, forKey: SKAnnotationSelfSignDateFormatterIncludeTimeKey)
            }
        }
        reloadData()
    }
    
    @IBAction func dateCheckButtonAction(_ sender: NSPopUpButton) {
        for case let tAnnotation as KMSelfSignAnnotationFreeText in annotations {
            if subType == .date && isannotationMode {
                let fetchArray = KMSelfSignAnnotationFreeText.fetchAllDateString(includeTime: false)
                if sender.indexOfSelectedItem >= 0 && sender.indexOfSelectedItem <= fetchArray.count - 1 {
                    UserDefaults.standard.set(sender.indexOfSelectedItem, forKey: SKAnnotationSelfSignDateFormatterKey)
                }
            }
            tAnnotation.dateFormatIndex = sender.indexOfSelectedItem
        }
        reloadData()
    }
    
    func annotationFontReload() {
        DispatchQueue.global(qos: .default).async { [self] in
            let fonts = NSFontManager.shared.availableFontFamilies
            let menu = NSMenu()
            var selectedIndex = 0
            
            for (index, fontName) in fonts.enumerated() {
                if let font = NSFont(name: fontName, size: 12.0) {
                    let attributedString = NSAttributedString(string: fontName, attributes: [NSAttributedString.Key.font: font])
                    let item = NSMenuItem()
                    item.attributedTitle = attributedString
                    menu.addItem(item)
                    
                    if annotationType == .freeText {
                        if annotationModel?.fontName() == font.fontName {
                            selectedIndex = index
                        }
                    }
                }
            }
            
            if annotationType == .freeText {
                let freetextFont = NSFont(name: (annotationModel?.fontName() as? String)!, size: 16) ?? NSFont.systemFont(ofSize: 16)
                if let family = freetextFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.family) as? String,
                   let style = freetextFont.fontDescriptor.object(forKey: NSFontDescriptor.AttributeName.face) as? String {
                    
                    DispatchQueue.main.async { [self] in
                        fontPopUpButton.menu = menu
                        fontPopUpButton.selectItem(at: selectedIndex)
                        
                        let selectedStyleIndex = setFontStyle(fontName: family, currentStyle: style)
                        fontStylePopUpButton.selectItem(at: Int(selectedStyleIndex))
                    }
                }
            }
        }
    }
    
    func adjustFreeText() {
        if annotationModel?.annotations != nil {
            if annotationType == .freeText || annotationType == .signText || annotationType == .signDate {
                for an in (annotationModel?.annotations)! {
                    if let freeTextAn = an as? CPDFFreeTextAnnotation {
                        let font = freeTextAn.font
                        var attributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: font as Any]
                        
                        let style = NSMutableParagraphStyle()
                        style.alignment = freeTextAn.alignment
                        attributes[NSAttributedString.Key.paragraphStyle] = style
                        
                        let contents = freeTextAn.contents ?? ""
                        let textViewSize = contents.boundingRect(with: CGSize(width: freeTextAn.bounds.size.width, height: CGFloat(MAXFLOAT)),
                                                                 options: .usesLineFragmentOrigin,
                                                                 attributes: attributes).size
                        
                        var rect = freeTextAn.bounds
                        
                        if textViewSize.height != freeTextAn.bounds.size.height {
                            rect.origin.y -= (textViewSize.height - rect.size.height)
                            rect.size.height = textViewSize.height
                        }
                        
                        if textViewSize.width < freeTextAn.bounds.size.width {
                            rect.size.width = textViewSize.width
                        }
                        
                        freeTextAn.bounds = rect
                    }
                }
            }
        }
    }
    
    // MARK: NSNotification
    
    @objc func textDidChange(_ notification: Notification) {
        self.isTextEdit = true
        
        if self.subType == KMSelfSignAnnotationFreeTextSubType.freeText && isannotationMode {
            if let obj = notification.object as? NSObject {
                for tAnnotation in annotations {
                    tAnnotation.setString(noteTextView.string)
                }
                
                if obj.isEqual(to: noteTextView) {
                    UserDefaults.standard.set(noteTextView.string, forKey: SKAnnotationSelfSignPlaceHolderStringKey)
                }
                
                if annotation.isKind(of: CPDFFreeTextAnnotation.self) {
                    textAnnotationImageView.image = annotationModel?.annotationImage
                } else {
                    generalImageView.image = annotationModel?.annotationImage
                }
            }
        } else {
            if let obj = notification.object as? NSObject, obj.isEqual(to: noteTextView) {
                for tAnnotation in self.annotations {
                    tAnnotation.setString(noteTextView.string)
                }
            }
        }
    }

    @objc func themeChanged(_ notification: Notification) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [self] in
            updateViewColor()
        }
    }
}

class KMGeneralAnnotationColorButton: NSButton {
    var _circleColor: NSColor = .clear
    var _buttonBorderColor: NSColor = .clear
    
    // MARK: Get & Set
    
    var circleColor: NSColor {
        set {
            _circleColor = newValue
            
            needsDisplay = true
        }
        get {
            return _circleColor
        }
    }
    
    var buttonBorderColor: NSColor {
        set {
            _buttonBorderColor = newValue
            
            needsDisplay = true
        }
        get {
            return _buttonBorderColor
        }
    }
    
    // MARK: Init
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        
        wantsLayer = true
        layer?.cornerRadius = 12.0
        layer?.masksToBounds = true
        layer?.borderColor = NSColor.clear.cgColor
    }
    
    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)
        
        let path3 = NSBezierPath(ovalIn: NSMakeRect(3, 3, dirtyRect.size.width - 6, dirtyRect.size.height - 6))
    }
}

class KMNoteIconButtonCell: NSButtonCell {
    override func drawImage(_ image: NSImage, withFrame frame: NSRect, in controlView: NSView) {
        let titleSize = self.attributedTitle.size()
        let imageSize = self.image!.size
        
        var rect = NSZeroRect
        let leftGap = (controlView.bounds.size.width - image.size.width) / 2.0
        rect.origin.x = leftGap
        
        if self.imagePosition == .imageAbove {
            rect.origin.y = 6
        } else {
            rect.origin.y = (controlView.frame.size.height - image.size.height) / 2.0
        }
        rect.size = imageSize
        super.drawImage(self.image!, withFrame: rect, in: controlView)
    }
    
    override func drawTitle(_ title: NSAttributedString, withFrame frame: NSRect, in controlView: NSView) -> NSRect {
        let titleSize = self.attributedTitle.size()
        let imageSize = self.image!.size
        let totalHeight = titleSize.height + imageSize.height + 1
        
        var rect = NSZeroRect
        rect.origin.x = (controlView.bounds.size.width - titleSize.width) / 2.0
        rect.origin.y = (controlView.bounds.size.height - totalHeight) / 2.0 + imageSize.height + 1
        rect.size = titleSize
        return super.drawTitle(title, withFrame: rect, in: controlView)
    }
}