/**
 * @class Ext.sparkline.Pie
 *
 * Plots a pie chart based upon the input {#values} array.
 *
 * See {@link Ext.sparkline.Base the base class} for a simple example.
 */
Ext.define('Ext.sparkline.Pie', {
    extend: 'Ext.sparkline.Base',
 
    alias: 'widget.sparklinepie',
 
    config: {
 
        /**
         * @cfg {Number} [offset] Angle in degrees to offset the first slice.
         */
        offset: 0,
 
        /**
         * @cfg {String[]} [sliceColors] An array of CSS colro values to apply to the chart slices.
         */
        sliceColors: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00', '#dd4477', '#0099c6',
                      '#990099'],
 
        /**
         * @cfg {Number} [borderWidth=0] Border width in pixels of line round slices.
         */
        borderWidth: 0,
 
        /**
         * @cfg {String} [borderColor=#000] Border color of line round slices.
         */
        borderColor: '#000'
    },
 
    tipTpl: '● {value} ({percent:number("0.0")}%)',
 
    // Ensure values is an array of numbers
    applyValues: function(newValues) {
        newValues = Ext.Array.map(Ext.Array.from(newValues), Number);
        this.disabled = !(newValues && newValues.length);
        this.updateConfigChange();
 
        return newValues;
    },
 
    onUpdate: function() {
        var me = this,
            values = me.values,
            total = 0,
            i;
 
        me.callParent(arguments);
 
        me.shapes = {}; // map shape ids to value offsets
        me.valueShapes = {}; // maps value offsets to shape ids
 
        if (values.length > 0) {
            for (= values.length; i--;) {
                total += values[i];
            }
        }
 
        me.total = total;
        me.radius = Math.floor(Math.min(me.getWidth(), me.getHeight()) / 2);
    },
 
    getRegion: function(x, y) {
        var ratio = window.devicePixelRatio || 1,
            shapeid = this.canvas.getShapeAt(* ratio, y * ratio);
 
        return (shapeid != null && this.shapes[shapeid] != null) ? this.shapes[shapeid] : null;
    },
 
    getRegionFields: function(region) {
        var sliceColors = this.getSliceColors();
 
        return {
            isNull: this.values[region] == null,
            value: this.values[region],
            percent: this.values[region] / this.total * 100,
            color: sliceColors[region % sliceColors.length],
            offset: region
        };
    },
 
    renderHighlight: function(region) {
        this.renderSlice(region, true).append();
    },
 
    renderSlice: function(valuenum, highlight) {
        var me = this,
            canvas = me.canvas,
            radius = me.radius,
            borderWidth = me.getBorderWidth(),
            offset = me.getOffset(),
            circle = 2 * Math.PI,
            values = me.values,
            total = me.total,
            next = offset ? (2 * Math.PI) * (offset / 360) : 0,
            start, end, i, vlen, color,
            sliceColors = this.getSliceColors();
 
        vlen = values.length;
 
        for (= 0; i < vlen; i++) {
            start = next;
            end = next;
 
            if (total > 0) {  // avoid divide by zero
                end = next + (circle * (values[i] / total));
            }
 
            if (valuenum === i) {
                color = sliceColors[% sliceColors.length];
 
                if (highlight) {
                    color = me.calcHighlightColor(color);
                }
 
                return canvas.drawPieSlice(radius, radius, radius - borderWidth, start, end,
                                           null, color);
            }
 
            next = end;
        }
    },
 
    renderGraph: function() {
        var me = this,
            canvas = me.canvas,
            values = me.values,
            radius = me.radius,
            borderWidth = me.getBorderWidth(),
            shape, i,
            shapes = me.shapes || (me.shapes = {}),
            valueShapes = me.valueShapes || (me.valueShapes = {});
 
        if (!me.callParent()) {
            return;
        }
 
        if (borderWidth) {
            canvas.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)),
                              me.getBorderColor(), null, borderWidth).append();
        }
 
        for (= values.length; i--;) {
            if (values[i]) { // don't render zero values
                shape = me.renderSlice(i).append();
                valueShapes[i] = shape.id; // store just the shapeid
                shapes[shape.id] = i;
            }
        }
 
        // If mouse is over, re-apply the highlight
        if (me.currentPageXY && me.canvasRegion.contains(me.currentPageXY)) {
            me.currentRegion = null;
            me.updateDisplay();
        }
 
        canvas.render();
    }
});