define(, function(Tools){

var _ = Tools._;
var Manager = Tools.Manager;

function Arc(parent, scales, df_id, _options){
    var options = {
        range: [0, 0],
        width: 0.5,
        color: ['rgb(166,206,227)', 'rgb(31,120,180)', 'rgb(178,223,138)', 'rgb(51,160,44)', 'rgb(251,154,153)', 'rgb(227,26,28)', 'rgb(253,191,111)', 'rgb(255,127,0)' ,'rgb(202,178,214)'],
        fill_by: null,
        x: null,
        y: null,
        layer: 1,
        axis: true
    };
    if(arguments.length>3)_.extend(options, _options);

    this.height_scale = (function(){
        var height = scales.getHeight(options.layer);
        return d3.scale.linear().domain(options.range).range([0, height]);
    })();

    this.inner_radius = scales.getRange(options.layer)[0];
    this.model = (function(){
        var center = scales.getCenter();
        return parent.append("g").attr('transform', 'translate(' + center.x + ',' + center.y + ')');
    })();
    this.scales = scales;
    this.df = Manager.getData(df_id);
    this.color_scale = d3.scale.ordinal().range(options.color);
    this.uuid = options.uuid;
    this.options = options;

    return this;
};

Arc.prototype.update = function(){
    var groups = this.scales.groups();
    var thisObj = this;

    if(this.options.axis){
        (function(){
            var values = thisObj.height_scale.ticks(5);
            values.reverse().pop();

            var group = thisObj.model
                .append("g")
                .selectAll("g")
                .data(values)
                .enter()
                .append("g");

            group.append("circle")
                .attr("fill", "none")
                .attr("stroke", "#000")
                .attr("r", function(d){return thisObj.inner_radius + thisObj.height_scale(d);});

            group.append("text")
                .attr("y", function(d){return -1*(thisObj.inner_radius + thisObj.height_scale(d) + 4);})
                .text(function(d){return d;});
        })();
    }

    _.each(groups, function(group, i){
        var x = thisObj.df.nested_column(i, thisObj.options.x);
        var y = thisObj.df.nested_column(i, thisObj.options.y);
        var fill_scale = (function(){
            var color = thisObj.options.color;
            if(thisObj.options.fill_by){
                var fill_by = thisObj.options.fill_by;
                var scale = thisObj.df.scale(fill_by, color);
                var pairs = _.zip.apply(null, _.map(thisObj.df.column(fill_by), function(val, i){
                    return [i, scale(val)];
                }));
                return d3.scale.ordinal().domain(pairs[0]).range(pairs[1]);
            }else{
                return d3.scale.ordinal().range(color);
            }
        })();
        var data = thisObj.processData(group, x, y, fill_scale);
        thisObj.updateModels(data);
    });
};

Arc.prototype.processData = function(group, x_arr, y_arr, fill_scale){
    var thisObj = this;
    return _.map(x_arr, function(x, i){
        var hash = thisObj.scales.get(thisObj.options.layer, group, x);
        hash['height'] = thisObj.height_scale(y_arr[i]);
        hash['fill'] = fill_scale(i);
        return hash;
    });
};

Arc.prototype.updateModels = function(data){
    var baseline = this.height_scale(0);
    var inner_radius = this.inner_radius;
    var width = this.scales.getWidth() * this.options.width;

    this.model.append("g")
        .selectAll("path")
        .data(data)
        .enter()
        .append("path")
        .attr("d", d3.svg.arc()
              .startAngle(function(d){return d.theta - width/2;})
              .endAngle(function(d){return d.theta + width/2;})
              .innerRadius(inner_radius + baseline)
              .outerRadius(function(d){return inner_radius + d.height;}))
        .attr("stroke", function(d){return d.fill;})
        .attr("fill", function(d){return d.fill;});
};

Arc.prototype.getLegend = function(){
};

Arc.prototype.checkSelectedData = function(ranges){
    return;
};

return Arc;

});