/**

 * echarts地图一般投射算法

 * modify from GeoMap v0.5.3 https://github.com/x6doooo/GeoMap

 * 

 * @desc echarts基于Canvas，纯Javascript图表库，提供直观，生动，可交互，可个性化定制的数据统计图表。

 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)

 *

 */

define(function(require) {



    var PathShape = require('zrender/shape/Path');

    function toFloat(str) {

        return parseFloat(str || 0);

    }



    function getBbox(root) {

        var svgNode = root.firstChild;

        // Find the svg node

        while (!(svgNode.nodeName.toLowerCase() == 'svg' && svgNode.nodeType == 1)) {

            svgNode = svgNode.nextSibling;

        }



        var x = toFloat(svgNode.getAttribute('x'));

        var y = toFloat(svgNode.getAttribute('y'));

        var width = toFloat(svgNode.getAttribute('width'));

        var height = toFloat(svgNode.getAttribute('height'));

        return {

            left: x,

            top: y,

            width: width,

            height: height

        };

    }

    

    function geoJson2Path(root, transform) {

        var scale = [transform.scale.x, transform.scale.y];

        var elList = [];

        function _getShape(root) {

            var tagName = root.tagName;

            if (shapeBuilders[tagName]) {

                var obj = shapeBuilders[tagName](root, scale);



                if (obj) {

                    // Common attributes

                    obj.scale = scale;

                    obj.properties = {

                        name: root.getAttribute('name') || ''

                    };

                    obj.id = root.id;

                    extendCommonAttributes(obj, root);



                    elList.push(obj);

                }

            }

            var shapes = root.childNodes;

            for (var i = 0, len = shapes.length; i < len; i++) {

                _getShape(shapes[i]);

            }

        }

        _getShape(root);

        return elList;

    }



    /**

     * 平面坐标转经纬度

     * @param {Array} p

     */

    function pos2geo(obj, p) {

        var point = p instanceof Array ? [p[0] * 1, p[1] * 1] : [p.x * 1, p.y * 1];

        return [point[0] / obj.scale.x, point[1] / obj.scale.y];

    }

    

    /**

     * 经纬度转平面坐标

     * @param {Array | Object} p

     */

    function geo2pos(obj, p) {

        var point = p instanceof Array ? [p[0] * 1, p[1] * 1] : [p.x * 1, p.y * 1];

        return [point[0] * obj.scale.x, point[1] * obj.scale.y];

    }



    function trim(str) {

        return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');

    }



    function extendCommonAttributes(obj, xmlNode) {



        var color = xmlNode.getAttribute('fill');

        var strokeColor = xmlNode.getAttribute('stroke');

        var lineWidth = xmlNode.getAttribute('stroke-width');

        var opacity = xmlNode.getAttribute('opacity');



        if (color && color != 'none') {

            obj.color = color;

            if (strokeColor) {

                obj.brushType = 'both';

                obj.strokeColor = strokeColor;

            } else {

                obj.brushType = 'fill';

            }

        } else if (strokeColor && strokeColor != 'none') {

            obj.strokeColor = strokeColor;

            obj.brushType = 'stroke';

        }

        if (lineWidth && lineWidth != 'none') {

            obj.lineWidth = parseFloat(lineWidth);

        }

        if (opacity && opacity != 'none') {

            obj.opacity = parseFloat(opacity);

        }

    }



    function parsePoints(str) {

        var list = trim(str).replace(/,/g, ' ').split(/\s+/);

        var points = [];



        for (var i = 0; i < list.length;) {

            var x = parseFloat(list[i++]);

            var y = parseFloat(list[i++]);

            points.push([x, y]);

        }

        return points;

    }



    // Regular svg shapes

    var shapeBuilders = {

        path: function(xmlNode, scale) {

            var path = xmlNode.getAttribute('d');

            var rect = PathShape.prototype.getRect({ path : path });

            return {

                shapeType: 'path',

                path: path,

                cp: [

                    (rect.x + rect.width / 2) * scale[0], 

                    (rect.y + rect.height / 2) * scale[1]

                ]

            };

        },



        rect: function(xmlNode, scale) {

            var x = toFloat(xmlNode.getAttribute('x'));

            var y = toFloat(xmlNode.getAttribute('y'));

            var width = toFloat(xmlNode.getAttribute('width'));

            var height = toFloat(xmlNode.getAttribute('height'));



            return {

                shapeType: 'rectangle',

                x: x,

                y: y,

                width: width,

                height: height,

                cp: [

                    (x + width / 2) * scale[0], 

                    (y + height / 2) * scale[1]

                ]

            };

        },



        line: function(xmlNode, scale) {

            var x1 = toFloat(xmlNode.getAttribute('x1'));

            var y1 = toFloat(xmlNode.getAttribute('y1'));

            var x2 = toFloat(xmlNode.getAttribute('x2'));

            var y2 = toFloat(xmlNode.getAttribute('y2'));



            return {

                shapeType: 'line',

                xStart: x1,

                yStart: y1,

                xEnd: x2,

                yEnd: y2,

                cp: [

                    (x1 + x2) * 0.5 * scale[0], 

                    (y1 + y2) * 0.5 * scale[1]

                ]

            };

        },



        circle: function(xmlNode, scale) {

            var cx = toFloat(xmlNode.getAttribute('cx'));

            var cy = toFloat(xmlNode.getAttribute('cy'));

            var r = toFloat(xmlNode.getAttribute('r'));



            return {

                shapeType: 'circle',

                x: cx,

                y: cy,

                r: r,

                cp: [

                    cx * scale[0],

                    cy * scale[1]

                ]

            };

        },



        ellipse: function(xmlNode, scale) {

            var cx = parseFloat(xmlNode.getAttribute('cx') || 0);

            var cy = parseFloat(xmlNode.getAttribute('cy') || 0);

            var rx = parseFloat(xmlNode.getAttribute('rx') || 0);

            var ry = parseFloat(xmlNode.getAttribute('ry') || 0);



            return {

                shapeType: 'ellipse',

                x: cx,

                y: cy,

                a: rx,

                b: ry,

                cp: [

                    cx * scale[0],

                    cy * scale[1]

                ]

            };

        },



        polygon: function(xmlNode, scale) {

            var points = xmlNode.getAttribute('points');

            var min = [Infinity, Infinity];

            var max = [-Infinity, -Infinity];

            if (points) {

                points = parsePoints(points);



                for (var i = 0; i < points.length; i++) {

                    var p = points[i];

                    

                    min[0] = Math.min(p[0], min[0]);

                    min[1] = Math.min(p[1], min[1]);



                    max[0] = Math.max(p[0], max[0]);

                    max[1] = Math.max(p[1], max[1]);



                }

                return {

                    shapeType: 'polygon',

                    pointList: points,

                    cp: [

                        (min[0] + max[0]) / 2 * scale[0],

                        (min[1] + max[1]) / 2 * scale[0]

                    ]

                };

            }

        },



        polyline: function(xmlNode, scale) {

            var obj = shapeBuilders.polygon(xmlNode, scale);

            return obj;

        }

    };

    

    return {

        getBbox: getBbox,

        geoJson2Path: geoJson2Path,

        pos2geo: pos2geo,

        geo2pos: geo2pos

    };

}); 