//
//  KMPDFAnnotationChoiceWidgetSub.swift
//  PDF Reader Pro
//
//  Created by wanjun on 2024/1/31.
//

import Cocoa

class KMPDFAnnotationChoiceWidgetSub: CPDFChoiceWidgetAnnotation {
    var formType: CAnnotationType = .unkown
    
    override func draw(with box: CPDFDisplayBox, in context: CGContext!) {
        let listChoice: Bool = isListChoice
        if listChoice {
            if hasAppearanceStream() {
                super.draw(with: box, in: context)
            } else {
                super.draw(with: box, in: context)
                transformContext(for: page, displayBox: box)
                
                context.setStrokeColor(red: 0, green: 0, blue: 0, alpha: 1.0)
                context.setLineWidth(1.0)
                context.addRect(CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.size.width, height: bounds.size.height))
                context.strokePath()
            }
        } else {
            if hasAppearanceStream() {
                super.draw(with: box, in: context)
            } else {
                var stabilizeHeight = bounds.size.height
                if stabilizeHeight > 25.0 {
                    stabilizeHeight = 25.0
                }
                var actualRect = CGRect.zero
                actualRect = CGRect(x: bounds.origin.x, y: bounds.minY + (bounds.height - stabilizeHeight) / 2, width: bounds.size.width, height: stabilizeHeight)
                
                let borderWidth: CGFloat = 0.5
                var rightPartWidthChangePointValue = bounds.size.width / 2
                if rightPartWidthChangePointValue > 30 {
                    rightPartWidthChangePointValue = 30
                }
                let radius: CGFloat = 2.0
                
                // 画外框
                context.saveGState()
                context.move(to: CGPoint(x: actualRect.maxX - rightPartWidthChangePointValue, y: actualRect.minY + borderWidth))
                context.addLine(to: CGPoint(x: actualRect.minX + borderWidth, y: actualRect.minY + borderWidth))
                context.addLine(to: CGPoint(x: actualRect.minX + borderWidth, y: actualRect.maxY - borderWidth))
                context.addLine(to: CGPoint(x: actualRect.maxX - rightPartWidthChangePointValue + 2 * borderWidth, y: actualRect.maxY - borderWidth))
                context.addLine(to: CGPoint(x: actualRect.maxX - rightPartWidthChangePointValue + 2 * borderWidth, y: actualRect.minY + borderWidth))
                context.setStrokeColor(NSColor.lightGray.cgColor)
                context.setLineWidth(borderWidth)
                context.setFillColor(self.backgroundColor.cgColor)
                context.drawPath(using: .fillStroke)
                context.restoreGState()
                
                context.saveGState()
                context.move(to: CGPoint(x: actualRect.maxX - rightPartWidthChangePointValue, y: actualRect.maxY))
                context.addLine(to: CGPoint(x: actualRect.maxX - rightPartWidthChangePointValue, y: actualRect.minY))
                context.addLine(to: CGPoint(x: actualRect.maxX - radius, y: actualRect.minY))
                context.addArc(center: CGPoint(x: actualRect.maxX - radius, y: actualRect.minY + radius), radius: radius, startAngle: CGFloat(3 * Double.pi / 2), endAngle: CGFloat(2 * Double.pi), clockwise: false)
                context.addLine(to: CGPoint(x: actualRect.maxX, y: actualRect.maxY - radius))
                context.addArc(center: CGPoint(x: actualRect.maxX - radius, y: actualRect.maxY - radius), radius: radius, startAngle: CGFloat(2 * Double.pi), endAngle: CGFloat(Double.pi / 2), clockwise: false)
                context.addLine(to: CGPoint(x: actualRect.maxX - rightPartWidthChangePointValue, y: actualRect.maxY))
                context.setFillColor(NSColor(red: 37/255.0, green: 139/255.0, blue: 251/255.0, alpha: 1.0).cgColor)
                context.drawPath(using: .fill)
                context.restoreGState()
                
                // 画等边三角形
                let triangleWidth = min(rightPartWidthChangePointValue, actualRect.height) / 2.0
                let triangleHeight = triangleWidth * sqrt(3.0) / 2
                let centerPointUpGap = triangleHeight / 3.0
                
                context.saveGState()
                let startPointX = actualRect.maxX - rightPartWidthChangePointValue + (rightPartWidthChangePointValue - triangleWidth) / 2
                let startPointY = actualRect.midY + centerPointUpGap
                context.move(to: CGPoint(x: startPointX, y: startPointY))
                context.addLine(to: CGPoint(x: startPointX + triangleWidth, y: startPointY))
                context.addLine(to: CGPoint(x: startPointX + triangleWidth / 2.0, y: actualRect.midY - 2 * centerPointUpGap))
                context.closePath()
                context.setFillColor(NSColor.white.cgColor)
                context.drawPath(using: .fill)
                context.restoreGState()
                
                context.saveGState()
                // 画文字
                var attributes = [NSAttributedString.Key: Any]()
                if let font = self.font {
                    attributes[.font] = font
                }
                if let fontColor = self.fontColor {
                    attributes[.foregroundColor] = fontColor
                }
                let stringRect = self.string().boundingRect(with: CGSize(width: actualRect.size.width - rightPartWidthChangePointValue, height: actualRect.size.height), options: .usesLineFragmentOrigin, attributes: attributes)
                
                self.string().draw(in: CGRect(x: actualRect.origin.x, y: (actualRect.size.height - stringRect.size.height) / 2 + actualRect.origin.y, width: stringRect.size.width, height: stringRect.size.height), withAttributes: attributes)
//                context.restoreGState()
            }
        }
    }
    
    func transformContext(for page: CPDFPage, displayBox box: CPDFDisplayBox) {
        var transform = NSAffineTransform()

        // Identity.
        transform = NSAffineTransform()

        // Bounds for page.
        let boxRect = page.bounds(for: box)

        // Handle rotation.
        let rotation = page.rotation
        switch rotation {
        case 90:
            transform.rotate(byDegrees: -90)
            transform.translateX(by: -boxRect.size.width, yBy: 0.0)
        case 180:
            transform.rotate(byDegrees: 180)
            transform.translateX(by: -boxRect.size.width, yBy: -boxRect.size.height)
        case 270:
            transform.rotate(byDegrees: 90)
            transform.translateX(by: 0.0, yBy: -boxRect.size.height)
        default:
            break
        }

        // Origin.
        transform.translateX(by: -boxRect.origin.x, yBy: -boxRect.origin.y)

        // Concatenate.
        transform.concat()
    }

    func keysForValuesToObserveForUndo() -> Set<String> {
        return []
    }
}