//
//  KMAnnotationViewController.swift
//  PDF Reader Pro
//
//  Created by lxy on 2022/10/10.
//

import Cocoa

enum KMAnnotationViewShowType: Int {
    case none
    case hidden
}

class KMAnnotationViewController: KMSideViewController {
    @IBOutlet weak var topView: NSView!
    @IBOutlet weak var filtrateButton: NSButton!
    @IBOutlet weak var moreButton: NSButton!
    @IBOutlet weak var markupTitleLabel: NSTextField!
    @IBOutlet weak var emptyView: NSView!
    @IBOutlet weak var bigTipLabel: NSTextField!
    @IBOutlet weak var tipLabel: NSTextField!
    
    @IBOutlet weak var annotationOutlineView: KMAnnotationOutlineView!
    
    var annotations: [KMBOTAAnnotationSection] = [] {
        didSet {
            self.annotationOutlineView.inputData = annotations
            self.updateExtempViewState()
        }
    }
    var screenAnnotations: [KMBOTAAnnotationSection] = [] {
        didSet {
            self.annotations = screenAnnotations
        }
    }
    
    //注释状态
    var annotationShowState: KMAnnotationViewShowType = .none {
        didSet {
            self.reloadData()
        }
    }
    
    var allAnnotations: [CPDFAnnotation] = []
    
    //localEvent
    var localEvent: Bool = false
    
    
    deinit {
        KMPrint("KMAnnotationViewController")
        self.removeNotification()
    }
    //MARK: View
        
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.setup()
        self.updateUI()
        self.updateLanguage()
        self.addNotification()
        self.reloadData()
    }
    
    func setup() {
        self.view.wantsLayer = true
        self.view.layer?.backgroundColor = NSColor.km_init(hex: "#F7F8FA").cgColor
        
        self.emptyView.backgroundColor(NSColor.km_init(hex: "#F7F8FA"))
        
        self.topView.wantsLayer = true
        self.topView.layer?.backgroundColor = NSColor.clear.cgColor
        
        self.annotationOutlineView.outlineView.doubleAction = #selector(tableViewDoubleAction)
        self.annotationOutlineView.delegate = self
    }
    
    func updateUI() {
        self.markupTitleLabel.font = NSFont.SFProTextSemiboldFont(14.0)
        self.markupTitleLabel.textColor = NSColor.km_init(hex: "#252629")
        
        self.bigTipLabel.font = NSFont.SFProTextRegularFont(14.0)
        self.bigTipLabel.textColor = NSColor.km_init(hex: "#616469")
        
        if self.annotationShowState == .none {
            
        } else {
            self.bigTipLabel.font = NSFont.SFProTextRegularFont(12.0)
            self.bigTipLabel.textColor = NSColor.km_init(hex: "#94989C")
        }
    }
    
    func updateLanguage() {
        self.markupTitleLabel.stringValue = NSLocalizedString("Annotation", comment: "")
        
        self.filtrateButton.toolTip = NSLocalizedString("Sort", comment: "")
        self.moreButton.toolTip = NSLocalizedString("More", comment: "")
        

        if self.annotationShowState == .none {
            self.bigTipLabel.stringValue = NSLocalizedString("No Annotations", comment: "")
            
            let title = NSLocalizedString("All annotations will be displayed here.", comment: "")
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineHeightMultiple = 1.32
            paragraphStyle.alignment = .center
            self.tipLabel.attributedStringValue = NSMutableAttributedString(string: title, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle, .foregroundColor : NSColor.km_init(hex: "#94989C"), NSAttributedString.Key.font: NSFont.SFProTextRegularFont(12)])
        } else {
            self.bigTipLabel.stringValue = NSLocalizedString("The Annotations are hidden", comment: "")
            self.tipLabel.stringValue = ""
        }
    }
    
    func addNotification() {
        NotificationCenter.default.addObserver(self, selector: #selector(documentPageCountChangedNotification), name: NSNotification.Name.init(rawValue: "CPDFDocumentPageCountChangedNotification"), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(CPDFListViewActiveAnnotationsChangeNotification), name: NSNotification.Name.init(rawValue: "CPDFListViewActiveAnnotationsChangeNotification"), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(CPDFListViewAnnotationsAttributeHasChangeNotification), name: NSNotification.Name.init(rawValue: "CPDFListViewAnnotationsAttributeHasChangeNotification"), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(reloadDataAfter), name: NSNotification.Name.init(rawValue: "CPDFPageDidAddAnnotationNotification"), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(reloadDataAfter), name: NSNotification.Name.init(rawValue: "CPDFPageDidRemoveAnnotationNotification"), object: nil)
    }
    
    func removeNotification() {
        NotificationCenter.default.removeObserver(self)
    }
    
    public func clear() {
        self.annotations.removeAll()
        self.annotationOutlineView.reloadData()
    }
}

//MARK: Data
extension KMAnnotationViewController {
    @objc public func reloadData() {
//        self.reloadAnnotation()
//        self.annotationSort(sortArray: [])
    }
    
    func reloadAnnotation() {
        if self.listView != nil {
            var dataArray: [KMBOTAAnnotationSection] = []
            var annotationArray: [CPDFAnnotation] = []
            for i in 0 ..< self.pageCount() {
                var annotationItemArray: [KMBOTAAnnotationItem] = []
                let page = self.pdfDocument()?.page(at: UInt(i))
                let types = ["Highlight","Underline","Strikeout","Freehand","FreeText","Note","Square","Circle","Line","Stamp","Arrow","Image","Redact","Sign"]
                var pageAnnotations: [CPDFAnnotation] = KMOCToolClass.filterAnnotation(annotations: page!.annotations,types: types) as! [CPDFAnnotation]
                //添加签名注释
                for annotation in page!.annotations {
                   if annotation.isKind(of: CPDFSignatureAnnotation.self) {
                       pageAnnotations.append(annotation)
                   }
                }
                
                for annotation in pageAnnotations {
                    if annotation.annotationShouldDisplay() == false {
                        pageAnnotations.removeObject(annotation)
                    }
                }

                //转换所有annotation类型
                let section = KMBOTAAnnotationSection()
                for annotation in pageAnnotations {
                    let item = KMBOTAAnnotationItem()
                    item.section = section
                    item.annotation = annotation
                    item.index = Int(annotation.page.pageIndex())
                    annotationItemArray.append(item)
                }
                
                if annotationItemArray.count != 0 {
                    section.annotations = annotationItemArray
                    section.page = page
                    section.isItemExpanded = true
                    dataArray.append(section)
                }
                
                //添加所有annotation 用于筛选
                annotationArray += pageAnnotations
            }
            
            //转换对象,用于数据显示
            self.annotations = dataArray
            self.allAnnotations = annotationArray
            
            if self.annotations.count < 1 {
               self.filtrateButton.isEnabled = false
            } else {
               self.filtrateButton.isEnabled = true
            }
        }
    }
    
    func annotationSort(sortArray:[[Any]]) {
        if self.listView != nil {
            var typeArr: [Any] = []
            var colorArr: [Any] = []
            var authorArr: [Any] = []
            
            let sud = UserDefaults.standard
            let typeData = sud.object(forKey: "KMNoteOutlineFilterSelectArray_Type" + (self.pdfDocument()?.documentURL.path ?? "")) as? Data
            if typeData != nil {
                typeArr = NSKeyedUnarchiver.unarchiveObject(with: typeData!) as! [Any]
            }
            
            let colorData = sud.object(forKey: "KMNoteOutlineFilterSelectArray_Color" + (self.pdfDocument()?.documentURL.path ?? "")) as? Data
            if colorData != nil {
                colorArr = NSKeyedUnarchiver.unarchiveObject(with: colorData!) as! [Any]
            }
            
            let authorData = sud.object(forKey: "KMNoteOutlineFilterSelectArray_Author" + (self.pdfDocument()?.documentURL.path ?? "")) as? Data
            if authorData != nil {
                authorArr = NSKeyedUnarchiver.unarchiveObject(with: authorData!) as! [Any]
            }
            
            if typeArr.count == 0 && colorArr.count == 0 && authorArr.count == 0 {
                self.filtrateButton.image = NSImage(named: "KMImageNameAnnotationsFiltrate")
                self.reloadAnnotation()
            } else {
                self.filtrateButton.image = NSImage(named: "icon_annotation_screening_select")
                var dataArray: [KMBOTAAnnotationSection] = []
                for i in 0 ..< self.pageCount() {
                    var annotationItemArray: [KMBOTAAnnotationItem] = []
                    let page = self.listView?.document?.page(at: UInt(i))
                    if page!.annotations.count > 0 {
                        var filterAnnotations: [CPDFAnnotation] = page!.annotations
                        if typeArr.count > 0 {
                            filterAnnotations = (KMOCToolClass.filterAnnotation(annotations: filterAnnotations, types: typeArr) as! [CPDFAnnotation])
                        }
                        if (colorArr.count > 0) {
                            filterAnnotations = (KMOCToolClass.filterAnnotation(annotations: filterAnnotations,colors: colorArr) as! [CPDFAnnotation])
                        }
                        if (authorArr.count > 0) {
                            filterAnnotations = (KMOCToolClass.filterAnnotation(annotations: filterAnnotations,authors: authorArr) as! [CPDFAnnotation])
                        }
                        
                        let section = KMBOTAAnnotationSection()
                        for annotation in filterAnnotations {
                            let item = KMBOTAAnnotationItem()
                            item.section = section
                            item.annotation = annotation
                            item.index = Int(page!.pageIndex())
                            annotationItemArray.append(item)
                        }
                        
                        if annotationItemArray.count != 0 {
                            section.annotations = annotationItemArray
                            section.page = page
                            section.isItemExpanded = true
                            dataArray.append(section)
                        }
                    }
                }
                
                self.annotations = dataArray
            }
        }
    }
}

//MARK: reloadData
extension KMAnnotationViewController {
    func updateExtempViewState() {
        if self.emptyView != nil {
            var hidden = false
            if self.annotationOutlineView.outlineView.numberOfRows != 0 {
                hidden = true
            }
            self.emptyView.isHidden = hidden
            self.annotationOutlineView.isHidden = !hidden
            //刷新
            self.updateUI()
            self.updateLanguage()
        }
    }
}

//MARK: Notification
extension KMAnnotationViewController {
    @objc public func reloadDataAfter() {
        if !localEvent {
            let rect = self.annotationOutlineView.outlineView.visibleRect
            self.reloadData()
            self.annotationOutlineView.outlineView.scrollToVisible(rect)
        }
//        localEvent = false
    }

    @objc func documentPageCountChangedNotification(notification: NSNotification) {
        if notification.object is CPDFDocument {
            let pdfdocument : CPDFDocument = notification.object as! CPDFDocument
            if pdfdocument.isEqual(self.listView?.document) {
                if !localEvent {
                    self.reloadData()
                }
    //            localEvent = false
            }
        }
    }

    @objc func CPDFListViewActiveAnnotationsChangeNotification(notification: NSNotification) {
        if notification.object is CPDFListView {
            let listView : CPDFListView = notification.object as! CPDFListView
            if listView.isEqual(self.listView) {
                if self.listView?.activeAnnotations.count == 0 {
                    self.escButtonAction(Any.self)
                } else {
                    if !localEvent {
                        let tempAnnotations : [CPDFAnnotation] = self.listView?.activeAnnotations as! [CPDFAnnotation]
                        var indexset = IndexSet()
                        for annotation in tempAnnotations {
                            if self.annotations.count > 0 {
                                for section in self.annotations {
                                    for item in section.annotations! {
                                        if item.annotation == annotation {
                                            let index = self.annotationOutlineView.outlineView.row(forItem: item)
                                            indexset.insert(index)
                                        }
                                    }
                                }
                            }
                        }

                        if indexset.count != 0 && indexset.first != -1 {
                            self.annotationOutlineView.outlineView.selectRowIndexes(indexset, byExtendingSelection: false)
                            self.annotationOutlineView.didSelectItem(view: nil, event: NSEvent(), isNeedDelegate: false)
                        }
                    }
    //                localEvent = false
                }
            }
        }
    }

    @objc func CPDFListViewAnnotationsAttributeHasChangeNotification(notification: NSNotification) {
        if notification.object != nil {
            let dic = notification.object as? NSDictionary
            if dic?["keyPath"] as! String != CPDFAnnotationBoundsKey &&
                dic?["keyPath"] as! String != CPDFAnnotationStartPointKey &&
                dic?["keyPath"] as! String != CPDFAnnotationEndPointKey{
                if dic?["object"] is CPDFAnnotation {
                    let annotation : CPDFAnnotation = dic?["object"] as? CPDFAnnotation ?? CPDFAnnotation()
                    for section in self.annotations {
                        for (_, item) in section.annotations!.enumerated() {
                            if item.annotation == annotation {
                                let row = self.annotationOutlineView.outlineView.row(forItem: item)
                                let indexSet = IndexSet.init(integer: row)
                                self.annotationOutlineView.outlineView.noteHeightOfRows(withIndexesChanged: indexSet)
                                self.annotationOutlineView.outlineView.reloadItem(item)
                                break
                            }
                        }
                    }
                }
            }
        }
    }
}

//MARK: Action
extension KMAnnotationViewController {
    @IBAction func tableViewDoubleAction(_ sender: Any) {
        if self.annotationOutlineView.selectItems.count > 1 {
            return
        }
        let selectedRow = self.annotationOutlineView.outlineView.selectedRow
        if selectedRow >= 0 {
            let annotationItem = self.annotationOutlineView.outlineView.item(atRow: selectedRow)
            if (annotationItem is KMBOTAAnnotationItem) {
                let annotation = (annotationItem as! KMBOTAAnnotationItem).annotation
                self.listView?.go(to: annotation!.bounds, on: annotation!.page, animated: true)
            }
        }
    }

    @IBAction func moreButtonAction(_ sender: NSButton) {
        self.addMoreMenu(sender: sender)
    }

    @IBAction func filtrateButtonAction(_ sender: NSButton) {
        let menu = NSMenu()
        let annotationScreenView = KMAnnotationScreenCollectionView(frame: CGRect(x: 0, y: 0, width: 304, height: 296))
        annotationScreenView.path = self.listView?.document.documentURL.path ?? ""
        annotationScreenView.annotations = self.allAnnotations
        annotationScreenView.applyAction = { [unowned self] (view, typeArray, colorArray, authArray) in
            menu.cancelTracking()
            self.annotationSort(sortArray: [typeArray, colorArray, authArray])
        }
        
        annotationScreenView.cancelAction = { [unowned self] view in
            menu.cancelTracking()
        }
            
        let item = menu.addItem(withTitle: "", action: nil, keyEquivalent: "")
        item.target = self
//        item.representedObject = filterVC
        item.view = annotationScreenView
        menu.popUp(positioning: nil, at: CGPoint(x: -130, y: 30), in: sender)
    }

    @IBAction func deleteButtonAction(_ sender: Any) {
        let alert = NSAlert()
        alert.alertStyle = .critical
        alert.messageText = NSLocalizedString("This will permanently remove all annotations. Are you sure to continue?", comment: "")
        alert.informativeText = NSLocalizedString("You cannot undo this operation.", comment: "")
        alert.addButton(withTitle: NSLocalizedString("Yes", comment: ""))
        alert.addButton(withTitle: NSLocalizedString("No", comment: ""))
        alert.beginSheetModal(for: self.view.window!, completionHandler: { result in
            if result == .OK {
                for i in 0 ..< self.pageCount() {
                    let page = self.listView?.document?.page(at: UInt(i))
                    page?.removeAllAnnotations()
                }
//                let undoManager : UndoManager = self.mainWindowController.document?.undoManager ?? UndoManager()
//                undoManager.setActionName("")
                self.listView?.updateActiveAnnotations([CPDFAnnotation()])
                self.listView?.setNeedsDisplayForVisiblePages()
                self.reloadData()
            }
        })
    }
//
    @IBAction func flattenButtonAction(_ sender: NSMenuItem) {
        let selects = sender.representedObject as! NSIndexSet
        var indexs : [Int] = []
        for index in selects {
            indexs.append(index)
        }

        if selects.count == 1 {
            let index = selects.firstIndex
            let annotationItem: KMBOTAAnnotationItem = self.annotationOutlineView.outlineView.item(atRow: index) as! KMBOTAAnnotationItem
            if annotationItem.annotation != nil {
                if annotationItem.annotation!.contents?.lengthOfBytes(using: String.Encoding(rawValue: String.Encoding.utf16.rawValue)) ?? 0 > 0 {
                    var content: String = annotationItem.annotation!.contents!
                    let item: CPDFMarkupAnnotation = annotationItem.annotation! as? CPDFMarkupAnnotation ?? CPDFMarkupAnnotation()
                    if item.markupText() != nil {
                        KMPrint(item.markupText() as Any)
                        content = content + "\n" + item.markupText()
                    }

                    let pasteBoard = NSPasteboard.general
                    pasteBoard.clearContents()
                    pasteBoard.setString(content, forType: .string)
                }
            }
        }
    }
//
    @IBAction func exportItemAction(_ sender: Any) {
        let panel = NSSavePanel()
        panel.nameFieldStringValue = "\(NSLocalizedString("Untitled", comment: "")).xfdf"
        panel.isExtensionHidden = true
        let response = panel.runModal()
        if response == .OK {
            let url = panel.url
            let result = self.listView?.document.exportAnnotation(toXFDFPath: url!.path) ?? false
            if result {
//                NSWorkspace.shared.openFile(url!.path.deletingLastPathComponent)
//                NSWorkspace.shared.open(url!)
                
                let filePath = url!.path // 要打开的文件路径
                let fileURL = URL(fileURLWithPath: filePath)
                let fileDirectoryURL = fileURL.deletingLastPathComponent() // 获取文件所在的文件夹路径

                NSWorkspace.shared.activateFileViewerSelecting([fileDirectoryURL])
            }
        }
    }
//
    @IBAction func importItemAction(_ sender: Any) {
        let panel = NSOpenPanel()
        panel.allowsMultipleSelection = false
        panel.allowedFileTypes = ["xfdf"]
        panel.beginSheetModal(for: NSApp.mainWindow!) { response in
            if response == .OK {
                let openPath = panel.url?.path
                let result = self.listView?.document.importAnnotation(fromXFDFPath: openPath!) ?? false
                if result {
                    self.listView?.setNeedsDisplayAnnotationViewForVisiblePages()
                    self.reloadData()
                }
            }
        }
    }
//
    @IBAction func deleteItemAction(_ sender: NSMenuItem) {
        let selects = sender.representedObject as! NSIndexSet
        var indexs : [KMBOTAAnnotationItem] = []
        for index in selects {
            if self.annotationOutlineView.outlineView.item(atRow: index) is KMBOTAAnnotationItem {
                let annotationItem: KMBOTAAnnotationItem = self.annotationOutlineView.outlineView.item(atRow: index) as! KMBOTAAnnotationItem
                annotationItem.index = index
                indexs.append(annotationItem)
            }
        }
        indexs.sort(){$0.index! > $1.index!}

        self.deleteAnnotations(annotationItems: indexs)
    }
//
    @IBAction func deleteAllAnonationAction(_ sender: NSMenuItem) {
        let alter = NSAlert()
        alter.alertStyle = NSAlert.Style.informational
        alter.messageText = NSLocalizedString("This will permanently remove all annotations. Are you sure to continue?", comment: "")
        alter.addButton(withTitle: NSLocalizedString("Yes", comment:""))
        alter.addButton(withTitle: NSLocalizedString("No", comment:""))
        let modlres = alter.runModal()
        if modlres == NSApplication.ModalResponse.alertFirstButtonReturn {
//            for i in 0 ..< self.listView.document.pageCount {
//                let page = self.listView.document.page(at: i)
//                for annotation in page!.annotations {
//                    page?.removeAnnotation(annotation)
//
//                }
//            }
//            self.listView.setNeedsDisplayForVisiblePages()
//            self.reloadData()
            var indexs : [KMBOTAAnnotationItem] = []
            for section in self.annotations {
                indexs.append(contentsOf: section.annotations!)
            }
            indexs.sort(){$0.index! > $1.index!}

            self.deleteAnnotations(annotationItems: indexs)
        }
    }
//
    @IBAction func escButtonAction(_ sender: Any) {
        self.cancelSelect()
    }
//
    func cancelSelect() {
        self.annotationOutlineView.cancelSelect()
    }
//
    func selectItem(index: Int) {
        self.annotationOutlineView.outlineView.selectRowIndexes(IndexSet(integer: index), byExtendingSelection: false)
        self.annotationOutlineView.didSelectItem(view: nil, event: NSEvent(), isNeedDelegate: false)
    }

    func updateListViewData(annotationItems: [KMBOTAAnnotationItem]) {
        if annotationItems.count > 0 {
            if annotationItems.count == 1 {
                let annotationItem = annotationItems.first!
                if annotationItem.annotation != nil {
                    self.listView?.go(to: annotationItem.annotation!.bounds, on: annotationItem.annotation!.page, animated: true)
                }
            }
            
            var annotations: [CPDFAnnotation] = []
            for item in annotationItems {
                if item.annotation != nil {
                    annotations.append(item.annotation!)
                }
            }
            self.listView?.updateActiveAnnotations(annotations)
            self.listView?.setNeedsDisplayAnnotationViewForVisiblePages()
        }
    }
}

extension KMAnnotationViewController: KMAnnotationOutlineViewDelegate {
    func annotationOutlineView(_ outlineView: KMAnnotationOutlineView, rightMouseDownDidSelectView: NSView, evnet: NSEvent) {
        self.addRightMenuItem(view: rightMouseDownDidSelectView, event: evnet)
    }
    
    func annotationOutlineView(_ outlineView: KMAnnotationOutlineView, didReloadData: KMBOTAOutlineItem) {
        
    }
    
    func annotationOutlineView(_ outlineView: KMAnnotationOutlineView, didSelectItem: [KMBOTAAnnotationItem]) {
        self.localEvent = true
        self.updateListViewData(annotationItems: didSelectItem)
        self.localEvent = false
    }
}

//MARK: Menu
extension KMAnnotationViewController : NSMenuDelegate, NSMenuItemValidation {
    @objc private func expandAllComments(sender:NSMenuItem) {
        self.annotationOutlineView.expandAllComments(item: sender)
    }
    
    @objc private func collapseAllComments(sender:NSMenuItem) {
        self.annotationOutlineView.collapseAllComments(item: sender)
    }
    
//    @objc private func expandAllComments(sender:NSMenuItem) {
//        if sender.tag == 0 {
//            self.annotationOutlineView.expandAllComments(item: sender)
//        } else if sender.tag == 1 {
//            self.annotationOutlineView.collapseAllComments(item: sender)
//        } else if sender.tag == 2 {
//            let alter = NSAlert()
//            alter.alertStyle = NSAlert.Style.informational
//            alter.messageText = NSLocalizedString("This will permanently remove all outlines. Are you sure to continue?", comment: "")
//            alter.addButton(withTitle: NSLocalizedString("Yes", comment:""))
//            alter.addButton(withTitle: NSLocalizedString("No", comment:""))
//            let modlres = alter.runModal()
//            if modlres == NSApplication.ModalResponse.alertFirstButtonReturn {
//                self.deleteAllAnonationAction(sender)
//            }
//        }
//    }

    func addRightMenuItem(view: NSView, event: NSEvent) {
        let menu = NSMenu()
        menu.delegate = self
        let selectedRowIndexes = self.annotationOutlineView.outlineView.selectedRowIndexes
        var menuItem = NSMenuItem()
        if selectedRowIndexes.count == 1 {
            let item: KMBOTAAnnotationItem = self.annotationOutlineView.outlineView.item(atRow: selectedRowIndexes.first!) as! KMBOTAAnnotationItem
            if item.annotation != nil {
                if item.annotation!.contents != nil {
                    if item.annotation!.contents.count > 0 {
                        menuItem = menu.addItem(withTitle: NSLocalizedString("Copy Text", comment: ""), action: #selector(flattenButtonAction), target: self)!
                        menuItem.representedObject = selectedRowIndexes
                        menu.addItem(NSMenuItem.separator())
                    }
                }
            }
        }

        menuItem = menu.addItem(withTitle: NSLocalizedString("Export Annotation", comment: ""), action: #selector(exportItemAction), target: self)!
        if self.annotationOutlineView.selectItems.count == 1 {
            menuItem = menu.addItem(withTitle: NSLocalizedString("Import Annotation", comment: ""), action: #selector(importItemAction), target: self)!
        }
        menu.addItem(NSMenuItem.separator())

        menuItem = menu.addItem(withTitle: NSLocalizedString("Delete", comment: ""), action: #selector(deleteItemAction), target: self)!
        menuItem.representedObject = selectedRowIndexes
        menu.addItem(NSMenuItem.separator())
    
        let point = view.convert(event.locationInWindow, from: nil)
        menu.popUp(positioning: nil, at: point, in: view)
    }
    
    func addMoreMenu(sender: NSView) {
        let moreMenu = NSMenu()
        _ = moreMenu.addItem(withTitle:  NSLocalizedString("Expand All", comment: ""), action: #selector(expandAllComments), target: self, tag: 0)
        _ = moreMenu.addItem(withTitle:  NSLocalizedString("Collapse All", comment: ""), action: #selector(collapseAllComments), target: self, tag: 1)
//        let soreItem = moreMenu.addItem(withTitle:  NSLocalizedString("Sort", comment: ""), action: nil, target: self)
//        let soreMenu = NSMenu()
//        soreMenu.addItem(withTitle:  NSLocalizedString("Page", comment: ""), action: #selector(expandAllComments), target: self, tag: 0)
//        soreMenu.addItem(withTitle:  NSLocalizedString("Chronologically - ascending", comment: ""), action: #selector(expandAllComments), target: self, tag: 1)
//        soreMenu.addItem(withTitle:  NSLocalizedString("Chronologically - reverse", comment: ""), action: #selector(expandAllComments), target: self, tag: 0)
//        soreItem?.submenu = soreMenu
        _ = moreMenu.addItem(withTitle:  NSLocalizedString("Import Annotations", comment: ""), action: #selector(importItemAction), target: self)
        _ = moreMenu.addItem(withTitle:  NSLocalizedString("Export Annotations to XFDF", comment: ""), action: #selector(exportItemAction), target: self)
        _ = moreMenu.addItem(withTitle:  NSLocalizedString("Remove All Annotations", comment: ""), action: #selector(deleteAllAnonationAction), target: self)
        let rect = sender.convert(sender.bounds, to: self.view)
        moreMenu.popUp(positioning: nil, at: NSPoint(x: rect.origin.x, y: rect.origin.y-10), in: self.view)
    }
    
    func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
        let action = menuItem.action
        if (action == #selector(undo)) {
            return self.listView?.undoManager?.canUndo ?? false
        }
        if (action == #selector(redo)) {
            return self.listView?.undoManager?.canRedo ?? false
        }

        if (action == #selector(flattenButtonAction)) {
            if self.annotationOutlineView.selectItems.count != 1 {
                return false
            }
        }

        if (action == #selector(deleteAllAnonationAction)) {
            if self.annotations.count == 0 {
                return false
            }
        }
        
        if action == #selector(exportItemAction) {
            if self.annotations.count == 0 {
                return false
            }
        }
        
        if action == #selector(exportItemAction) {
            if self.annotations.count == 0 {
                return false
            }
        }
        
        if (action == #selector(expandAllComments)) {
            var canExpand = false
            for row in 0..<self.annotationOutlineView.outlineView.numberOfRows {
                // 检查当前项目是否可以展开
                let item = self.annotationOutlineView.outlineView.item(atRow: row)
                if self.annotationOutlineView.outlineView.isExpandable(item) {
                    if !self.annotationOutlineView.outlineView.isItemExpanded(item) {
                        canExpand = true
                        break
                    }
                }
            }
            return canExpand
        }
        
        if (action == #selector(collapseAllComments)) {
            var canCollapse = false
            for row in 0..<self.annotationOutlineView.outlineView.numberOfRows {
                let item = self.annotationOutlineView.outlineView.item(atRow: row)
                if self.annotationOutlineView.outlineView.isExpandable(item) {
                    if self.annotationOutlineView.outlineView.isItemExpanded(item) {
                        canCollapse = true
                        break
                    }
                }
            }
            return canCollapse
        }
        
        return true
    }
}

//MARK: undo Redo
extension KMAnnotationViewController {
    func deleteAnnotations(annotationItems: [KMBOTAAnnotationItem]) {
        self.removeNotification()
        self.localEvent = true
        
        var removeAnnotations: [Any] = []
        var tempAnnotations: [KMBOTAAnnotationItem] = []
        for annotationItem in annotationItems {
            let annotation = annotationItem.annotation
            annotationItem.index = annotationItem.section?.annotations?.firstIndex(of: annotationItem)
            let page = annotation?.page
            if ((page?.annotations.contains(annotation!)) != nil) {
                page?.removeAnnotation(annotation)
                annotationItem.section?.annotations?.removeObject(annotationItem)
            } else {
                KMPrint("不存在")
            }
            
            if let data = self.listView?.activeAnnotations.contains(annotation!), data {
                removeAnnotations.append(annotation!)
            }
            
            if annotation != nil {
                tempAnnotations.append(annotationItem)
            }
        }
        
        if removeAnnotations.count != 0 {
            self.listView?.activeAnnotations.remove(removeAnnotations)
        }
        self.listView?.setNeedsDisplayForVisiblePages()
        
        self.annotationOutlineView.reloadData(expandItemType: .none)
        self.updateExtempViewState()
        self.listView?.undoManager?.registerUndo(withTarget: self) { [unowned self] targetType in
            self.addAnnotations(annotationItems: tempAnnotations)
        }
        
        self.addNotification()
        self.localEvent = false
    }
    
    func addAnnotations(annotationItems: [KMBOTAAnnotationItem]) {
        self.removeNotification()
        self.localEvent = true
        
        var tempAnnotationItems: [KMBOTAAnnotationItem] = annotationItems
        tempAnnotationItems.sort(){$0.index ?? 0 < $1.index ?? 0}
        
        for annotationItem in tempAnnotationItems {
            if !annotationItem.annotation!.page.annotations.contains(annotationItem.annotation!) {
                annotationItem.annotation?.page.addAnnotation(annotationItem.annotation!)
                annotationItem.section?.annotations?.insert(annotationItem, at: annotationItem.index ?? 0)
            }
        }
        
        self.listView?.setNeedsDisplayForVisiblePages()
        self.annotationOutlineView.reloadData(expandItemType: .none)
        
        if tempAnnotationItems.count != 0 {
            let row = self.annotationOutlineView.outlineView.row(forItem: tempAnnotationItems.last)
            self.annotationOutlineView.outlineView.scrollRowToVisible(row)
        }
        
        self.updateExtempViewState()
        
        let tempAnnotations: [KMBOTAAnnotationItem] = tempAnnotationItems
        self.listView?.undoManager?.registerUndo(withTarget: self) { [unowned self] targetType in
            self.deleteAnnotations(annotationItems: tempAnnotations)
        }
        
        self.addNotification()
        self.localEvent = false
    }
    
    @IBAction func undo(_ sender: Any) {
        if (self.listView?.undoManager?.canUndo ?? false) {
            self.listView?.undoManager?.undo()
        }
    }
    
    @IBAction func redo(_ sender: Any) {
        if (self.listView?.undoManager?.canRedo ?? false) {
            self.listView?.undoManager?.redo()
        }
    }
}