(function(window){
    'use strict';

    /*global define, module, exports, require */
    var Graphnion = {};

    Graphnion.pie = function (selector, options) {
        return new GraphnionPie(selector, options);
    };


    /**
     * Pie graphs
     */

    function GraphnionPie(selector, options) {

        // Default settings
        var defaults = {
            type: 'consensus',
            size : 150,
            colors : {
                relays : "#111",
                others : "#666"
            }
        }
        // main element
        this.selector = selector;

        // option cache
        this.options = {};
        options = options || {};

        this.options.type = options.type || defaults.type;
        this.options.size = options.size || defaults.size;
        this.options.width = options.width || (this.options.size / 5); // Radius * 10%
        this.options.colors = options.colors || defaults.colors;
        this.options.onionoo = options.onionoo;


        // initialize some attributes
        this.init();
        this.callOnionoo();
    }

    Graphnion.version = "0.1";

    GraphnionPie.prototype = {
        constructor: GraphnionPie,

        init : function() {
            var self = this;

            this.radius = this.options.size / 2,
            this.formatPercent = d3.format(".2%");
            this.arc = d3.svg.arc()
                .outerRadius(this.radius)
                .innerRadius(this.radius - this.options.width);

            this.pie = d3.layout.pie()
                .sort(null)
                .value(function(d) { return d.frac; });

            switch (this.options.type) {
                case 'consensus':
                    this.field = "consensus_weight_fraction";
                    break;
                case 'guard':
                    this.field = "guard_probability";
                    break;
                case 'middle':
                    this.field = "middle_probability";
                    break;
                case 'exit':
                    this.field= "exit_probability";
                    break;
            }
        },

        draw : function(frac) {
            var self = this;

            var data = [
                {
                    frac: frac,
                    color: this.options.colors.relays
                },
                {
                    frac: (1 - frac),
                    color: this.options.colors.others
                }
            ];

            var svg = d3.select(this.selector).append("svg")
                .style("margin", "auto")
                .attr("width", this.options.size)
                .attr("height", this.options.size)
                .append("g")
                .attr("transform", "translate(" + this.options.size / 2 + "," + this.options.size / 2 + ")");


            var text = svg.append("text")
                .attr("text-anchor", "middle")
                .attr("dy", ".35em")
                .text(this.formatPercent(frac));

            var g = svg.selectAll(".arc")
                .data(this.pie(data))
                .enter()
                    .append("g")
                    .attr("class", "arc");

            g.append("path")
                .attr("d", this.arc)
                .style("fill", function(d) { return d.data.color; });

        },

        callOnionoo : function() {
            var self = this;

            // Create Onionoo url
            var url = "https://onionoo.torproject.org/details?type=relay&fields=fingerprint,nickname," + this.field;
            if (typeof this.options.onionoo.contact !== 'undefined') {
                url += "&contact=" + this.options.onionoo.contact;
            }
            else if (typeof this.options.onionoo.family !== 'undefined') {
                url += "&family=" + this.options.onionoo.family;
            }

            // Load data, and draw graph
            d3.json(url, function(error, data) {
                if (error) return console.warn(error);

                var frac = self.computeData(data);
                self.draw(frac);
            });
        },

        computeData : function(rawData) {
            var self = this;

            var frac = 0;
            rawData['relays'].forEach(function(d) {
                frac += d[self.field];
            });
            return frac;
        }

    }


    if (typeof define === 'function' && define.amd) {
        define("Graphnion", ["d3"], Graphnion);
    } else if ('undefined' !== typeof exports && 'undefined' !== typeof module) {
        module.exports = Graphnion;
    } else {
        window.Graphnion = Graphnion;
    }

})(window);