/// <reference path="BarChartVisualisation.ts" />
/// <reference path="BarChartColumn.ts" />
/// <reference path="../FDEventHandler.ts" />
/// <reference path="../resources/three.d.ts" />

module FD {

    export class BarChartEventHandler extends FDEventHandler {

        private selectedMesh: THREE.Mesh;
        private mouseDownPosition: THREE.Vector2;
        private visualisation: BarChartVisualisation;
        private activeMat;
        private inactiveMat;
        private action;
        private sprite;
        private spriteInit;
        private texture1;
        private context1;
        private fontsize: number;
        private canvas1;
        private selectedColor;
        private hoveredBar;

        constructor(debug: boolean, fluidDiagrams: FluidDiagrams) {
            super(debug, fluidDiagrams);
            this.mouseDown = false;
            this.mouseDownPosition = new THREE.Vector2();
            this.visualisation = <BarChartVisualisation>this.fluidDiagrams.getVisualisation();
            this.activeMat = new THREE.LineBasicMaterial({ color: 0x0000ff });
            this.inactiveMat = new THREE.LineBasicMaterial({ color: 0xcccccc });

            this.selectedMesh = null;
            this.action = null;
            this.sprite = null;
            this.spriteInit = false;
            this.fontsize = 20;
            this.selectedColor = 0xffffff;
            this.hoveredBar = null;

        }

        public onMouseDown(e: Event) {

            var clickedElem = this.fluidDiagrams.objectFromMouse((<any>e).clientX, (<any>e).clientY);
            if (clickedElem != null) {
                var marker = clickedElem.name.search(":");
                var substring = clickedElem.name.substring(0, marker - 1);

                if (clickedElem.name == this.visualisation.titlePopUP) {
                    var newtitle = prompt("Name of the title:", "title");
                    if (newtitle) {
                        this.visualisation.title = newtitle;
                        this.visualisation.update();
                        this.visualisation.drawLegend();
                    }
                }

                if (clickedElem.name == this.visualisation.XtitlePopUP) {
                    var newtitle = prompt("Name of the Xtitle:", "Xtitle");
                    if (newtitle) {
                        this.visualisation.Xtitle = newtitle;
                        this.visualisation.update();
                        this.visualisation.drawLegend();
                    }
                }

                if (clickedElem.name == this.visualisation.YtitlePopUP) {
                    var newtitle = prompt("Name of the Ytitle:", "Ytitle");
                    if (newtitle) {
                        this.visualisation.Ytitle = newtitle;
                        this.visualisation.update();
                        this.visualisation.drawLegend();
                    }
                }

                if (clickedElem instanceof THREE.Mesh) {

                    if (document.body.style.cursor != 'default') {
                        this.visualisation.changeColorOfSameKind(this.selectedColor, substring);
                        document.body.style.cursor = 'default';
                    }
                }
                this.mouseDown = true;
            }
        }

        public onMouseUp(e: Event) {

            this.mouseDown = false;
            this.selectedMesh = null;
        }

        public onMouseMove(e: Event) {

            this.createSprite();


            
            var hoveredElem = this.fluidDiagrams.objectFromMouse((<any>e).clientX, (<any>e).clientY);

            
            //reset hovereffect
            if (hoveredElem == null && this.hoveredBar != null) {
                var marker = this.hoveredBar.name.search(":");
                var substring = this.hoveredBar.name.substring(0, marker - 1);
                this.visualisation.hideShadow(substring);

                //hide shadows
                this.hoveredBar = null;
            }


            //hovertext
            if (hoveredElem instanceof THREE.Mesh) {
                var lineHeight = this.fontsize;
                this.context1.clearRect(0, 0, 640, 480);
                var message = hoveredElem.name;
                var metrics = this.context1.measureText(message);
                var width = metrics.width;

                var maxTextWidth = 0;
                var words;
                var height = lineHeight;
                if (width > 400) {

                    words = message.split('\n');
                    height = words.length * lineHeight;
                    for (var n = 0; n < words.length; n++) {
                        var saveN;
                        if (maxTextWidth < words[n].length) {
                            maxTextWidth = words[n].length;
                            saveN = n;
                        }
                    }
                    maxTextWidth = this.context1.measureText(words[saveN]).width;
                } else {

                    maxTextWidth = metrics.width;
                }

                //  this.canvas1.width = maxTextWidth*2;

                this.context1.fillStyle = "rgba(0,0,0,0.95)"; // black border
                this.context1.fillRect(0, 0, maxTextWidth + 8, height + 8);
                this.context1.fillStyle = "rgba(255,255,255,0.95)"; // white filler
                this.context1.fillRect(2, 2, maxTextWidth + 4, height + 4);
                this.context1.fillStyle = "rgba(0,0,0,1)"; // text color


                var y = 0;
                if (metrics.width > 400) {
                    for (var n = 0; n < words.length; n++) {
                        this.context1.fillText(words[n], 4, this.fontsize + y + 2);
                        y += lineHeight;
                    }
                } else {
                    this.context1.fillText(message, 4, this.fontsize + 2);
                }

                this.texture1.needsUpdate = true;
                //TODO convert screen coordinates to local coordinates:
                var offsetLeft = this.fluidDiagrams.domElement.offsetLeft;
                var offsetTop = this.fluidDiagrams.domElement.offsetTop;
                var eltx = (<any>e).clientX;
                var elty = this.fluidDiagrams.domElement.height-(<any>e).clientY;
                var vpx = ((eltx / this.fluidDiagrams.domElement.width) * 2 - 1);
                var vpy = (-(elty / this.fluidDiagrams.domElement.height) * 2 + 1); 
                debugPrinter.print(eltx+" "+elty,true);                
                this.sprite.position.set(eltx, elty, 2);
            }

            else {
                this.context1.clearRect(0, 0, 300, 300);
                this.texture1.needsUpdate = true;
            }
            //delete empty hoovers
            if (hoveredElem != null && hoveredElem.name == "") {
                this.context1.clearRect(0, 0, 300, 300);
                this.texture1.needsUpdate = true;
            }


            //hovereffect
            if (hoveredElem instanceof THREE.Mesh && this.hoveredBar != hoveredElem /* && hoveredElem != hoveredElemShadows*/) {
                //downscale old hovered first
                if (this.hoveredBar != null) {
                    var marker = this.hoveredBar.name.search(":");
                    var substring = this.hoveredBar.name.substring(0, marker - 1);
                    this.visualisation.hideShadow(substring);

                }

                this.hoveredBar = hoveredElem;

                //show new shadows
                var marker = hoveredElem.name.search(":");
                var substring = hoveredElem.name.substring(0, marker - 1);
                //                alert("set " + substring );
                this.visualisation.drawShadow(substring);
            }
        }

        public setNewHoveredElement(mesh) {

            this.hoveredBar = mesh;
        }

        public mouseWheel(e: Event) {
            //debugPrinter.print("MouseWheel not implemented", this.debug);
        }

        public createSprite() {

            if (this.spriteInit == false) {

                var size = 512;
                this.canvas1 = <any>document.createElement('canvas');
                // canvas1.height = size;
                // canvas1.width = size;

                this.context1 = this.canvas1.getContext('2d');
                this.context1.font = "Bold 20px Arial";
                //          context1.textAlign = 'center';
                this.context1.fillStyle = "rgba(0,0,0,0.95)";
                // this.context1.fillText('', 0, 20);

                // canvas contents will be used for a texture
                this.texture1 = new THREE.Texture(this.canvas1)
                this.texture1.needsUpdate = true;

                var spriteMat = new THREE.SpriteMaterial({ map: this.texture1 });
                //spriteMat.useScreenCoordinates = true;
                //spriteMat.alignment = THREE.SpriteAlignment.topLeft;
                //          spriteMat.transparent = false;

                this.sprite = new THREE.Sprite(spriteMat);
                this.sprite.scale.set(200, 100, 1.0);
                //            this.sprite.position.set( 50, 50, 0 );
                this.fluidDiagrams.scene.add(this.sprite);

                this.spriteInit = true;
            }


        }

        public changeColorTheme(color: Number) {
            this.visualisation.changeColorTheme(color);
        }

        public selectColor(color: Number) {
            this.selectedColor = color;
        }

        public visualisationUpdate() {
            this.visualisation.update();
        }

        public legend() {
            this.visualisation.toggleLegend();
        }

        public changeSeparationmark(mark) {
            this.visualisation.separationMark = mark;
            this.visualisation.update();
        }

        public changeDecimalPoint(mark) {
            this.visualisation.floatSeperationMark = mark;
            this.visualisation.update();

        }
    }
}
