//
//  KMHomeExtractActionViewController.swift
//  PDF Master
//
//  Created by wanjun on 2022/11/28.
//

import Cocoa

enum KMComboBoxPageChoice : Int {
    case all = 0
    case current
    case odd
    case even
    case custom
}

protocol KMHomeExtractActionViewControllerDelegate: NSObjectProtocol {
    func extractActionViewController(_ viewController: KMHomeExtractActionViewController, pages: [CPDFPage])
    func extractActionViewController(_ viewController: KMHomeExtractActionViewController, isOneDocumentPerPage: Bool, isDeletePage: Bool)
}

class KMExtractCombobox: KMComboBox {
    typealias mouseDownCallback = (_ mouseDown: Bool) -> Void
    var downCallback: mouseDownCallback?

    override func mouseDown(with event: NSEvent) {
        super.mouseDown(with: event)
        
        if let callback = downCallback {
            callback(true)
        }
    }
}

class KMHomeExtractActionViewController: NSViewController {
    
    @IBOutlet weak var pageScopeLabel: NSTextField!
    @IBOutlet weak var pageScopeBox: NSBox!
    @IBOutlet weak var extractionWayLabel: NSTextField!
    @IBOutlet weak var oneDocumentPerPageBox: KMBox!
    @IBOutlet weak var oneDocumentPerPageImageView: NSImageView!
    @IBOutlet weak var oneDocumentPerPageLabel: NSTextField!
    @IBOutlet weak var isDeletePageBox: KMBox!
    @IBOutlet weak var isDeletePageImageView: NSImageView!
    @IBOutlet weak var isDeletePageLabel: NSTextField!
    
    var pageRangeCombobox: KMExtractCombobox!

    var pdfDocument: CPDFDocument? = nil
    var currentPageCount: Int! = 1
    
    var choiceArray: [String] = []
    var pageChoice: KMComboBoxPageChoice = .all
    var comboBoxContent: String = ""
    var isOneDocumentPerPage: Bool = false
    var isDeletePage: Bool = false
    var customPageNumbers: [String] = []
    open weak var delete: KMHomeExtractActionViewControllerDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        
        choiceArray = [NSLocalizedString("All Pages", comment: ""), NSLocalizedString("Current Page", comment: ""), NSLocalizedString("Odd Pages", comment: ""), NSLocalizedString("Even Pages", comment: ""), NSLocalizedString("Customized", comment: "")]
                
        oneDocumentPerPageBox.downCallback = { [weak self](downEntered: Bool, mouseBox: KMBox, event) -> Void in
            if downEntered {
                if self != nil {
                    self!.oneDocumentPerPageAction(mouseBox)
                }
            }
        }
        isDeletePageBox.downCallback = { [weak self](downEntered: Bool, mouseBox: KMBox, event) -> Void in
            if downEntered {
                if self != nil {
                    self!.isDeletePageAction(mouseBox)
                }
            }
        }
    }
    
    override func viewDidAppear() {
        super.viewDidAppear()
        
        initializeUI()
        initLocalization()

        reloadData()
    }
    
    // MARK: Init
    
    func initializeUI() -> Void {
        pageRangeCombobox = KMExtractCombobox(frame: pageScopeBox.bounds)
        pageRangeCombobox.comboxRect = pageRangeCombobox.bounds
        pageRangeCombobox.type = .none
        pageRangeCombobox.focusRingType = .none
        pageRangeCombobox.wantsLayer = true
        pageRangeCombobox.layer?.backgroundColor = .white
        pageRangeCombobox.layer?.borderWidth = 1.0
        pageRangeCombobox.layer?.borderColor = .black
        pageRangeCombobox.layer?.cornerRadius = 1.0
        pageRangeCombobox.backgroundColor = .white
        pageScopeBox.addSubview(pageRangeCombobox)
        pageRangeCombobox.addItems(withObjectValues: choiceArray)
        let cell = pageRangeCombobox.cell as! NSTextFieldCell
        cell.placeholderString = "e.g. 1,3-5,10"
        pageRangeCombobox.selectItem(at: 0)
        pageRangeCombobox.isEditable = false
        pageRangeCombobox.delegate = self
        comboBoxContent = "e.g. 1,3-5,10"
        pageRangeCombobox.downCallback = { [weak self](mouseDown: Bool) -> Void in
            if mouseDown {
                if self != nil {
                    self!.pageRangeComboboxAction(self!.pageRangeCombobox as Any)
                }
            }
        }
        
    }
    
    func initLocalization() -> Void {
        pageScopeLabel.stringValue = NSLocalizedString("页面范围", comment: "")
        extractionWayLabel.stringValue = NSLocalizedString("提取方式", comment: "")
        oneDocumentPerPageBox.toolTip = NSLocalizedString("每个页面作为单独页面", comment: "")
        oneDocumentPerPageLabel.stringValue = NSLocalizedString("每个页面作为单独页面", comment: "")
        isDeletePageBox.toolTip = NSLocalizedString("提取后删除页面", comment: "")
        isDeletePageLabel.stringValue = NSLocalizedString("提取后删除页面", comment: "")
    }
    
    // MARK: private

    func reloadData() -> Void {
        var pages: [CPDFPage] = []
        switch pageChoice {
        case .all:
            for count in 1...pdfDocument!.pageCount {
                let page = pdfDocument?.page(at: UInt(count - 1))
                pages.append(page!)
            }
        case .current:
            let page = pdfDocument?.page(at: UInt(currentPageCount - 1))
            pages.append(page!)
        case .odd:
            for count in 1...pdfDocument!.pageCount {
                if count % 2 != 0 {
                    let page = pdfDocument?.page(at: UInt(count - 1))
                    pages.append(page!)
                }
            }
        case .even:
            for count in 1...pdfDocument!.pageCount {
                if count % 2 == 0 {
                    let page = pdfDocument?.page(at: UInt(count - 1))
                    pages.append(page!)
                }
            }
        case .custom:
            for string in customPageNumbers {
                let page = pdfDocument?.page(at: UInt(string)!)
                pages.append(page!)
            }
        }
        
        self.delete?.extractActionViewController(self, pages: pages)
        
        if isOneDocumentPerPage {
            oneDocumentPerPageImageView.image = NSImage(named: "KMImageNameSelect")
        } else {
            oneDocumentPerPageImageView.image = NSImage(named: "KMImageNameUnSelect")
        }
        if isDeletePage {
            isDeletePageImageView.image = NSImage(named: "KMImageNameSelect")
        } else {
            isDeletePageImageView.image = NSImage(named: "KMImageNameUnSelect")
        }
        self.delete?.extractActionViewController(self, isOneDocumentPerPage: isOneDocumentPerPage, isDeletePage: isDeletePage)
    }
    
    // MARK: Acton

    @IBAction func pageRangeComboboxAction(_ sender: Any) -> Void {
        if pageRangeCombobox.indexOfSelectedItem == KMComboBoxPageChoice.custom.rawValue {
            if comboBoxContent == "e.g. 1,3-5,10" {
                pageRangeCombobox.stringValue = ""
            } else {
                pageRangeCombobox.stringValue = comboBoxContent
            }
        }
    }
    
    @IBAction func oneDocumentPerPageAction(_ sender: Any) -> Void {
        isOneDocumentPerPage = !isOneDocumentPerPage
        reloadData()
    }
    
    @IBAction func isDeletePageAction(_ sender: Any) -> Void {
        isDeletePage = !isDeletePage
        reloadData()
    }
}

// MARK: NSComboBoxDelegate

extension KMHomeExtractActionViewController: NSComboBoxDelegate {
    func comboBoxSelectionDidChange(_ notification: Notification) {
        let combobox = notification.object as! KMExtractCombobox
        if combobox.isEqual(pageRangeCombobox) {
            if pageRangeCombobox.indexOfSelectedItem == KMComboBoxPageChoice.custom.rawValue {
                pageRangeCombobox.isEditable = true
                pageRangeCombobox.isSelectable = true
                self.view.window?.makeFirstResponder(pageRangeCombobox)
            } else {
                pageRangeCombobox.resignFirstResponder()
                pageRangeCombobox.isEditable = false
                pageRangeCombobox.isSelectable = false
            }
            let index = pageRangeCombobox.indexOfSelectedItem
            pageChoice = KMComboBoxPageChoice(rawValue: index) ?? .all

            
            reloadData()
        }
    }
    
    func controlTextDidChange(_ obj: Notification) {
        let combobox = obj.object as! KMExtractCombobox
        if combobox.isEqual(pageRangeCombobox) {
            comboBoxContent = combobox.stringValue
        }
    }
    
    func controlTextDidEndEditing(_ obj: Notification) {
        let combobox = obj.object as! KMExtractCombobox
        if combobox.isEqual(pageRangeCombobox) {
            reloadData()
        }
    }
}