(function ($) {
    var _plugin = 'goldChart';

    $.fn[_plugin] = function (options) {
        var opts = $.extend(true, {}, $.fn[_plugin].defaults, options);

        return this.each(function () {
            var $this = $(this);
            var o = $.meta ? $.extend(true, {}, opts, $this.data()) : opts;

            if (o.url) {
                $.get(o.url, function (xml) {
                    _render($this, xml, o);
                });
            }
            else if (o.xml) {
                _render($this, o.xml, o);
            }
        });
    };

    $.fn[_plugin].defaults =
	{
	    url: '',
	    xml: '',
	    onPostRender: function () { },
	    onMaCalculation: function (ma, xml) {
	        var interval = parseInt(xml.find('interval').text());

	        var interval = interval / 1000 / 60 / 60 / 24; // number of days

	        var num = ma / interval;

	        var hasCats = xml.find('start').length ? false : true;

	        var maValues = [];
	        var value = 0;
	        var count = 0;
	        var ser = xml.find('series:first value');

	        if (ser.length > num) {
	            var i = 0;
	            for (i = 0; i < ser.length - 1; i++) {
	                value += parseFloat(ser.eq(i).text());

	                if (maValues.length == 0 && !hasCats) {
	                    maValues.push(null);
	                }

	                if (i >= num) {
	                    // remove the extra value
	                    value -= parseFloat(ser.eq(i - num).text());
	                    maValues.push(value / num);
	                }
	                else {
	                    maValues.push(null);
	                }

	            }

	        }



	        //	        xml.find('series:first value').each(function () {
	        //	            count++;
	        //	            value += parseFloat($(this).text());

	        //	            // set the first value
	        //	            if (maValues.length == 0 && !hasCats) {
	        //	                maValues.push(value);
	        //	            }

	        //	            if (count == num) {
	        //	                value = value / count;

	        //	                if (hasCats) {
	        //	                    for (var i = 0; i < num; i++) {
	        //	                        maValues.push(value);
	        //	                    }
	        //	                }
	        //	                else {
	        //	                    maValues.push(value);
	        //	                }

	        //	                value = 0;
	        //	                count = 0;
	        //	            }

	        //	        });

	        /*
	        var last = value / count;
	        if (!isNaN(last))
	        {
	        maValues.push(last);
	        }
	        */

	        return maValues;
	    },
	    settings:
		{
		    chart:
			{
			//margin: [50, 50, 100, 70]

},
		    credits: { enabled: false },
		    title:
			{
			    text: '',
			    y: 15
			},
		    xAxis:
			{
			    type: 'datetime',
			    title: { text: null },
			    labels: { align: 'right' }
			},
		    yAxis:
			{
			    title: { text: '' },
			    min: 0.6,
			    endOnTick: false,
			    startOnTick: false,
			    showFirstLabel: true,
			    labels: {
			        formatter: function () {
			            return parseInt(this.value);
			        }
			    }

			},
		    tooltip:
			{
			    //enabled: false
			    formatter: function () {
			        return this.series.name + ' ' + Math.round(this.y * 100) / 100;
			    }
			},
		    legend:
			{
			    enabled: false
			},
		    plotOptions:
			{
			    line:
				{
				    marker:
					{
					    enabled: false,
					    states: { hover: { enabled: false} }
					},
				    states: { hover: { enabled: true, lineWidth: 3} }
				}
			},
		    series: []
		}
	};

    // takes the xml data and renders the charts
    var _render = function (container, xml, options) {

        try {


            $xml = $(xml);

            // add class to container
            container.addClass('chart');

            // add the buttons container
            var buttons = '<ul class="chart-buttons"></ul>';
            container.append(buttons);
            buttons = container.find('ul.chart-buttons');
            buttons.click(function (event) {
                var li = $(event.target).closest('li');
                if (!li.length) { return false; }

                var id = li.find('a').attr('href').split('#')[1] || '';
                _showChart(container, id);

                return false;
            });

            // add the ma container
            var maButtons = '<ul class="chart-ma"></ul>';
            container.append(maButtons);
            maButtons = container.find('ul.chart-ma');
            maButtons.click(function (event) {
                var a = $(event.target).closest('a');
                if (!a.length) { return false; }

                var add = a.attr('href').split('#')[1] || 0;
                if (!add) { return false; }
                add = parseInt(add);

                var input = a.siblings('input');
                var value = parseInt(input.attr('value'));
                input.attr('value', value + add).change();

                return false;
            });

            // the default chart id
            var defaultId = '';

            // do a seperate one for each chart
            var index = 1;
            $xml.find('chart').each(function () {
                var chart = $(this);

                // get an id
                var id = 'chart-' + index;
                while ($('#' + id).length) {
                    index++;
                    id = 'chart-' + index;
                }

                // is this the default?
                if (!defaultId) { defaultId = id; }
                if (chart.attr('default')) { defaultId = id; }

                // add container
                container.append('<div id="' + id + '" class="chart-area"></div>');

                // add a button
                chart.find('button').each(function () {
                    var button = $(this);
                    var label = button.text();

                    buttons.append('<li><a href="#' + id + '">' + label + '</a></li>');
                });

                // add the MA selector
                var ma = 0;
                var maButton;
                chart.find('ma').each(function () {

                    $ma = $(this);
                    ma = $ma.text();
                    var interval = $ma.attr('interval') || 5;
                    interval = parseInt(interval);

                    var lower = $ma.attr('lower') || 10;
                    lower = parseInt(lower);

                    var upper = $ma.attr('upper') || 300;
                    upper = parseInt(upper);

                    maButtons.append('<li><span>MA</span><input type="text" name="' + id + '-ma" value="' + ma + '"/><a href="#' + (-interval) + '">Dn</a><a href="#' + interval + '">Up</a></li>');

                    maButton = maButtons.find('input[name=' + id + '-ma]');
                    maButton.change(function (event) {
                        var v = parseInt(this.value);
                        v = isNaN(v) ? lower : v;
                        if (v < lower) { v = lower; }
                        else if (v > upper) { v = upper; }
                        this.value = v;

                        _calculateMA(v, id, chart, options);
                    });

                    maButtons.find('li:last').hide();
                });

                if (maButton) {
                    options.settings.legend.enabled = false;
                }

                // draw the chart
                var settings = $.extend(true, {}, options.settings);
                settings.chart.renderTo = id;



                var interval = parseInt(chart.find('interval').text());

                settings.series = [];
                var min = 0;
                chart.find('series').each(function () {
                    var series = $(this);
                    var name = series.find('name').text();

                    var data = [];
                    var categories = [];
                    series.find('value').each(function () {
                        var v = $(this);
                        var value = parseFloat(v.text());
                        data.push(value);

                        if (min == 0 || value < min) {
                            min = value;
                        }

                        var label = v.attr('label');
                        if (!label) {
                            label = ' ';
                            settings.xAxis.tickWidth = 0;
                        }
                        categories.push(label);
                    });

                    var seriesSettings =
				{
				    type: 'line',
				    name: name,
				    data: data
				};

                    var start = chart.find('start');
                    if (start.length) {
                        seriesSettings.pointInterval = interval;
                        seriesSettings.pointStart = _parseDate(chart.find('start'));
                    }
                    else {
                        settings.xAxis.type = 'linear';
                        settings.xAxis.categories = categories;
                        settings.xAxis.labels.rotation = 270;
                    }

                    var color = series.find('color').text();
                    if (color) { seriesSettings.color = color; }

                    var type = series.find('type').text();
                    if (type) { seriesSettings.type = type; }

                    settings.series.push(seriesSettings);
                });

                settings.yAxis.min = min;

                // set the title?
                var text = chart.find('title:first').text();
                settings.title.text = (text) ? text : settings.title.text;

                //console.log(settings);

                // render the chart
                var hc = new Highcharts.Chart(settings, function () {



                });

                var thisChart = $('#' + id);
                thisChart.data('chart', hc);
                thisChart.hide();

                if (maButton) {
                    setTimeout(function () {
                        maButton.change();
                    }, 100);
                }

            });

            // show the default one
            _showChart(container, defaultId);

            // post render hook
            if (options.onPostRender) {
                options.onPostRender(container);

            }

        }
        catch (err)
    { }

    };

    // returns the extracted date
    var _parseDate = function (xml) {
        var year = parseInt(xml.find('year').text());
        var month = parseInt(xml.find('month').text());
        var day = parseInt(xml.find('day').text());

        return Date.UTC(year, month - 1, day);
    }

    // shows the selected chart
    var _showChart = function (container, id) {
        if (!id) { return; }

        container.find('div.chart-area').hide();
        container.find('ul.chart-ma li').hide();
        container.find('ul.chart-buttons a').removeClass('chart-selected');

        var chart = $('#' + id);
        chart.show();

        container.find('ul.chart-buttons a[href=#' + id + ']').addClass('chart-selected');
        container.find('ul.chart-ma li:has(input[name=' + id + '-ma])').show();
    };

    // calculate the MA on the chart
    var _calculateMA = function (ma, id, xml, options) {
        var chart = $('#' + id);
        if (!chart.length || !ma) { return; }

        var maValues = options.onMaCalculation(ma, xml);

        var hc = chart.data('chart');
        var maId = id + '-ma';

        var series = hc.get(maId);
        if (series) {
            series.remove(false);
        }

        var maSettings =
		{
		    type: 'line',
		    marker: { enabled: false },
		    id: maId,
		    name: 'MA',
		    data: maValues
		};

        var start = xml.find('start');
        if (start.length) {
            maSettings.pointStart = _parseDate(xml.find('start'));
            maSettings.pointInterval = ma * 24 * 60 * 60 * 1000;
        }

        var color = xml.find('ma').attr('color');
        if (color) { maSettings.color = color; }

        hc.addSeries(maSettings);
    };

})(jQuery);
