/*
* Created by Ari Rauhala, Christine Pichler
*/
var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
/// <reference path="../FDNode.ts" />
/// <reference path="../resources/jquery.d.ts" />
/// <reference path="../debugPrinter.ts" />
/// <reference path="../resources/three.d.ts" />
/// <reference path="../FDGeomObject.ts" />
/// <reference path="../FDHelpers.ts" />
/// <reference path="../FDVisualisation.ts" />
/// <reference path="LineChartLine.ts" />
/// <reference path="FDLine.ts" />
var FD;
(function (FD) {
    var LineChartVisualisation = (function (_super) {
        __extends(LineChartVisualisation, _super);
        function LineChartVisualisation(debug, fluidDiagram) {
            _super.call(this, debug, fluidDiagram);
            this.defaultLineColors = [
                0x0000ff, 0x00ff00, 0xffff00, 0xff00ff, 0x00ffff, 0x009900, 0x000099, 0x990000, 0x009999, 0xff0000
            ];
            this.floatSeperationMark = ".";
            this.separationMark = ",";
            this.xValueIsYear = true;
            this.lineAmount = 0;
            this.axisYTitle = "Y Title";
            this.axisXTitle = "X Title";
            this.title = "Diagram";
            this.nodeRep = this.createSquare();
            this.fontSize = 13;
            this.lineIsSelected = false;
            this.newColorSelected = false;
            this.backgroundColor = 0xffffff; // set the color for the background
            this.deselectColor = 0x999999;
            this.axisColor = 0x999999;
            this.gridColor = 0xe5e5e5;
            this.nodeSize = 6; // size for the nodes 6
            this.lineSize = 4;
            this.yTickAmount = 8; //default tickAmount, if this does not fit to the tick mark spacing for the rounded values, this will be automatically changed
            this.circleNodeSize = (this.nodeSize / 10);
            this.xGridsBetweenValues = 1; // how many vertical lines between value markers on x-axis
            this.yGridsBetweenValues = 1; // how many horizontal lines between value markers on y-axis
            this.isXGridDrawn = true;
            this.isYGridDrawn = true;
            this.initDiagram(); // initialize the sizes for the diagram view
            this.axesLabels = [];
            this.lines = [];
        }
        LineChartVisualisation.prototype.visualise = function () {
            if (this.nodes.length <= 1) {
                this.createGrid();
                alert("Invalid csv file!");
                return;
            }

            var i = 0;
            for (var node in this.fluidDiagrams.rootNodes) {
                var n = this.fluidDiagrams.rootNodes[node];
                this.axesLabels[i] = n.getUniqueId();
                i++;
            }

            var lables = this.nodes[0].getData();
            this.axisYTitle = "";
            for (var n_ in lables) {
                FD.debugPrinter.print(this.lineAmount.toString(), this.debug);
                if (this.lineAmount > 0)
                    this.axisYTitle = "Values";
                else
                    this.axisYTitle = n_;

                this.lines[n_] = new FD.LineChartLine(n_);
                this.lines[n_].setColor(this.defaultLineColors[this.lineAmount < 10 ? this.lineAmount : this.lineAmount % 10]);
                this.lineAmount++;

                //fill lines with data
                var j = 0;
                for (var node in this.nodes) {
                    var currentNode = this.nodes[node];
                    var data = currentNode.getData();
                    this.lines[n_].addEntrie(this.axesLabels[j], data[n_]);
                    FD.debugPrinter.print(this.axesLabels[j] + "  " + data[n_], this.debug);
                    j++;
                }
            }

            this.maxY = this.getMaximumValue();
            this.minY = this.getMinimumValue();
            FD.debugPrinter.print("Min: " + this.minY, this.debug);
            FD.debugPrinter.print("Max: " + this.maxY, this.debug);
            this.calculateTicks();
            this.yTickMarkSpacing = this.diagramHeight / this.yTickAmount;
            this.xValueCount = this.nodes.length - 1;
            FD.debugPrinter.print("xValuecount " + this.xValueCount, this.debug);
            this.updateGui();
        };

        LineChartVisualisation.prototype.initDiagram = function () {
            this.yValueCount = this.fluidDiagrams.width / 10;
            this.diagramTopPadding = 60;
            this.diagramBottomPadding = 100;
            this.diagramRightPadding = this.fluidDiagrams.width / 10 - 50;
            this.diagramLeftPadding = this.fluidDiagrams.width / 10 + 50;
            this.diagramWidth = this.fluidDiagrams.width - this.diagramLeftPadding - this.diagramRightPadding;
            this.diagramHeight = this.fluidDiagrams.height - this.diagramBottomPadding - this.diagramTopPadding;
            this.right = (this.fluidDiagrams.width / 2) - this.diagramRightPadding;
            this.left = -((this.fluidDiagrams.width / 2) - this.diagramLeftPadding);
            this.top = (this.fluidDiagrams.height / 2) - this.diagramTopPadding;
            this.bottom = -((this.fluidDiagrams.height / 2) - this.diagramBottomPadding);

            FD.debugPrinter.print("------initDiagram()------", this.debug);
            FD.debugPrinter.print("diagramRightPadding: " + this.diagramRightPadding, this.debug);
            FD.debugPrinter.print("diagramLeftPadding: " + this.diagramLeftPadding, this.debug);
            FD.debugPrinter.print("diagramTopPadding: " + this.diagramTopPadding, this.debug);
            FD.debugPrinter.print("diagramBottomPadding: " + this.diagramBottomPadding, this.debug);
            FD.debugPrinter.print("fluidDiagrams.width: " + this.fluidDiagrams.width, this.debug);
            FD.debugPrinter.print("fluidDiagrams.height: " + this.fluidDiagrams.height, this.debug);
            FD.debugPrinter.print("diagramwidth: " + this.diagramWidth, this.debug);
            FD.debugPrinter.print("diagramheight: " + this.diagramHeight, this.debug);
            FD.debugPrinter.print("right: " + this.right, this.debug);
            FD.debugPrinter.print("left: " + this.left, this.debug);
            FD.debugPrinter.print("bottom: " + this.bottom, this.debug);
            FD.debugPrinter.print("top: " + this.top, this.debug);
            FD.debugPrinter.print("---------------------------", this.debug);
        };

        LineChartVisualisation.prototype.updateGui = function () {
            this.deleteMarkers();
            this.createGrid();
            this.createAxis();
            this.createXValues();
            this.createYValues();
            if (this.legendVisible)
                this.createLegend();
            this.createLines();
        };

        LineChartVisualisation.prototype.createLines = function () {
            var colNmbr = 0;
            for (var c in this.lines) {
                var opacity = 1.0;
                var prevPointX = 0;
                var prevPointY = 0;
                var start = { x: 0, y: 0 };
                var end = { x: 0, y: 0 };
                var currentNodeIndex = 0;
                if (this.lines[c].getColor() == 0x000000)
                    this.lines[c].setColor(this.defaultLineColors[colNmbr]);

                for (var n in this.nodes) {
                    var currentNode = this.nodes[n];
                    var data = currentNode.getData();
                    if (this.lineIsSelected && c == this.selectedLineIDString) {
                        if (this.newColorSelected) {
                            this.lines[c].setColor(this.newNodeColor);
                            this.newColorSelected = false;
                        }
                        //if (this.newNodeRepSelected) {
                        //    this.nodeRep = this.newNodeRep;
                        //    this.lineNodeReps[colNmbr] = this.nodeRep;
                        //}
                    }
                    if (this.lineIsSelected && c != this.selectedLineIDString) {
                        opacity = 0.4;
                        var sortMat = new THREE.MeshBasicMaterial({ transparent: true, color: this.deselectColor });
                    } else
                        var sortMat = new THREE.MeshBasicMaterial({ transparent: true, color: this.lines[c].getColor() });

                    end.x = (this.left + (currentNodeIndex * (this.diagramWidth / this.xValueCount)));
                    var resY = ((this.lines[c].nodes[this.axesLabels[currentNodeIndex]] - this.roundedMinY) / (this.roundedMaxY - this.roundedMinY));
                    end.y = this.diagramHeight * resY + this.bottom;

                    this.nodeMesh = new THREE.Mesh(this.nodeRep, sortMat);
                    this.nodeMesh.position = new THREE.Vector3(end.x, end.y, 0);
                    this.nodeMesh.scale = new THREE.Vector3(this.nodeSize, this.nodeSize, 1);

                    //this.nodeMesh.name = c + "\nx: " + currentNode.getUniqueId() + "\ny: " + data[c];
                    var delCurrNode = currentNode.getUniqueId();

                    if (!this.xValueIsYear) {
                        delCurrNode = this.insertDelemeters(delCurrNode);

                        if (delCurrNode == ("NaN" + this.floatSeperationMark + "N") || delCurrNode == "NaN")
                            delCurrNode = currentNode.getUniqueId();
                    }

                    this.nodeMesh.name = c + "\nx: " + delCurrNode + "\ny: " + this.insertDelemeters(data[c]);
                    this.nodeMesh.opacity = opacity;
                    this.nodes[n].addGeometry(this.nodeMesh);

                    //add lines
                    if (n != "0") {
                        var line = new FDLine(start, end, this.lineSize / 2);
                        var lineGeom = line.drawLine();
                        var lineMesh = new THREE.Mesh(lineGeom, sortMat);
                        lineMesh.name = c;
                        this.nodes[n].addGeometry(lineMesh);
                    }
                    start.x = end.x;
                    start.y = end.y;
                    currentNodeIndex++;
                }
                colNmbr++;
            }
        };

        //draws a grid
        LineChartVisualisation.prototype.createGrid = function () {
            //this can be changed with a check box and a slider
            var horizontalGridAmount = this.xValueCount * this.xGridsBetweenValues;
            var gridWidth = this.diagramWidth / horizontalGridAmount;
            var gridHeight = this.yTickMarkSpacing / this.yGridsBetweenValues;
            var horizontalGridLineAmount = this.yTickAmount * this.yGridsBetweenValues;
            var verticalGridLineAmount = this.diagramWidth / gridWidth;

            // horizontal lines -
            if (this.isYGridDrawn) {
                for (var horGr = 1; horGr < horizontalGridLineAmount + 1; horGr++) {
                    var linegeom = new THREE.Geometry();
                    linegeom.vertices.push(new THREE.Vector3(this.left, this.bottom + (horGr * gridHeight), -1));
                    linegeom.vertices.push(new THREE.Vector3(this.right, this.bottom + (horGr * gridHeight), -1));
                    var line = new THREE.Line(linegeom, new THREE.LineBasicMaterial({ color: this.gridColor }));
                    this.fluidDiagrams.addSceneObject(line);
                }
            }

            // vertical lines |
            if (this.isXGridDrawn) {
                for (var verGr = 1; verGr < verticalGridLineAmount + 1; verGr++) {
                    var linegeom = new THREE.Geometry();
                    linegeom.vertices.push(new THREE.Vector3(this.left + (verGr * gridWidth), this.top, -1));
                    linegeom.vertices.push(new THREE.Vector3(this.left + (verGr * gridWidth), this.bottom, -1));
                    var line = new THREE.Line(linegeom, new THREE.LineBasicMaterial({ color: this.gridColor }));
                    this.fluidDiagrams.addSceneObject(line);
                }
            }
        };

        LineChartVisualisation.prototype.createAxis = function () {
            var axes = new THREE.Geometry();

            // line from 0,0 to 0,y
            axes.vertices.push(new THREE.Vector3(this.left, this.top, 0)); // 0,y
            axes.vertices.push(new THREE.Vector3(this.left, this.bottom, 0)); // 0,0
            var line = new THREE.Line(axes, new THREE.LineBasicMaterial({ color: this.axisColor }));
            this.fluidDiagrams.addSceneObject(line);

            // line from 0,0 to x,0
            axes.vertices.push(new THREE.Vector3(this.right, this.bottom, 0)); //x,0
            axes.vertices.push(new THREE.Vector3(this.left, this.bottom, 0)); // 0,0
            line = new THREE.Line(axes, new THREE.LineBasicMaterial({ color: this.axisColor })); //0000ff
            this.fluidDiagrams.addSceneObject(line);

            // title for axis y
            var width = this.axisYTitle.length;
            this.drawLables(this.axisYTitle, width * 15, this.left - 50, 0, 90 * Math.PI / 180, 'center', '');

            // title for axis x
            width = this.axisXTitle.length;
            this.drawLables(this.axisXTitle, width * 15, 0, this.bottom - 70, 0, 'center', '');

            // diagram title
            width = this.title.length;
            this.drawLables(this.title, width * 15, 0, this.top + 40, 0, 'center', '');
            //// arrow at 0,y
            //var filterMat = <any>new THREE.MeshBasicMaterial({ transparent: true, color: this.axisColor });
            //var tri = this.createArrowHead();
            //var triMesh = new THREE.Mesh(tri, filterMat);
            //triMesh.position = new THREE.Vector3(this.left, this.top + 2, 0);
            //triMesh.scale = new THREE.Vector3(2, 2, 1);
            //triMesh.rotation.z = Math.PI / 360; // points up
            //this.fluidDiagrams.addSceneObject(triMesh);
            //// arrow at x,0
            //var filterMat2 = <any>new THREE.MeshBasicMaterial({ transparent: true, color: this.axisColor });
            //var tri2 = this.createArrowHead();
            //var triMesh2 = new THREE.Mesh(tri2, filterMat2);
            //triMesh2.position = new THREE.Vector3(this.right + 2, this.bottom, 0);
            //triMesh2.scale = new THREE.Vector3(2, 2, 1);
            //triMesh2.rotation.z = (3 / 2) * Math.PI; // points right
            //this.fluidDiagrams.addSceneObject(triMesh2);
        };

        //public createArrowHead(): THREE.Geometry {
        //    var triangleGeometry = new THREE.Geometry();
        //    triangleGeometry.vertices.push(new THREE.Vector3(1.0, 0.0, 0.0));
        //    triangleGeometry.vertices.push(new THREE.Vector3(0.0, -2.0, 0.0));
        //    triangleGeometry.vertices.push(new THREE.Vector3(2.0, -2.0, 0.0));
        //    triangleGeometry.faces.push(new THREE.Face3(0, 1, 2));
        //    triangleGeometry.computeBoundingBox();
        //    triangleGeometry.computeFaceNormals();
        //    return triangleGeometry;
        //}
        LineChartVisualisation.prototype.createLegend = function () {
            var posY = (this.fluidDiagrams.height / 2 - 20);
            var posX = -(this.fluidDiagrams.width / 2 - 55);
            var font = this.fontSize;
            this.fontSize = 16;
            this.drawLables('Legend', 150, posX, posY, 0, 'left', '0xffffff');
            posY -= 10;

            for (var l in this.lines) {
                posY -= this.fontSize;

                var color;
                var drawnName;

                color = this.lines[l].getColor().toString(16);

                while (color.length < 6)
                    color = '0' + color;

                drawnName = l;
                if (drawnName.length > 11) {
                    var tmp = l;
                    drawnName = drawnName.substr(0, 9) + "...";
                }
                this.maximum = -Number.MIN_VALUE;
                this.drawLables(drawnName, 150, posX, posY, 0, 'left', '#' + color);
            }
            this.fontSize = font;
        };

        LineChartVisualisation.prototype.drawLables = function (lableName, width, posX, posY, rot, float, color) {
            var canvas1 = document.createElement('canvas');
            canvas1.height = this.fontSize + 8;
            canvas1.width = width;
            var context1 = canvas1.getContext('2d');

            context1.font = "Bold " + this.fontSize + "px Arial";
            context1.fillStyle = color;
            context1.textAlign = 'left';

            context1.fillText(lableName, 28, this.fontSize + 2);

            // canvas contents will be used for a texture
            var texture1 = new THREE.Texture(canvas1);
            texture1.needsUpdate = true;
            var textMat = new THREE.MeshBasicMaterial({ map: texture1 });
            textMat.transparent = true;
            textMat.side = THREE.DoubleSide;
            var textPlane = new THREE.PlaneGeometry(canvas1.width, canvas1.height);
            var textMesh = new THREE.Mesh(textPlane, textMat);
            textMesh.position = new THREE.Vector3(posX, posY, 0);
            textMesh.rotation.z = rot;
            textMesh.name = lableName;
            this.fluidDiagrams.addSceneObject(textMesh);
        };

        LineChartVisualisation.prototype.createYValues = function () {
            var horizontalGridLineAmount = this.yTickAmount;

            for (var horGr = 0; horGr <= horizontalGridLineAmount; horGr++) {
                // draw tick marks on y-axis -
                var linegeom = new THREE.Geometry();
                linegeom.vertices.push(new THREE.Vector3(this.left, this.bottom + (horGr * this.yTickMarkSpacing), 0));
                linegeom.vertices.push(new THREE.Vector3(this.left - 4, this.bottom + (horGr * this.yTickMarkSpacing), 0));
                var line = new THREE.Line(linegeom, new THREE.LineBasicMaterial({ color: this.axisColor }));
                this.fluidDiagrams.addSceneObject(line);

                // draw value names on y-axis
                var value = this.roundedMinY + (this.roundedTickSpacing * horGr);
                value = this.insertDelemeters(value);
                this.createAxesValue(value, this.left - 20, this.bottom + (horGr * this.yTickMarkSpacing) - 3, 0);
            }
        };

        LineChartVisualisation.prototype.createXValues = function () {
            for (var verGr = 0; verGr <= this.xValueCount; verGr++) {
                // draw tick marks on x-axis |
                var linegeom = new THREE.Geometry();
                linegeom.vertices.push(new THREE.Vector3(this.left + (verGr * (this.diagramWidth / this.xValueCount)), this.bottom, 0));
                linegeom.vertices.push(new THREE.Vector3(this.left + (verGr * (this.diagramWidth / this.xValueCount)), this.bottom - 4, 0));
                var line = new THREE.Line(linegeom, new THREE.LineBasicMaterial({ color: this.axisColor }));
                this.fluidDiagrams.addSceneObject(line);

                // draw value names on x-axis
                var value = this.axesLabels[verGr];

                if (!this.xValueIsYear) {
                    value = this.insertDelemeters(value);

                    if (value == ("NaN" + this.floatSeperationMark + "N") || value == "NaN")
                        value = this.axesLabels[verGr];
                }
                this.createAxesValue(value, this.left + (verGr * (this.diagramWidth / this.xValueCount)) + 8, this.bottom - 35, (5 * Math.PI) / 3);
            }
        };

        LineChartVisualisation.prototype.createAxesValue = function (value, posX, posY, rot) {
            var canvas1 = document.createElement('canvas');
            canvas1.height = 20;
            canvas1.width = 100;
            var context1 = canvas1.getContext('2d');
            context1.font = "Bold " + this.fontSize + "px Arial";
            context1.fillStyle = "rgba(0,0,0,1)";
            context1.textAlign = 'center';
            FD.debugPrinter.print(value, this.debug);
            context1.fillText(value.toString(), 50, 10);

            // canvas contents will be used for a texture
            var texture1 = new THREE.Texture(canvas1);
            texture1.needsUpdate = true;
            var textMat = new THREE.MeshBasicMaterial({ map: texture1 });
            textMat.transparent = true;
            textMat.side = THREE.DoubleSide;
            var textPlane = new THREE.PlaneGeometry(100, 20);
            var textMesh = new THREE.Mesh(textPlane, textMat);
            textMesh.position = new THREE.Vector3(posX, posY, 0);
            textMesh.rotation.z = rot;
            this.fluidDiagrams.addSceneObject(textMesh);
        };

        LineChartVisualisation.prototype.getMinimumValue = function () {
            var minimum = Number.MAX_VALUE;
            for (var x in this.lines) {
                if (this.lines[x].getMin() < minimum)
                    minimum = this.lines[x].getMin();
            }
            return minimum;
        };

        LineChartVisualisation.prototype.getMaximumValue = function () {
            var maximum = -Number.MAX_VALUE;
            for (var x in this.lines) {
                if (this.lines[x].getMax() > maximum)
                    maximum = this.lines[x].getMax();
            }
            return maximum;
        };

        LineChartVisualisation.prototype.createTriangle = function () {
            var triangleGeom = new THREE.Geometry();
            triangleGeom.vertices.push(new THREE.Vector3(0.0, 0.8, 0.0));
            triangleGeom.vertices.push(new THREE.Vector3(-0.7, -0.6, 0.0));
            triangleGeom.vertices.push(new THREE.Vector3(0.7, -0.6, 0.0));
            triangleGeom.faces.push(new THREE.Face3(0, 1, 2));
            triangleGeom.computeBoundingBox();
            triangleGeom.computeFaceNormals();
            return triangleGeom;
        };

        LineChartVisualisation.prototype.createSquare = function () {
            var squareGeom = new THREE.Geometry();
            squareGeom.vertices.push(new THREE.Vector3(-0.5, 0.5, 0));
            squareGeom.vertices.push(new THREE.Vector3(-0.5, -0.5, 0));
            squareGeom.vertices.push(new THREE.Vector3(0.5, -0.5, 0));
            squareGeom.vertices.push(new THREE.Vector3(0.5, 0.5, 0));
            squareGeom.faces.push(new THREE.Face4(0, 1, 2, 3));
            squareGeom.computeBoundingBox();
            squareGeom.computeFaceNormals();
            return squareGeom;
        };

        LineChartVisualisation.prototype.createDiamond = function () {
            var diamondGeom = new THREE.Geometry();
            diamondGeom.vertices.push(new THREE.Vector3(0, 0.8, 0));
            diamondGeom.vertices.push(new THREE.Vector3(-0.6, 0, 0));
            diamondGeom.vertices.push(new THREE.Vector3(0, -0.8, 0));
            diamondGeom.vertices.push(new THREE.Vector3(0.6, 0, 0));
            diamondGeom.faces.push(new THREE.Face4(0, 1, 2, 3));
            diamondGeom.computeBoundingBox();
            diamondGeom.computeFaceNormals();
            return diamondGeom;
        };

        LineChartVisualisation.prototype.createStar = function () {
            var starPoints = [];
            starPoints.push(new THREE.Vector2(0, 0.9));
            starPoints.push(new THREE.Vector2(0.2, 0.2));
            starPoints.push(new THREE.Vector2(0.7, 0.2));
            starPoints.push(new THREE.Vector2(0.4, -0.2));
            starPoints.push(new THREE.Vector2(0.5, -0.8));
            starPoints.push(new THREE.Vector2(0, -0.4));
            starPoints.push(new THREE.Vector2(-0.5, -0.8));
            starPoints.push(new THREE.Vector2(-0.4, -0.2));
            starPoints.push(new THREE.Vector2(-0.7, 0.2));
            starPoints.push(new THREE.Vector2(-0.2, 0.2));
            var starShape = new THREE.Shape(starPoints);
            var starGeom = new THREE.ShapeGeometry(starShape);
            return starGeom;
        };

        LineChartVisualisation.prototype.createCircle = function () {
            var circleGeom = new THREE.CircleGeometry(this.circleNodeSize, 15);
            circleGeom.computeBoundingBox();
            circleGeom.computeFaceNormals();
            return circleGeom;
        };

        LineChartVisualisation.prototype.changeColor = function (color) {
            this.newNodeColor = color;
            this.newColorSelected = true;
        };

        LineChartVisualisation.prototype.changeColorOfSameKind = function (hexColor, name) {
            for (var node in this.nodes) {
                var allGeometry = this.nodes[node].getAllGeometry();
                for (var cube in allGeometry) {
                    var marker = allGeometry[cube].name.search(":");
                    var substring = allGeometry[cube].name.substr(0, marker);

                    if (name == substring) {
                        allGeometry[cube].material.color.setHex("0x" + hexColor);
                    }
                }
            }
        };

        LineChartVisualisation.prototype.deleteMarkers = function () {
            var myList = this.fluidDiagrams.nodeSceneGraph.getDescendants();
            for (var desc in myList) {
                var tmp = myList[desc];
                this.fluidDiagrams.nodeSceneGraph.remove(tmp);
            }

            for (var desc in this.fluidDiagrams.geometryObjects) {
                var tmp = this.fluidDiagrams.geometryObjects[desc];
                this.fluidDiagrams.geometryObjects[desc].remove(tmp);
            }

            for (var node in this.fluidDiagrams.rootNodes) {
                var n = this.fluidDiagrams.rootNodes[node];
                var geom = n.getAllGeometry();
                for (var geo in geom)
                    n.getNodeSceneGraph().remove(geom[geo]);
                geom.splice(0, 1);
            }
        };

        LineChartVisualisation.prototype.getLineIdByName = function (name) {
            var int = 0;
            for (var i in this.lines) {
                if (name == this.lines[i].getLineName()) {
                    return int;
                }
                int++;
            }
            return -1;
        };

        //calculates the y axis ticks based on the java code from Keith Andrews
        LineChartVisualisation.prototype.calculateTicks = function () {
            FD.debugPrinter.print("---------TickScale--------", this.debug);
            FD.debugPrinter.print("tickAmount: " + this.yTickAmount, this.debug);
            this.tickRange = this.niceNum(this.maxY - this.minY, false);
            this.roundedTickSpacing = this.niceNum(this.tickRange / (this.yTickAmount), true);
            this.roundedMinY = Math.floor(this.minY / this.roundedTickSpacing) * this.roundedTickSpacing;
            this.roundedMaxY = Math.ceil(this.maxY / this.roundedTickSpacing) * this.roundedTickSpacing;
            var calculatedTickAmount = ((this.roundedMaxY - this.roundedMinY) / this.roundedTickSpacing);
            if (calculatedTickAmount != this.yTickAmount) {
                this.yTickAmount = calculatedTickAmount; // - this.roundedMinY;
            }

            FD.debugPrinter.print("tickRange: " + this.tickRange, this.debug);
            FD.debugPrinter.print("roundedTickSpacing: " + this.roundedTickSpacing, this.debug);
            FD.debugPrinter.print("roundedMin: " + this.roundedMinY, this.debug);
            FD.debugPrinter.print("roundedMax: " + this.roundedMaxY, this.debug);
            FD.debugPrinter.print("calculatedTickAmount: " + calculatedTickAmount, this.debug);
            FD.debugPrinter.print("tickAmount: " + this.yTickAmount, this.debug);
            FD.debugPrinter.print("---------------------------", this.debug);
        };

        LineChartVisualisation.prototype.niceNum = function (range, round) {
            var exponent;
            var fraction;
            var niceFraction;

            exponent = Math.floor(this.log10(range));
            fraction = range / Math.pow(10, exponent);

            if (round) {
                if (fraction < 1.5)
                    niceFraction = 1;
                else if (fraction < 3)
                    niceFraction = 2;
                else if (fraction < 7)
                    niceFraction = 5;
                else
                    niceFraction = 10;
            } else {
                if (fraction <= 1)
                    niceFraction = 1;
                else if (fraction <= 2)
                    niceFraction = 2;
                else if (fraction <= 5)
                    niceFraction = 5;
                else
                    niceFraction = 10;
            }
            return niceFraction * Math.pow(10, exponent);
        };

        LineChartVisualisation.prototype.log10 = function (val) {
            return Math.log(val) / Math.LN10;
        };

        LineChartVisualisation.prototype.getLines = function () {
            return this.lines;
        };

        LineChartVisualisation.prototype.setLineColor = function (line, color) {
            this.lines[line].setColor(color);
        };

        LineChartVisualisation.prototype.getLineIsSelected = function () {
            return this.lineIsSelected;
        };

        LineChartVisualisation.prototype.setLineIsSelected = function (sel) {
            this.lineIsSelected = sel;
        };

        LineChartVisualisation.prototype.setSelectedLineIDString = function (line) {
            this.selectedLineIDString = line;
        };

        LineChartVisualisation.prototype.getSelectedLineIDString = function () {
            return this.selectedLineIDString;
        };

        LineChartVisualisation.prototype.insertDelimetersDecimal = function (val) {
            val = val.replace(/[.]/g, this.floatSeperationMark);
            return val;
        };

        LineChartVisualisation.prototype.thousandSeparation = function (val) {
            return String(val).split("").reverse().join("").replace(/(\d{3}\B)/g, "$1" + this.separationMark).split("").reverse().join("");
        };

        LineChartVisualisation.prototype.insertDelemeters = function (val) {
            var integer = Math.floor(val);

            var decimal = val - integer;
            var intString = this.thousandSeparation(integer);

            if (decimal == 0) {
                if (this.floatSeperationMark != "")
                    return intString + this.floatSeperationMark + "0";
                else
                    return intString;
            }

            return intString + this.floatSeperationMark + decimal.toString().substring(2, 4);
        };
        return LineChartVisualisation;
    })(FD.FDVisualisation);
    FD.LineChartVisualisation = LineChartVisualisation;
})(FD || (FD = {}));
