/**
 * ParagraphLayout Module
 * Interfaces with the Knuth-Plass line breaking algorithm to calculate optimal line breaks.
 */
import { BaseModule } from './base-module.js';
import { moduleRegistry } from './module-registry.js';

class ParagraphLayoutModule extends BaseModule {
    /**
     * Create a new ParagraphLayout
     */
    constructor() {
        super('paragraph-layout', 'Paragraph Layout');
        this.kapAlgorithm = null;
        this.measureText = null;
    }
    
    /**
     * Load module dependencies
     * @returns {Promise} - Resolves when dependencies are loaded
     */
    async loadDependencies() {
        try {
            // First load linebreak.js if needed
            if (!window.linebreak) {
                await this.loadScript('/js/linebreak.js');
                this.reportProgress(40, "Linebreak algorithm loaded");
            }
            
            // Then load knuth-and-plass.js if needed
            if (!window.kap) {
                await this.loadScript('/js/knuth-and-plass.js');
                this.reportProgress(60, "KAP algorithm loaded");
            }
            
            this.kapAlgorithm = window.kap;
            
            return true;
        } catch (error) {
            console.error("Error loading paragraph layout dependencies:", error);
            return false;
        }
    }
    
    /**
     * Load a script dynamically
     * @param {string} src - Script source URL
     * @returns {Promise} - Resolves when script is loaded
     */
    loadScript(src) {
        return new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.src = src;
            script.onload = () => resolve();
            script.onerror = () => reject(new Error(`Failed to load script: ${src}`));
            document.head.appendChild(script);
        });
    }
    
    /**
     * Initialize the module
     * @returns {Promise<boolean>} - Resolves with success status
     */
    async initialize() {
        try {
            // The measureText function will be provided by the game controller later
            this.reportProgress(100, "Paragraph layout initialized");
            return true;
        } catch (error) {
            console.error("Error initializing paragraph layout:", error);
            return false;
        }
    }
    
    /**
     * Calculate layout for a paragraph
     * @param {string} processedText - The pre-processed text (with SmartyPants and hyphenation)
     * @param {Array<number>} measures - Array of line width measurements
     * @param {boolean} hyphenate - Whether to enable hyphenation
     * @param {Function} [measureFunc] - Optional specific measurement function for this call
     * @returns {Object} Layout data with nodes and breaks
     */
    calculateLayout(processedText, measures, hyphenate = true, measureFunc = null) {
        const measure = measureFunc || this.measureText; // Use provided func or fallback to instance default
        if (typeof measure !== 'function') {
            throw new Error('No text measurement function available');
        }
        
        return this.kapAlgorithm(processedText, measure, measures, hyphenate);
    }

    /**
     * Set a new text measurement function
     * @param {Function} measureFunc - The new measurement function
     */
    setMeasureFunction(measureFunc) {
        this.measureText = measureFunc;
    }

    /**
     * Set a new Knuth and Plass algorithm implementation
     * @param {Function} kapFunc - The new KAP algorithm function
     */
    setKapAlgorithm(kapFunc) {
        this.kapAlgorithm = kapFunc;
    }
}

// Create the singleton instance
const ParagraphLayout = new ParagraphLayoutModule();

// Register with the module registry
moduleRegistry.register(ParagraphLayout);

// Export the module
export { ParagraphLayout };

// Keep a reference in window for loader system
window.ParagraphLayout = ParagraphLayout;
