define(['tools'], function(Tools){
    function Axis(parent, scales, _options){
        var _ = Tools._;
        var Manager = Tools.Manager;

        var options = {
            width:0,
            height:0,
            margin: {top:0,bottom:0,left:0,right:0},
            x_label:'X',
            y_label:'Y',
            zoom:true,
            zoom_range:[0, 500],
            rotate_x_label:0,
            rotate_y_label:0,
            pane_uuid: null,
            z_index:0,
            extra: {}
        };

        var options_extra = {
            df_id: null,
            map_data: null,
            cca3: null,
            fill_by: null,
            color: ["none"],
            text_color: '#fff',
            text_size: '1em',
            stroke_color: '#000',
            no_data_color: 'none',
            center: [13, 35],
            scale: 1000
        };

        if(arguments.length>2){
            _.extend(options, _options);
            _.extend(options_extra, _options.extra);
            options.extra = options_extra;
        }

        var fill_scale = (function(){
            var country_id = _.map(options.extra.map_data.features, function(d){return d.id;});

            if(_.every(country_id, function(id){return typeof id == "undefined";})){
                return d3.scale.ordinal().range(options.extra.color);
            }

            if(options.extra.fill_by != null){
                var df = Manager.getData(options.extra.df_id);
                var scale = df.scale(options.extra.fill_by, options.extra.color);
                var fill_by_column = df.column(options.extra.fill_by);
                var id_column = df.column(options.extra.cca3);
                return d3.scale.ordinal()
                    .domain(country_id)
                    .range(_.map(country_id, function(id, i){
                        var pos = id_column.indexOf(id);
                        if(pos != -1)return scale(fill_by_column[pos]);
                        else return options.extra.no_data_color;
                    }));
            }else{
                return d3.scale.ordinal()
                    .domain(country_id)
                    .range(options.extra.color);
            }
        })();

        var model = parent.append("g");
        var clip_id = "clip" + options.pane_uuid;

        model.append("clipPath")
            .attr("id", clip_id)
            .append("rect")
            .attr({
                "x": 0,
                "y": 0,
                "width": options.width,
                "height": options.height
            });

        model
            .attr("clip-path", "url(#" + clip_id + ")")
            .append("g").attr("class", "map")
            .style("z-index", options.z_index);

        var projection = d3.geo.mercator()
                .center(options.extra.center)
                .scale(options.extra.scale);

        scales.init(projection);

        var path = d3.geo.path().projection(projection);

        var graticule = d3.geo.graticule();
        model.select(".map").append("path")
            .datum(graticule)
            .attr({
                "d": path,
                "stroke": "#fff",
                "stroke-width":2
            });

        var map = model.select(".map").selectAll("path")
                .data(options.extra.map_data.features)
                .enter()
                .append('path')
                .attr("d", path)
                .attr("stroke", options.extra.stroke_color)
                .attr("fill", function(d){
                    if(typeof d.id == "undefined")return options.extra.no_data_color;
                    else return fill_scale(d.id);
                });

       if(options.zoom){
           parent.call(
               d3.behavior.zoom()
                   .scaleExtent(options.zoom_range)
                   .on("zoom", function(){
                       var translate = d3.event.translate;
                       var scale = d3.event.scale;
                       scales.setTranslate(translate[0], translate[1]);
                       scales.setScale(scale);
                       parent.select(".context_child").attr('transform', 'translate(' + translate + ') scale(' + scale + ')');
                       model.select(".map").attr('transform', 'translate(' + translate + ') scale(' + scale + ')');
                   })
           );
       }
    }
    return Axis;
});