if (!AJS.FECRU) {
    AJS.FECRU = {};
}
AJS.FECRU.RAPHAELCHARTS = {};

(function () {

    var LINE_COLOURS_PIE = ["#478ec7","#769810","#d8561f","#d7e52e","#0c4383","#5fbe41","#f5832b","#edef00","#0c87c9","#ad2a15"];
    var LINE_COLOURS_XY = ["#d7561f","#478ec7","#769810","#dee439","#5fbe41","#0c4383","#f5832b","#edef00","#0c87c9","#ad2a15","#aebf47"];
    var REPOSITORY_COLOURS = ["#d7561f","#769810","#dee439","#5fbe41","#0c4383","#f5832b","#edef00","#0c87c9","#ad2a15","#aebf47"];

    var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];

    var getClr = function(i) {
        return LINE_COLOURS_XY[i % LINE_COLOURS_XY.length];
    };

    function getMinY(bars) {
        var minY = bars[0].y;
        for (var i = 1, ii = bars.length; i < ii; i++) {
            minY = Math.min(bars[i].y, minY);
        }
        return minY;
    }

    function getMaxY(bars) {
        var maxY = 0;
        for (var i = 0, ii = bars.length; i < ii; i++) {
            maxY = Math.max(bars[i].y + bars[i].h, maxY);
        }
        return maxY;
    }

    function toComp(num) {
        var prefix = ["",,, "K",,, "M",,, "G",,, "T",,, "P",,, "E",,, "Z",,, "Y"];
        for (var i = 0, ii = prefix.length; i < ii; i++) {
            if (typeof prefix[i] == "string") {
                if (num < Math.pow(10, i + 3)) {
                    return Math.round(num / Math.pow(10, i)) + prefix[i];
                }
            }
        }
        return Math.round(num / Math.pow(10, i - 1)) + prefix[prefix.length - 1];
    }

    function initDiv(divName) {
        AJS.$("body").append('<div id="' + divName + '-child" style="display:block;position:absolute; left:-4000px;">&nbsp;</div>');
        return divName + '-child';
    }

    function finaliseDiv(divName) {
        var div = AJS.$('#' + divName + '-child');
        div.removeAttr("style");

        //div.insertAfter(AJS.$('#' + divName));
        AJS.$('#' + divName).replaceWith(div);

    }

    function drawLocCharts(xValuesLoc, yValuesLoc, seriesLabelsShort, seriesLabelsLong, pageUrl) {

        var txt = {"text-anchor": "start", "font-size": 11, fill: "#666"};
        var popup;
        var dateText;

        var formattedDates = [];
        for (var i = 0, ii = xValuesLoc.length; i < ii; i++) {
            formattedDates[i] = formatDate(xValuesLoc[i]);
        }

        function hin2() {
            axisSet.hide();
            if (popup) {
                popup.remove();
                tooltipSet.hide();
                popup = null;
            }
            if (dateText) {
                dateText.remove();
                dateText = null;
            }
            for (var i = 0, ii = this.values.length; i < ii; i++) {
                tooltipSet[i].attr({text: seriesLabelsShort[i] + ": " + toComp(this.values[i])});
            }
            tooltipSet.show();
            if (this.line) {
                this.line.show();
            } else {
                this.line = rMain.set();
                this.line.push(rMain.path({opacity: .3}, "M" + [Math.round(this.x) + .5, 10, "l", 0, 130]).insertBefore(this));
                for (var j = 0, jj = this.values.length; j < jj; j++) {
                    this.line.push(rMain.circle(Math.round(this.x) + .5, this.y[j], 3).insertBefore(this).attr({fill: getClr(j), stroke: "#fff"}));
                }
            }
            popup = rMain.set();
            var maxy = Math.max.apply(0, this.y);
            var miny = Math.min.apply(0, this.y);
            popup.push(rMain.g.popupit(this.x, miny + (maxy - miny) / 2, tooltipSet, (this.x < 200) * 2 + 1).insertBefore(this).attr({fill: "#fff", stroke: "#666"}));
            tooltipSet.insertBefore(this);
            dateText = rMain.text(this.x, 150, (formattedDates[this.xIndex]));
        }

        function hout() {
            if (popup) {
                popup.remove();
                tooltipSet.hide();
                axisSet.show();
                popup = null;
                this.line.hide();
            }
            if (dateText) {
                dateText.remove();
                dateText = null;
            }
        }

        function fclick() {
            if (pageUrl) {
                var oldMaxDate = pageUrl.match(/maxDate=.*?(?=&|$)/);
                var newMaxDate = 'maxDate=' + xValuesLoc[this.xIndex];
                if (oldMaxDate) {
                    pageUrl = pageUrl.replace(oldMaxDate, newMaxDate);
                } else {
                    pageUrl += (pageUrl.indexOf("?") == -1) ? "?" : "&";
                    pageUrl += newMaxDate;
                }
                window.location = pageUrl;
            }
        }

        // draw sparkline

        var divSparkline = "locChartSparkline";
        var divSparklineChild = initDiv(divSparkline);

        var rSparkline = Raphael(divSparklineChild, 280, 37);
        rSparkline.g.linechart(0, 0, 280, 32, xValuesLoc, yValuesLoc, {colors: LINE_COLOURS_XY, width: 2});


        // draw main chart

        var divMain = "locChartMain";
        var divMainChild = initDiv(divMain);

        var bump = 20;
        var mainHeight = 150 + 10 + 20 * seriesLabelsLong.length;

        var rMain = Raphael(divMainChild, 280, mainHeight);

        // set up tooltip text
        var tooltipSet = rMain.set();
        for (var l = 0, ll = seriesLabelsLong.length; l < ll; l++) {
            tooltipSet.push(rMain.text(100, 30 + l * 15, "").attr({fill: getClr(l), "font-weight": 800}));
        }
        tooltipSet.hide();

        // draw legend
        for (var i = 0, ii = seriesLabelsLong.length; i < ii; i++) {
            rMain.g.disc(20, 150 + 20 * i + bump, 7).attr({stroke: "none", fill: getClr(i)});
            rMain.text(30, 150 + 20 * i + bump, seriesLabelsLong[i]).attr({"text-anchor": "start"});
        }

        rMain.path({opacity: .3}, "M" + [0, 130, "l", 276, 0]);

        // draw date axis
        var axisSet = rMain.set();

        var step = (276 - 9) / xValuesLoc.length;

        var dateWidth = 60;
        var lastX = - dateWidth / 2;

        for (var i = 0, ii = xValuesLoc.length; i < ii; i++) {

            var xVal = 12 + i * step;
            if (xVal - lastX > dateWidth) {
                lastX = xVal;
                //                axisSet.push(rMain.path({opacity: .3}, "M" + [xVal, 140, "l", 0, 5]));
                axisSet.push(rMain.text(xVal, 150, (formattedDates[i])));
            }
        }

        rMain.g.linechart(0, 10, 276, 130, xValuesLoc, yValuesLoc, {colors: LINE_COLOURS_XY, width: 2}).hoverColumn(hin2, hout).clickColumn(fclick);

        finaliseDiv(divSparkline);
        finaliseDiv(divMain);

    }

    function formatDate(ms) {

        var d = new Date(ms);

        var s = "";
        if (d.getDate() < 10) {
            s += '0';
        }
        s += (d.getDate()) + " ";

        s += months[d.getMonth()] + " ";

        var year = d.getYear() - 100;
        if (year < 10) {
            s += '0';
        }
        s += year;

        return s;
    }

    function drawCommitCharts(seriesLabels, sparklineLabels, sparklineData, commitsByDay, commitsByHour,
                              activityCalendarYears, activityCalendarData) {

        var dayLabels = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
        var hourLabels = ["00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23"];
        var monthLabels = ["J","F","M","A","M","J","J","A","S","O","N","D"];

        var divSparklineName = "sparklineSmall";
        var divSparklineChild = initDiv(divSparklineName);

        var rSmall = Raphael(divSparklineChild, 276, 32);
        rSmall.g.barchart(0, 0, 276, 32, sparklineData, false, {stacked: 1, vgutter: 0, colors: LINE_COLOURS_XY});
        rSmall.path({opacity: .3}, "M" + [0, 32, "l", 276, 0]);

        var divMainName = "mainCanvas";
        var divMainChild = initDiv(divMainName);
        var calendarHeight = 80 + 13 * activityCalendarYears.length;
        var mainHeight = 310 + calendarHeight;

        var r = Raphael(divMainChild, 300, mainHeight);

        // intialise tooltips
        var tooltipSet = r.set();
        for (var l = 0; l < seriesLabels.length; l++) {
            tooltipSet.push(r.text(100, 30 + l * 15, "").attr({fill: getClr(l), "font-weight": 800}));
        }
        tooltipSet.hide();

        var txt = {"text-anchor": "start", "font-size": 11, fill: "#666"};
        r.text(10, 10, "52 week commits volume").attr(txt);
        r.text(10, 110, "Commits by day").attr(txt);
        r.text(10, 200, "Commits by hour").attr(txt);
        r.text(10, 290, "Commit calendar").attr(txt);

        var hin = function() {
            for (var i = 0, ii = this.bars.length; i < ii; i++) {
                tooltipSet[i].attr({text: seriesLabels[i] + ": " + this.bars[i].value});
            }
            tooltipSet.show();
            this.popup = r.g.popupit(this.bars[0].x, getMinY(this.bars), tooltipSet, 2).insertBefore(this).attr({fill: "#fff", stroke: "#666"});
            tooltipSet.insertBefore(this);
        };

        var hin_below = function() {
            for (var i = 0, ii = this.bars.length; i < ii; i++) {
                tooltipSet[i].attr({text:  seriesLabels[i] + ": " + this.bars[i].value});
            }
            tooltipSet.show();
            this.popup = r.g.popupit(this.bars[0].x, getMaxY(this.bars), tooltipSet, 0).insertBefore(this).attr({fill: "#fff", stroke: "#666"});
            tooltipSet.insertBefore(this);
        };

        var hout = function() {
            if (this.popup) {
                this.popup.remove();
                tooltipSet.hide();
                delete this.popup;
            }
        };


        r.g.barchart(0, 20, 276, 70, sparklineData, false, {stacked: 1, vgutter: 0, colors: LINE_COLOURS_XY});
        r.path({opacity: .3}, "M" + [0, 90, "l", 276, 0]);

        r.g.barchart(20, 110, 235, 70, commitsByDay, false, {stacked: 1, vgutter: 15, colors: LINE_COLOURS_XY, "font-size": 11, fill: "#666"}).label(dayLabels).hoverColumn(hin, hout);

        r.g.barchart(25, 200, 230, 70, commitsByHour, false, {stacked: 1, vgutter: 15, colors: LINE_COLOURS_XY, "font-size": 11, fill: "#666"}).label(hourLabels).hoverColumn(hin, hout);


        var data = [],
                xs = [],
                ys = [];

        for (var i = 0, ii = activityCalendarData.length; i < ii; i++) {
            for (var j = 0, jj = activityCalendarData[j].length; j < jj; j++) {
                xs.push(j);
                ys.push(ii - i);
                data.push(activityCalendarData[i][j]);
            }
        }

        r.g.dotchart(0, 300, 270, calendarHeight, xs, ys, data, {symbol: "o", max: 6, heat: true, axis: "0 0 1 1", axisxstep: monthLabels.length - 1, axisystep: activityCalendarYears.length - 1, axisxlabels: monthLabels, axisxtype: " ", axisytype: " ", axisylabels: activityCalendarYears.reverse()}).hover(function () {
            this.tag = this.tag || r.g.tag(this.x, this.y, this.value, 0, this.r + 2).insertBefore(this);
            this.tag.show();
        }, function () {
            this.tag && this.tag.hide();
        }).axis.attr({"font-size": 10, fill: "#666"});

        finaliseDiv(divMainName);
        finaliseDiv(divSparklineName);
    }

    AJS.FECRU.RAPHAELCHARTS.commitSparkline = function(divName, width, height, queryParams, contextPath) {

        AJS.$.getJSON(contextPath + '/fe/commitSparkline.do', queryParams,
                function(_52) {
                    var r = Raphael(divName, width, height);

                    r.g.barchart(0, 10, width, height - 10, _52.data, false, {stacked: 1, vgutter: 0, colors: LINE_COLOURS_XY});
                });

    };

    AJS.FECRU.RAPHAELCHARTS.sidebarCharts = function(data, url) {
        drawLocCharts(data.locDataX, data.locDataY, data.seriesLabelsShort, data.seriesLabelsLong, url);
        drawCommitCharts(data.seriesLabelsShort, data.sparklineLabels, data.sparklineData, data.commitsByDay, data.commitsByHour, data.activityCalendarYears, data.activityCalendarData);
    };

    AJS.FECRU.RAPHAELCHARTS.sidebarChartsAjax = function(queryParams, contextPath, url) {

        AJS.$.getJSON(contextPath + '/fe/sidebarChartsJson.do', queryParams,
                function(data) {
                    AJS.FECRU.RAPHAELCHARTS.sidebarCharts(data, url);
                });
    };


})();

