import {LeafSegment} from "../Segment/LeafSegment";
import {Helper} from "../../../../../../js/lib/pwa-lib";
import {ParentSegment} from "../Segment/ParentSegment";

export class Level {
    constructor(templateContainer) {
        this.rootSegment = null;
        this.words = [];
        this.startRotations = [];
        this.templateContainer = templateContainer;

        this.hasWon = false;
        this.id = null;

        this.wonResolver = null;
        this.giveUpResolver = null;

        const self = this;
        this.wonPromise = new Promise((resolve, reject) => {
            self.wonResolver = resolve;
            self.giveUpResolver = reject;
        });

        this.segmentClickedListener = () => {};
    }

    saveAsCurrentLevel(){
        let rotations = this.getCurrentRotations();
        let locked = this.getCurrentLocked();
        localStorage.setItem("currentLevel", JSON.stringify({"id": this.id, "rotations": rotations, "locks":locked}));
    }

    getCurrentLocked(){
        if (this.rootSegment !== null)
        {
            return this.rootSegment.getCurrentLocked([]);
        }
        return [];
    }

    getCurrentRotations(){
        if (this.rootSegment !== null)
        {
            return this.rootSegment.getCurrentRotations([]);
        }
        return [];
    }

    setLocks(locks)
    {
        if (this.rootSegment !== null){
            this.rootSegment.applyLocks(locks);
        }
    }

    setId(id)
    {
        this.id = id;
    }

    getId()
    {
        return this.id;
    }

    getLevel()
    {
        return this;
    }

    setRootSegment(rootSegment)
    {
        this.rootSegment = rootSegment;
        this.rootSegment.setParent(this);
        if (this.startRotations)
        {
            this.applyRotations();
        }
    }

    setWords(words)
    {
        this.words = [];
        for (let i = 0, n = words.length; i < n; i++) {
            this.words.push(words[i].toUpperCase());
        }
    }

    setStartRotations(rotations)
    {
        this.startRotations = rotations;
    }

    applyRotations(rotations)
    {
        if (this.rootSegment)
        {
            rotations = Helper.nonNull(rotations, this.startRotations);
            this.rootSegment.applyRotations(rotations);
        }
    }

    getHasWon()
    {
        return this.hasWon;
    }

    checkHasWon(delayPromise) {
        if (this.rootSegment.isSolved()){
            this.hasWon = true;
            const self = this;
            Promise.resolve(delayPromise).then(()=>{
                self.wonResolver(true);
            });
            return true;
        }
        this.saveAsCurrentLevel();
        return false;
    }

    getWonPromise(){
        return this.wonPromise;
    }

    getRootSegment(){
        return this.rootSegment;
    }

    createSegments() {};

    getRotatableSegments(){
        return Level._getRotatableSegmentsFrom(this.rootSegment);
    }

    setSegmentClickedListener(listener){
        this.segmentClickedListener = listener;
    }

    static _getRotatableSegmentsFrom(segment){
        let rotatable = [];
        if (segment.canRotate())
        {
            rotatable.push(segment);
        }
        if (segment instanceof ParentSegment){
            for (let i = 0; i < segment.children.length; i++) {
                rotatable.push.apply(rotatable, Level._getRotatableSegmentsFrom(segment.children[i]));
            }
        }
        return rotatable;
    }

    static _createLeafsForWord(word, leafSegmentTemplate)
    {
        let leafSegments = [];
        for (let i = 0, n = word.length; i < n; i++) {
            leafSegments.push(new LeafSegment(Helper.cloneNode(leafSegmentTemplate), word.charAt(i)));
        }
        return leafSegments;
    }
}