import { h } from "@stencil/core";
/**
 * Display a dialog that allows the user to specify a signature image, either by using a signature-font-generated image
 * based on their full name, or by hand-drawing their signature with a mouse or tablet.
 */
export class VerdocsAdoptSignatureDialog {
    constructor() {
        /**
         * Initial signature text
         */
        this.name = '';
        this.fontLoaded = false;
        this.enteredName = '';
        this.enteredInitials = '';
        this.mode = 'type';
        this.isDrawing = false;
        this.hasDrawnSignature = false;
        this.currentSigStroke = [];
        this.allSigStrokes = [];
        this.lastSigPoint = null;
        this.currentInitialsStroke = [];
        this.allInitialsStrokes = [];
        this.lastInitialsPoint = null;
        this.handleSigPointerDown = (e) => {
            e.preventDefault();
            if (!this.signatureElement || !this.sigDrawingContext) {
                return;
            }
            this.isDrawing = true;
            this.hasDrawnSignature = true;
            const point = this.getSigCanvasCoordinates(e);
            this.currentSigStroke = [point];
            this.lastSigPoint = point;
            // Start a new path
            this.sigDrawingContext.beginPath();
            this.sigDrawingContext.moveTo(point.x, point.y);
            // Capture pointer to ensure we get all events even if pointer leaves canvas
            this.signatureElement.setPointerCapture(e.pointerId);
        };
        this.handleSigPointerMove = (e) => {
            e.preventDefault();
            if (!this.isDrawing || !this.sigDrawingContext || !this.lastSigPoint) {
                return;
            }
            const point = this.getSigCanvasCoordinates(e);
            this.currentSigStroke.push(point);
            // Use quadratic curves for smooth drawing
            // The control point is the last point, and we draw to the midpoint
            const midPoint = {
                x: (this.lastSigPoint.x + point.x) / 2,
                y: (this.lastSigPoint.y + point.y) / 2,
            };
            this.sigDrawingContext.quadraticCurveTo(this.lastSigPoint.x, this.lastSigPoint.y, midPoint.x, midPoint.y);
            this.sigDrawingContext.stroke();
            this.lastSigPoint = point;
        };
        this.handleSigPointerUp = (e) => {
            e.preventDefault();
            if (!this.isDrawing || !this.sigDrawingContext) {
                return;
            }
            // Complete the stroke
            if (this.lastSigPoint && this.currentSigStroke.length > 0) {
                this.sigDrawingContext.lineTo(this.lastSigPoint.x, this.lastSigPoint.y);
                this.sigDrawingContext.stroke();
            }
            // Save the completed stroke
            if (this.currentSigStroke.length > 0) {
                this.allSigStrokes.push([...this.currentSigStroke]);
            }
            this.isDrawing = false;
            this.currentSigStroke = [];
            this.lastSigPoint = null;
            // Release pointer capture
            if (this.signatureElement) {
                this.signatureElement.releasePointerCapture(e.pointerId);
            }
        };
        this.handleSigPointerCancel = (e) => {
            // Handle cases where drawing is interrupted (e.g., phone call, notification)
            this.isDrawing = false;
            this.currentSigStroke = [];
            this.lastSigPoint = null;
            if (this.signatureElement) {
                this.signatureElement.releasePointerCapture(e.pointerId);
            }
        };
        this.handleInitialsPointerDown = (e) => {
            e.preventDefault();
            if (!this.initialsElement || !this.initialsDrawingContext) {
                return;
            }
            this.isDrawing = true;
            this.hasDrawnSignature = true;
            const point = this.getInitialsCanvasCoordinates(e);
            this.currentInitialsStroke = [point];
            this.lastInitialsPoint = point;
            // Start a new path
            this.initialsDrawingContext.beginPath();
            this.initialsDrawingContext.moveTo(point.x, point.y);
            // Capture pointer to ensure we get all events even if pointer leaves canvas
            this.initialsElement.setPointerCapture(e.pointerId);
        };
        this.handleInitialsPointerMove = (e) => {
            e.preventDefault();
            if (!this.isDrawing || !this.initialsDrawingContext || !this.lastInitialsPoint) {
                return;
            }
            const point = this.getInitialsCanvasCoordinates(e);
            this.currentInitialsStroke.push(point);
            // Use quadratic curves for smooth drawing
            // The control point is the last point, and we draw to the midpoint
            const midPoint = {
                x: (this.lastInitialsPoint.x + point.x) / 2,
                y: (this.lastInitialsPoint.y + point.y) / 2,
            };
            this.initialsDrawingContext.quadraticCurveTo(this.lastInitialsPoint.x, this.lastInitialsPoint.y, midPoint.x, midPoint.y);
            this.initialsDrawingContext.stroke();
            this.lastInitialsPoint = point;
        };
        this.handleInitialsPointerUp = (e) => {
            e.preventDefault();
            if (!this.isDrawing || !this.initialsDrawingContext) {
                return;
            }
            // Complete the stroke
            if (this.lastInitialsPoint && this.currentInitialsStroke.length > 0) {
                this.initialsDrawingContext.lineTo(this.lastInitialsPoint.x, this.lastInitialsPoint.y);
                this.initialsDrawingContext.stroke();
            }
            // Save the completed stroke
            if (this.currentInitialsStroke.length > 0) {
                this.allInitialsStrokes.push([...this.currentInitialsStroke]);
            }
            this.isDrawing = false;
            this.currentInitialsStroke = [];
            this.lastInitialsPoint = null;
            // Release pointer capture
            if (this.initialsElement) {
                this.initialsElement.releasePointerCapture(e.pointerId);
            }
        };
        this.handleInitialsPointerCancel = (e) => {
            // Handle cases where drawing is interrupted (e.g., phone call, notification)
            this.isDrawing = false;
            this.currentInitialsStroke = [];
            this.lastInitialsPoint = null;
            if (this.initialsElement) {
                this.initialsElement.releasePointerCapture(e.pointerId);
            }
        };
    }
    componentWillLoad() {
        this.enteredName = this.name;
        this.computeEnteredInitials(this.name);
        const ds = new FontFace('Dancing Script', 'url(https://fonts.gstatic.com/s/dancingscript/v19/If2cXTr6YS-zF4S-kcSWSVi_sxjsohD9F50Ruu7BMSo3Sup6hNX6plRP.woff)');
        ds.load().then(font => {
            document.fonts.add(font);
            this.fontLoaded = true;
        });
    }
    componentDidLoad() {
        this.drawSignatureText();
        this.drawInitialsText();
        this.setupSignatureCanvas();
        this.setupInitialsCanvas();
    }
    componentDidUpdate() {
        this.drawSignatureText();
        this.drawInitialsText();
        this.setupSignatureCanvas();
        this.setupInitialsCanvas();
        // Redraw drawn signature when in draw mode
        if (this.mode === 'draw' && this.allSigStrokes.length > 0) {
            this.redrawDrawnSignature();
        }
        if (this.mode === 'draw' && this.allInitialsStrokes.length > 0) {
            this.redrawDrawnInitials();
        }
    }
    drawSignatureText() {
        if (!this.signatureElement || this.mode !== 'type') {
            return;
        }
        const sigCanvasWidth = this.signatureElement.width;
        const sigCanvasHeight = this.signatureElement.height;
        const sigContext = this.signatureElement.getContext('2d');
        sigContext.clearRect(0, 0, this.signatureElement.width, this.signatureElement.height);
        let fontSize = 100;
        let metrics = sigContext.measureText(this.enteredName);
        do {
            fontSize -= 2;
            sigContext.font = `${fontSize}px Dancing Script`;
            metrics = sigContext.measureText(this.enteredName);
        } while (metrics.width > sigCanvasWidth - 24 || metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent + 24 > sigCanvasHeight);
        sigContext.textAlign = 'center';
        sigContext.textBaseline = 'middle';
        sigContext.font = `${fontSize}px Dancing Script`;
        sigContext.fillText(this.enteredName, this.signatureElement.width / 2, this.signatureElement.height / 2);
    }
    drawInitialsText() {
        if (!this.initialsElement || this.mode !== 'type') {
            return;
        }
        const initialsCanvasWidth = this.initialsElement.width;
        const initialsCanvasHeight = this.initialsElement.height;
        const context = this.initialsElement.getContext('2d');
        context.clearRect(0, 0, this.initialsElement.width, this.initialsElement.height);
        let fontSize = 100;
        let metrics = context.measureText(this.enteredInitials);
        do {
            fontSize -= 2;
            context.font = `${fontSize}px Dancing Script`;
            metrics = context.measureText(this.enteredInitials);
        } while (metrics.width > initialsCanvasWidth - 24 || metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent + 24 > initialsCanvasHeight);
        context.textAlign = 'center';
        context.textBaseline = 'middle';
        context.font = `${fontSize}px Dancing Script`;
        context.fillText(this.enteredInitials, this.initialsElement.width / 2, this.initialsElement.height / 2);
    }
    redrawDrawnSignature() {
        if (!this.signatureElement || !this.sigDrawingContext || this.allSigStrokes.length === 0) {
            return;
        }
        // Clear the canvas first
        this.sigDrawingContext.clearRect(0, 0, this.signatureElement.width, this.signatureElement.height);
        // Redraw all strokes
        for (const stroke of this.allSigStrokes) {
            if (stroke.length === 0) {
                continue;
            }
            // Start the path at the first point
            this.sigDrawingContext.beginPath();
            this.sigDrawingContext.moveTo(stroke[0].x, stroke[0].y);
            // Draw smooth curves through all points in the stroke
            for (let i = 1; i < stroke.length; i++) {
                const currentPoint = stroke[i];
                const previousPoint = stroke[i - 1];
                // Use quadratic curves for smooth lines
                const midPoint = {
                    x: (previousPoint.x + currentPoint.x) / 2,
                    y: (previousPoint.y + currentPoint.y) / 2,
                };
                this.sigDrawingContext.quadraticCurveTo(previousPoint.x, previousPoint.y, midPoint.x, midPoint.y);
            }
            // Draw to the last point
            if (stroke.length > 1) {
                const lastPoint = stroke[stroke.length - 1];
                this.sigDrawingContext.lineTo(lastPoint.x, lastPoint.y);
            }
            this.sigDrawingContext.stroke();
        }
    }
    redrawDrawnInitials() {
        if (!this.initialsElement || !this.initialsDrawingContext || this.allInitialsStrokes.length === 0) {
            return;
        }
        // Clear the canvas first
        this.initialsDrawingContext.clearRect(0, 0, this.initialsElement.width, this.initialsElement.height);
        // Redraw all strokes
        for (const stroke of this.allInitialsStrokes) {
            if (stroke.length === 0) {
                continue;
            }
            // Start the path at the first point
            this.initialsDrawingContext.beginPath();
            this.initialsDrawingContext.moveTo(stroke[0].x, stroke[0].y);
            // Draw smooth curves through all points in the stroke
            for (let i = 1; i < stroke.length; i++) {
                const currentPoint = stroke[i];
                const previousPoint = stroke[i - 1];
                // Use quadratic curves for smooth lines
                const midPoint = {
                    x: (previousPoint.x + currentPoint.x) / 2,
                    y: (previousPoint.y + currentPoint.y) / 2,
                };
                this.initialsDrawingContext.quadraticCurveTo(previousPoint.x, previousPoint.y, midPoint.x, midPoint.y);
            }
            // Draw to the last point
            if (stroke.length > 1) {
                const lastPoint = stroke[stroke.length - 1];
                this.initialsDrawingContext.lineTo(lastPoint.x, lastPoint.y);
            }
            this.initialsDrawingContext.stroke();
        }
    }
    handleNameChange(e) {
        this.enteredName = e.target.value;
        this.computeEnteredInitials(e.target.value);
    }
    computeEnteredInitials(name) {
        const nameComponents = name
            .trim()
            .split(' ')
            .filter(part => part.length > 0);
        this.enteredInitials = nameComponents.length > 1 ? nameComponents.map(word => word.charAt(0).toUpperCase()).join('') : nameComponents[0].toUpperCase();
    }
    handleCancel(e) {
        e.stopPropagation();
        e.preventDefault();
        this.exit.emit();
    }
    handleAdopt(e) {
        e.stopPropagation();
        e.preventDefault();
        const signature = this.signatureElement.toDataURL('image/png');
        const initials = this.initialsElement.toDataURL('image/png');
        this.next.emit({ signature, initials });
    }
    isAdoptButtonDisabled() {
        switch (this.mode) {
            case 'type':
                // Disable if no name has been entered
                return !this.enteredName || this.enteredName.trim().length === 0;
            case 'draw':
                // Disable if nothing has been drawn
                return !this.hasDrawnSignature || this.allSigStrokes.length === 0 || this.allInitialsStrokes.length === 0;
            default:
                return true;
        }
    }
    setupSignatureCanvas() {
        if (!this.signatureElement) {
            return;
        }
        // Set up drawing context when in draw mode
        if (this.mode === 'draw') {
            // Always get fresh context from the current canvas element
            const sigContext = this.signatureElement.getContext('2d');
            // Only initialize if we don't have a context or it's different
            if (sigContext && sigContext !== this.sigDrawingContext) {
                this.sigDrawingContext = sigContext;
                // Configure drawing style for smooth signatures
                this.sigDrawingContext.strokeStyle = '#000000';
                this.sigDrawingContext.lineWidth = 2;
                this.sigDrawingContext.lineCap = 'round';
                this.sigDrawingContext.lineJoin = 'round';
                // Clear canvas only if there are no existing strokes
                if (this.allSigStrokes.length === 0) {
                    this.sigDrawingContext.clearRect(0, 0, this.signatureElement.width, this.signatureElement.height);
                }
            }
        }
        // Reset drawing context when switching away from draw mode
        // NOTE: We don't clear allStrokes here so drawing persists when returning to draw mode
        if (this.mode !== 'draw' && this.sigDrawingContext) {
            this.sigDrawingContext = null;
            this.currentSigStroke = [];
            this.lastSigPoint = null;
        }
    }
    setupInitialsCanvas() {
        if (!this.initialsElement) {
            return;
        }
        // Set up drawing context when in draw mode
        if (this.mode === 'draw') {
            // Always get fresh context from the current canvas element
            const initialsContext = this.initialsElement.getContext('2d');
            // Only initialize if we don't have a context or it's different
            if (initialsContext && initialsContext !== this.initialsDrawingContext) {
                this.initialsDrawingContext = initialsContext;
                // Configure drawing style for smooth signatures
                this.initialsDrawingContext.strokeStyle = '#000000';
                this.initialsDrawingContext.lineWidth = 2;
                this.initialsDrawingContext.lineCap = 'round';
                this.initialsDrawingContext.lineJoin = 'round';
                // Clear canvas only if there are no existing strokes
                if (this.allInitialsStrokes.length === 0) {
                    this.initialsDrawingContext.clearRect(0, 0, this.initialsElement.width, this.initialsElement.height);
                }
            }
        }
        // Reset drawing context when switching away from draw mode
        // NOTE: We don't clear allStrokes here so drawing persists when returning to draw mode
        if (this.mode !== 'draw' && this.initialsDrawingContext) {
            this.initialsDrawingContext = null;
            this.currentInitialsStroke = [];
            this.lastInitialsPoint = null;
        }
    }
    clearSignatureCanvas() {
        if (!this.signatureElement || !this.sigDrawingContext) {
            return;
        }
        this.sigDrawingContext.clearRect(0, 0, this.signatureElement.width, this.signatureElement.height);
        this.currentSigStroke = [];
        this.allSigStrokes = [];
        this.lastSigPoint = null;
        this.hasDrawnSignature = false;
    }
    clearInitialsCanvas() {
        if (!this.initialsElement || !this.initialsDrawingContext) {
            return;
        }
        this.initialsDrawingContext.clearRect(0, 0, this.initialsElement.width, this.initialsElement.height);
        this.currentInitialsStroke = [];
        this.allInitialsStrokes = [];
        this.lastInitialsPoint = null;
        this.hasDrawnSignature = false;
    }
    handleClearDrawing(e) {
        e.stopPropagation();
        e.preventDefault();
        this.clearSignatureCanvas();
        this.clearInitialsCanvas();
    }
    getSigCanvasCoordinates(e) {
        if (!this.signatureElement) {
            return { x: 0, y: 0 };
        }
        const rect = this.signatureElement.getBoundingClientRect();
        // Calculate the scale factor between canvas size and display size
        const scaleX = this.signatureElement.width / rect.width;
        const scaleY = this.signatureElement.height / rect.height;
        return {
            x: (e.clientX - rect.left) * scaleX,
            y: (e.clientY - rect.top) * scaleY,
        };
    }
    getInitialsCanvasCoordinates(e) {
        if (!this.initialsElement) {
            return { x: 0, y: 0 };
        }
        const rect = this.initialsElement.getBoundingClientRect();
        // Calculate the scale factor between canvas size and display size
        const scaleX = this.initialsElement.width / rect.width;
        const scaleY = this.initialsElement.height / rect.height;
        return {
            x: (e.clientX - rect.left) * scaleX,
            y: (e.clientY - rect.top) * scaleY,
        };
    }
    render() {
        return (h("verdocs-dialog", { key: 'cd7e4e12870c3e5c6e3ecae99ca18a2e517cc5d7' }, h("div", { key: 'e0361f91ecde016a44a9df467989e59b9c7dac78', slot: "heading", class: "heading" }, "Adopt Your Signature"), h("div", { key: '871467dcc778eea921fc9f7c43a6f4f00020a716', slot: "content", class: "content" }, h("div", { key: 'bfa75ff9630b434b3498dd4b5858a48f4c5d34b1', style: { fontWeight: '300', color: '#242424', fontSize: '13px' } }, "Confirm your name, initials, and signature."), h("div", { key: '1c35c5deb3062f9d15c12601fcfdf1b2c141cf40', class: { type: true, active: this.mode === 'type' } }, h("verdocs-text-input", { key: '52ab06b5039e3b01bb778380282a2f9209ce2c09', label: "Full Name", value: this.enteredName, onInput: e => this.handleNameChange(e), onClick: e => e.stopPropagation() })), h("div", { key: '2ca4dd8dbf1a15f37fc1d746d660601ba0e7744a', style: { fontWeight: '400', color: '#242424', fontSize: '13px' } }, "Select a signature style"), h("div", { key: '028510ba0e54e67d8c0e0580b2c39ad741be66b3', style: { display: 'flex', flexDirection: 'row', gap: '10px', marginBottom: '6px', alignItems: 'center', fontSize: '13px' } }, h("verdocs-radio-button", { key: 'aae39fd918af8f4d3c6938507d8acfca0a50cad7', checked: this.mode === 'type', value: "type", name: "mode", onClick: () => (this.mode = 'type') }), h("label", { key: '3ef1416e35982cb0741aba43f531373235688cb8' }, "Typed with a keyboard")), h("div", { key: '1b858ad50908df8f52cd46257fa62d5f6238b46a', style: { display: 'flex', flexDirection: 'row', gap: '10px', marginBottom: '6px', alignItems: 'center', fontSize: '13px' } }, h("verdocs-radio-button", { key: 'b28fd02ddba1e50d95e71daebadcbe4692cc07bf', checked: this.mode === 'draw', value: "draw", name: "mode", onClick: () => (this.mode = 'draw') }), h("label", { key: 'f1ec506edace3f839be3e60a833a7078388511c6' }, "Drawn with touch, mouse, or stylus")), h("div", { key: '7ba7b888718f4d36cb6c3dff4766c7d4a4aa8588', class: "draw-actions" }, h("button", { key: '5aa570c6bd0a7919df717f57cd126ce693901614', class: "clear-button", onClick: e => this.handleClearDrawing(e), disabled: !this.hasDrawnSignature }, "Clear")), h("div", { key: 'da02332f59f07b62abd19d424ee2026594614681', style: { fontSize: '13px', fontWeight: '400', marginTop: '8px' } }, "Signature Preview"), h("canvas", { key: 'f06947bf19e21ca9d55242616ff6203f1511f035', ref: el => (this.signatureElement = el), width: "300", height: "79", onPointerDown: this.handleSigPointerDown, onPointerMove: this.handleSigPointerMove, onPointerUp: this.handleSigPointerUp, onPointerCancel: this.handleSigPointerCancel, style: { touchAction: 'none', cursor: 'crosshair' } }), h("div", { key: 'e4253e4a1b0ae0ae2dbe12cbf5044ea19a55ffd1', style: { fontSize: '13px', fontWeight: '400', marginTop: '8px' } }, "Initials Preview"), h("canvas", { key: 'b5ffe09caca8e36d3b7645baaa9c49ac534ae2ab', ref: el => (this.initialsElement = el), width: "300", height: "79", onPointerDown: this.handleInitialsPointerDown, onPointerMove: this.handleInitialsPointerMove, onPointerUp: this.handleInitialsPointerUp, onPointerCancel: this.handleInitialsPointerCancel, style: { touchAction: 'none', cursor: 'crosshair' } }), h("div", { key: '2794cb9a0e09956c421436bf7d07b7ff5b05b877', class: "disclaimer" }, "By clicking \u00ABAdopt Signature\u00BB, I agree that the signature and initials above will be the electronic representation of my signature and initials for all purposes when I use them to sign documents. Applying them to a document is legally equivalent to signing with a pen on paper.")), h("div", { key: 'c162a5d0fb4e827097d386be1598f5687a1f0f9d', class: "footer", slot: "footer" }, h("div", { key: '784cabdfd41901b0082ed995f8da6f9d929d5bd6', class: "buttons" }, h("button", { key: 'e7a853d282ca868c6ad8f16c32a5295b91ad0027', class: "cancel", onClick: e => this.handleCancel(e) }, "Cancel"), h("button", { key: '5db215d9fbca44bd0b8b864cb34b9e9cb89e7cef', class: "proceed", onClick: e => this.handleAdopt(e), disabled: this.isAdoptButtonDisabled() }, "Adopt & Sign")))));
    }
    static get is() { return "verdocs-adopt-signature-dialog"; }
    static get originalStyleUrls() {
        return {
            "$": ["verdocs-adopt-signature-dialog.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["verdocs-adopt-signature-dialog.css"]
        };
    }
    static get properties() {
        return {
            "name": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Initial signature text"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "name",
                "defaultValue": "''"
            }
        };
    }
    static get states() {
        return {
            "fontLoaded": {},
            "enteredName": {},
            "enteredInitials": {},
            "mode": {},
            "isDrawing": {},
            "hasDrawnSignature": {}
        };
    }
    static get events() {
        return [{
                "method": "next",
                "name": "next",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Fired when the user completes the dialog and clicks Adopt. The event detail will contain a base64-encoded string\nrepresentation of the signature adopted."
                },
                "complexType": {
                    "original": "{signature: string; initials: string}",
                    "resolved": "{ signature: string; initials: string; }",
                    "references": {}
                }
            }, {
                "method": "exit",
                "name": "exit",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Event fired when the step is cancelled. This is called exit to avoid conflicts with the JS-reserved \"cancel\" event name."
                },
                "complexType": {
                    "original": "any",
                    "resolved": "any",
                    "references": {}
                }
            }];
    }
}
//# sourceMappingURL=verdocs-adopt-signature-dialog.js.map
