/**
 * @private
 */
Ext.define('Ext.sparkline.VmlCanvas', {
    extend: 'Ext.sparkline.CanvasBase',
 
    setWidth: function(width) {
        var me = this;
 
        me.callParent(arguments);
        me.owner.groupEl.dom.coordsize = me.width + ' ' + (me.height || 0);
        me.owner.groupEl.dom.style.width = width + 'px';
    },
 
    setHeight: function(height) {
        var me = this;
 
        me.callParent(arguments);
        me.owner.groupEl.dom.coordsize = (me.width || 0) + ' ' + me.height;
        me.owner.groupEl.dom.style.height = height + 'px';
    },
 
    onOwnerUpdate: function() {
        var me = this;
 
        me.group = me.owner.groupEl;
        me.el = me.owner.element;
        me.prerender = [];
    },
 
    _drawShape: function(shapeid, path, lineColor, fillColor, lineWidth) {
        var vpath = [],
            initial, stroke, fill, closed, plen, i;
 
        for (= 0, plen = path.length; i < plen; i++) {
            vpath[i] = (path[i][0]) + ',' + (path[i][1]);
        }
 
        initial = vpath.splice(0, 1);
        lineWidth = lineWidth == null ? 1 : lineWidth;
 
        stroke = lineColor == null
            ? ' stroked="false" '
            : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '';
 
        fill = fillColor == null
            ? ' filled="false"'
            : ' fillColor="' + fillColor + '" filled="true" ';
 
        closed = vpath[0] === vpath[vpath.length - 1] ? '' : '';
 
        return [
            '<svml:shape coordorigin="0 0" coordsize="', this.pixelWidth, ' ', this.pixelHeight,
            '" id="jqsshape', shapeid, '', stroke, fill,
            ' style="position:absolute;height:', this.pixelHeight,
            'px;width:', this.pixelWidth, 'px" ',
            ' path="m ', initial, ' l ', vpath.join(''), ' ', closed,
            'e"></svml:shape>'
        ].join('');
    },
 
    _drawCircle: function(shapeid, x, y, radius, lineColor, fillColor, lineWidth) {
        var circumference = radius * 2,
            stroke, fill;
 
        x -= radius;
        y -= radius;
 
        stroke = lineColor == null
            ? ' stroked="false" '
            : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '';
 
        fill = fillColor == null
            ? ' filled="false"'
            : ' fillColor="' + fillColor + '" filled="true" ';
 
        return [
            '<svml:oval id="jqsshape', shapeid, '',
            stroke,
            fill,
            ' style="position:absolute;top:', y, 'px; left:', x, 'px;width:',
            circumference, 'px;height:', circumference, 'px"></svml:oval>'
        ].join('');
    },
 
    _drawPieSlice: function(shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {
        var vpath,
            width = this.pixelWidth,
            height = this.pixelHeight,
            startx, starty, endx, endy, stroke, fill;
 
        stroke = lineColor == null
            ? ' stroked="false" '
            : ' strokeWeight="1px" strokeColor="' + lineColor + '';
 
        fill = fillColor == null
            ? ' filled="false"'
            : ' fillColor="' + fillColor + '" filled="true" ';
 
        // VML cannot handle start & end angle the same.
        if (startAngle === endAngle) {
            return '';
        }
 
        if ((endAngle - startAngle) === (2 * Math.PI)) {
            // VML seems to have a problem when drawing a full circle that doesn't start 0
            startAngle = 0.0;
            endAngle = (2 * Math.PI);
        }
 
        startx = x + Math.round(Math.cos(startAngle) * radius);
        starty = y + Math.round(Math.sin(startAngle) * radius);
        endx = x + Math.round(Math.cos(endAngle) * radius);
        endy = y + Math.round(Math.sin(endAngle) * radius);
 
        if (startx === endx && starty === endy) {
            if ((endAngle - startAngle) < Math.PI) {
                // Prevent very small slices from being mistaken as a whole pie
                return '';
            }
 
            // essentially going to be the entire circle, so ignore startAngle
            startx = endx = x + radius;
            starty = endy = y;
        }
 
        if (startx === endx && starty === endy && (endAngle - startAngle) < Math.PI) {
            return '';
        }
 
        vpath = [- radius, y - radius, x + radius, y + radius, startx, starty, endx, endy];
 
        return [
            '<svml:shape coordorigin="0 0" coordsize="', width, ' ', height,
            '" id="jqsshape', shapeid, '',
            stroke,
            fill,
            ' style="position:absolute;height:', height, 'px;width:', width,
            'px" path="m ', x, ',', y, ' wa ', vpath.join(''), ' x e"></svml:shape>'
        ].join('');
    },
 
    _drawRect: function(shapeid, x, y, width, height, lineColor, fillColor) {
        return this._drawShape(shapeid, [[x, y], [x, y + height], [+ width, y + height],
                                         [+ width, y], [x, y]], lineColor, fillColor);
    },
 
    reset: function() {
        Ext.fly(this.group).empty();
    },
 
    appendShape: function(shape) {
        this.prerender.push(this['_draw' + shape.type].apply(this, shape.args));
        this.lastShapeId = shape.id;
 
        return shape.id;
    },
 
    replaceWithShape: function(shapeid, shape) {
        var existing = this.el.getById('jqsshape' + shapeid, true),
            vel = this['_draw' + shape.type].apply(this, shape.args);
 
        existing.outerHTML = vel;
    },
 
    replaceWithShapes: function(shapeids, shapes) {
        // replace the first shapeid with all the new shapes then toast the remaining old shapes
        var existing = this.el.getById('jqsshape' + shapeids[0], true),
            replace = '',
            slen = shapes.length,
            i;
 
        for (= 0; i < slen; i++) {
            replace += this['_draw' + shapes[i].type].apply(this, shapes[i].args);
        }
 
        existing.outerHTML = replace;
 
        for (= 1; i < shapeids.length; i++) {
            this.el.getById('jqsshape' + shapeids[i]).destroy();
        }
    },
 
    insertAfterShape: function(shapeid, shape) {
        var existing = this.el.getById('jqsshape' + shapeid, true),
            vel = this['_draw' + shape.type].apply(this, shape.args);
 
        existing.insertAdjacentHTML('afterEnd', vel);
    },
 
    removeShapeId: function(shapeid) {
        var existing = this.el.getById('jqsshape' + shapeid, true);
 
        this.group.removeChild(existing);
    },
 
    getShapeAt: function(x, y) {
        var shapeid = this.el.id.substr(8);
 
        return shapeid;
    },
 
    render: function() {
        this.group.dom.innerHTML = this.prerender.join('');
    }
}, function() {
    Ext.onInternalReady(function() {
        var doc = document;
 
        if (doc.namespaces && !doc.namespaces.svml) {
            doc.namespaces.add("svml", "urn:schemas-microsoft-com:vml", '#default#VML');
        }
    });
});