module KB {

    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    ////////////////////    KEYBOARD     ///////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////

    export class Keyboard extends Phaser.Group {
        ////////////////////////////////////////////////////////////////////////
        ////////////////////    ATTRIBUTES   ///////////////////////////////////
        ////////////////////////////////////////////////////////////////////////
        /////////////// assign at creation
        public textStyle = { font: "normal 40pt Arial", fill: "white" };
        public arrSeparator = "|&|";
        public margin: number = 5;
        public hideable = true;
        public inputBoxStyle = { font: "normal 80pt Arial", fill: "black" };
        public controller: any;
        public maxLetters: number = 90;
        public RootController: any;
        private BigLetters = true;
        private SpecialLetters = true;
        /////////////// 

        public currInput: Phaser.Text = null;
        public nav: Phaser.Button;
        public keys: Array<Phaser.Button> = [];

        /////////////// keyboard private variables
        private confirmBtn: Phaser.Button;
        private input: Phaser.Text;
        private keyInputGroup: Phaser.Group;


        private isSpaceEnabled = false;

        constructor(game, name, x, y, hideable?: boolean, keyMargin?: number) {
            super(game, null, name);
            this.x = x;
            this.y = y;

            if (hideable !== undefined && hideable !== null) {
                this.hideable = hideable;
            }

            if (keyMargin !== undefined && keyMargin !== null) {
                this.margin = keyMargin;
            }

        }

        initialize(keyArr: String, btnKey: string, navKey?: string) {
            var arr = keyArr.split(this.arrSeparator);
            var len = arr.length;

            this.keyInputGroup = this.game.add.group();
            this.addChild(this.keyInputGroup);

            var keys = 0;
            var m = 0;
            if (this.hideable) {
                m = this.addHideBtn(navKey || btnKey);
                //m = this.addHideBtn( btnKey);
                m += this.addinputBox(m);
            }

            for (var i = 0; i < arr.length; i++) {
                keys += arr[i].length;
            }

            if (keys < len) {
                throw new RangeError("Not enough space for all keys");
            }

            var j = 1;
            var b = this.game.add.button(0, m, btnKey, this.keyClick, this, 0, 0, 1, 0, this);
            var txt = this.game.add.text(0, 0, arr[0][0], this.textStyle);
            txt.x = (b.width - txt.width) / 2;
            txt.y = (b.height - txt.height) / 2;
            b.addChild(txt);
            this.keys.push(b);
            this.keyInputGroup.add(b);

            for (var i = 0; i < arr.length; i++) {
                var row = arr[i];
                for (; j < row.length; j++) {

                    var t = this.game.add.button(j * (b.width + this.margin), m + i * (b.height + this.margin), btnKey, this.keyClick, this, 0, 0, 1, 0, this);
                    if (row[j] == "^" || row[j] == "&" || row[j] == " ") {
                        if (row[j] == "&") {
                            var txt = this.game.add.text(0, 0, 'alt', this.textStyle);
                        }
                        if (row[j] == "^") {
                            var txt = this.game.add.text(0, 0, 'shift', this.textStyle);
                        }
                        if (row[j] == " ") {
                            var txt = this.game.add.text(0, 0, 'spacja', { font: "normal 25pt Arial", fill: "white" });
                            this.isSpaceEnabled = true;
                        }

                    }
                    else
                        var txt = this.game.add.text(0, 0, row[j], this.textStyle);
                    txt.x = (t.width - txt.width) / 2;
                    txt.y = (t.height - txt.height) / 2;
                    t.addChild(txt);
                    this.keys.push(t);
                    this.keyInputGroup.add(t);
                }
                j = 0;
            }

            this.addKeyboardListener();

            if (this.hideable) {
                this.input.parent.width = this.width - this.margin - this.confirmBtn.width;
                this.nav.width = 0.2 * this.width;
                this.nav.x = 0.4 * this.width;
                this.y = this.game.world.height - this.nav.height;
                this.keyInputGroup.visible = false;
            }

        }

        private addHideBtn(key: string): number {
            var y = 0;
            EU.Log("klucz" + key);
            this.nav = this.game.add.button(0, 0, key, this.navClick, this, 0, 0, 1, 0, this);
            this.nav.scale.y = 0.4;
            y = this.nav.height + this.margin;
            this.addChild(this.nav);
            return y;
        }

        private addinputBox(m: number): number {
            var fontSize = 20;
            // var LetterAmountmultipler = 80 * (this.maxLetters / 2);
            this.inputBoxStyle.font = "normal " + fontSize + "pt Arial";
            var y = 0;
            this.confirmBtn = this.game.add.button(0, m, "key", this.confirm, this, 0, 0, 1, 0, this.keyInputGroup);
            this.confirmBtn.frame = 2;
            this.confirmBtn.inputEnabled = true;
            var txt = this.game.add.text(0, 0, "OK", this.textStyle);
            txt.x = (this.confirmBtn.width - txt.width) / 2;
            txt.y = (this.confirmBtn.height - txt.height) / 2;
            this.confirmBtn.addChild(txt);

            var bmd = this.game.add.bitmapData(400, 400);
            bmd.ctx.rect(0, 0, 400, 400);
            bmd.ctx.fillStyle = '#cdcdcd';
            bmd.ctx.fill();
            var box = this.game.add.sprite(this.confirmBtn.width + this.margin, m, bmd);
            box.alpha = 0.5;
            box.height = this.confirmBtn.height;
            this.input = this.game.add.text(0, 0, "", this.inputBoxStyle);
            // this.input.x = (box.width/2 - this.input.width/2);
            this.input.y = (box.height - this.input.height) / 2;
            this.input.scale.setTo(1, 6);
            box.addChild(this.input);

            this.keyInputGroup.addChild(box);
            y = this.confirmBtn.height + this.margin;
            return y;
        }

        addKeyboardListener() {
            var bspace = this.game.input.keyboard.addKey(Phaser.Keyboard.BACKSPACE);
            var space = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
            var alt = this.game.input.keyboard.addKey(Phaser.Keyboard.ALT);
            var shift = this.game.input.keyboard.addKey(Phaser.Keyboard.SHIFT);
            var enter = this.game.input.keyboard.addKey(Phaser.Keyboard.ENTER);

            this.game.input.keyboard.addKeyCapture(Phaser.Keyboard.BACKSPACE);
            this.game.input.keyboard.addKeyCapture(Phaser.Keyboard.SHIFT);
            this.game.input.keyboard.addKeyCapture(Phaser.Keyboard.SPACEBAR);
            this.game.input.keyboard.addKeyCapture(Phaser.Keyboard.ALT);


            this.game.input.keyboard.addCallbacks(this, null, null, this.keyPress);
            space.onDown.add(this.keyPress, this);
            bspace.onDown.add(this.keyPress, this);
            alt.onDown.add(this.keyPress, this);
            alt.onUp.add(this.keyUp, this);
            shift.onDown.add(this.keyPress, this);
            shift.onUp.add(this.keyUp, this);
            enter.onDown.add(this.keyPress, this);
        }
        navClick() {

            if (this.nav.exists) {
                var pt = this.game.world.height - this.nav.height;
                var vis = false;
                // EU.Log(this);
                if (!this.keyInputGroup.visible) {
                    vis = true;
                    this.keyInputGroup.visible = vis;
                    pt = this.game.world.height - this.height;
                } else {
                    this.keyInputGroup.visible = vis;
                }
                var tw = this.game.add.tween(this.cameraOffset);
                tw.to({ y: pt }, 500, Phaser.Easing.Cubic.InOut, true, 0, 0);
            }
            //  tw.start();
        }


        keyClick(e) {

            var len = this.keys.length;
            if (e.children[0].text == "shift" || e.children[0].text == "alt" || e.children[0].text == "spacja") {
                if (e.children[0].text == "shift") {
                    for (var i = 0; i < len; i++) {
                        var s: Phaser.Text = <Phaser.Text>this.keys[i].children[0];
                        if (s.text == "shift" || s.text == "alt" || s.text == "spacja" ) {
                        }
                        else {
                            if (s.text.length > 0)
                                if (this.BigLetters) {
                                    s.text = s.text.toLocaleUpperCase();
                                   // this.BigLetters = 1;
                                }
                                else {
                                    s.text = s.text.toLocaleLowerCase();
                                   // this.BigLetters = 0;
                                }
                        }
                    }
                    this.BigLetters = !this.BigLetters;
                }
                if (e.children[0].text == "alt") {
                    for (var i = 0; i < len; i++) {
                        var s: Phaser.Text = <Phaser.Text>this.keys[i].children[0];
                        if (s.text == "shift" || s.text == "alt" || s.text == "spacja") {
                        }
                        else {
                            if (s.text.length > 0)
                                if (this.SpecialLetters) {
                                    s.text = this.swapToDiactric(s.text);
                                    //this.SpecialLetters = 1;
                                }
                                else {
                                    s.text = this.swapFromDiactric(s.text);
                                    //this.SpecialLetters = 0;
                                }
                        }

                    }
                    this.SpecialLetters = !this.SpecialLetters;
                }
                if (e.children[0].text == "spacja")
                {
                this.input.text = this.input.text + " ";
                }
            }
        
        else{
        if (this.input.text.length <= this.maxLetters) {
            //EU.Log(e.children[0].text + " size:" + this.input.text.length);
                   

            this.input.text = this.input.text + e.children[0].text;

        }
        else {
            this.input.text = "";
        }
    }
    // this.currInput = e.children[0].text;
    //var t = e.children[0].text;
    // this.input.text = this.input.text + t;
    // return t;
}

        private keyPress(e) {
    var len = this.keys.length;

    if (this.input.exists)
        switch (e.keyCode) {
            case 8:
                EU.Log('backspace');
                this.input.text = this.input.text.slice(0, this.input.text.length - 1);
                break;
            case 13:
                EU.Log("enter");
                //if (this.currInput !== null) {
                // this.confirm(this.confirmBtn);
                //this.input.text = this.input.text + " ";
                // this.setCurrentInput(this.input);

                //}
                break;
            case 16:
                for (var i = 0; i < len; i++) {

                    var s: Phaser.Text = <Phaser.Text>this.keys[i].children[0];

                    if (s.text.length > 0)
                        s.text = s.text.toLocaleUpperCase();
                }
                break;
            case 18:
                for (var i = 0; i < len; i++) {
                    var s: Phaser.Text = <Phaser.Text>this.keys[i].children[0];

                    if (s.text.length > 0)
                        s.text = this.swapToDiactric(s.text);
                }
                break;
            case 32:
                EU.Log('spacja');
                if (this.isSpaceEnabled == true) {
                    this.input.text = this.input.text + " ";

                }
                break;
            default:
                var cl = this.getKey(e);
                if (cl !== null)
                    if (this.input.text.length <= this.maxLetters) {
                        //EU.Log(e.children[0].text + " size:" + this.input.text.length);
                        this.input.text = this.input.text + e;

                    }
                    else {
                        this.input.text = "";
                    }
                        
                // this.keyClick(cl);
                // this.keyClick(cl);
                if (this.currInput !== null) {
                    // this.input.text = this.input.text + e;
                }
                break;
        }

}

        private keyUp(e) {
    var len = this.keys.length;
    if (this.input.exists)
        switch (e.keyCode) {
            case 16:
                for (var i = 0; i < len; i++) {
                    var s: Phaser.Text = <Phaser.Text>this.keys[i].children[0];
                    if (s.text.length > 0)
                        s.text = s.text.toLocaleLowerCase();
                }
                break;
            case 18:
                for (var i = 0; i < len; i++) {
                    var s: Phaser.Text = <Phaser.Text>this.keys[i].children[0];
                    if (s.text.length > 0)
                        s.text = this.swapFromDiactric(s.text);
                }
                break;
        }
}

confirm(e) {
    if (this.controller !== null) {
        if (this.input.text == " ")
            this.input.text = " ?";
        // EU.Log("text: " + this.input.text + " sizeof: " + this.input.text.length);
        this.input.text = this.input.text.slice(1, this.input.text.length);
        // EU.Log("After:: " + this.input.text + " sizeof: " + this.input.text.length);
        this.controller.setText(this.input.text);
        this.controller.father.width = this.controller.width + 10;
        //  EU.Log("parent: " + this.controller.parent.x + " item: " + this.controller.x);
        //this.controller.anchor.set(0.5, 0.5);
        this.controller.x = this.controller.father.x;
        this.controller.x = (this.controller.parent.width / 2 - this.controller.width / 2);
        this.controller.x = this.controller.father.x;
        this.navClick();
        this.input.text = "";


    }
    if (this.currInput !== null) {
        // this.currInput.setText(this.input.text);
        // this.currInput = null;
        e.frame = 2;
        this.confirmBtn.inputEnabled = false;


    }
    if (this.RootController != null) {
        if (this.RootController.checkComplition)
            this.RootController.checkComplition(this);
        else this.RootController.checkIfEverythingIsCorrect();
    }
    return
}

setCurrentInput(txt: Phaser.Text) {
    this.confirm(this.confirmBtn);
    this.currInput = txt;
    this.confirmBtn.inputEnabled = true;
    this.confirmBtn.frame = 0;
}

        private getKey(e): Phaser.Button {
    var ret: Phaser.Button = null;
    var len = this.keys.length;
    for (var i = 0; i < len; i++) {
        if ((<Phaser.Text>this.keys[i].children[0]).text === e) {
            ret = this.keys[i];
        }
    }
    return ret;
}

        private swapToDiactric(txt: string): string {
    var ret = txt.replace(/a/g, 'ą').replace(/A/g, 'Ą')
        .replace(/c/g, 'ć').replace(/C/g, 'Ć')
        .replace(/e/g, 'ę').replace(/E/g, 'Ę')
        .replace(/l/g, 'ł').replace(/L/g, 'Ł')
        .replace(/n/g, 'ń').replace(/N/g, 'Ń')
        .replace(/o/g, 'ó').replace(/O/g, 'Ó')
        .replace(/s/g, 'ś').replace(/S/g, 'Ś')
        .replace(/z/g, 'ż').replace(/Z/g, 'Ż')
        .replace(/x/g, 'ź').replace(/X/g, 'Ź');;

    return ret;
}

        private swapFromDiactric(txt: string): string {
    var ret = txt.replace(/ą/g, 'a').replace(/Ą/g, 'A')
        .replace(/ć/g, 'c').replace(/Ć/g, 'C')
        .replace(/ę/g, 'e').replace(/Ę/g, 'E')
        .replace(/ł/g, 'l').replace(/Ł/g, 'L')
        .replace(/ń/g, 'n').replace(/Ń/g, 'N')
        .replace(/ó/g, 'o').replace(/Ó/g, 'O')
        .replace(/ś/g, 's').replace(/Ś/g, 'S')
        .replace(/ż/g, 'z').replace(/Ż/g, 'Z')
        .replace(/ź/g, 'x').replace(/Ź/g, 'X');;
    return ret;
}
    }

    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    ////////////////////  INPUT OBJECT   ///////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////

}