// Dependencies
var Ul = require("ul")
  , FlatColors = require("flatcolors")
  , CliCircle = require("cli-circle")
  , Couleurs = require("couleurs")()
  ;

function CliPie(r, data, options) {
    this.data = [];
    this.radius = r;
    this.total = 0;
    this.colors = {};
    if (Array.isArray(data)) {
        data.forEach(this.add.bind(this));
    } else if (data && data.constructor === Object) {
        options = data;
    }
    this.options = Ul.merge(options, {
        flat: true
      , chr: " "
      , circle_opts: {
            aRatio: 1
        }
    });
}

CliPie.Item = function (obj) {
    this.value = obj.value;
    this.name = obj.name;
    this.color = obj.color;
    this.percent = null;
    this.angle = null;
};

CliPie.prototype.add = function (item) {
    var nItem = new CliPie.Item(item);
    this.total += nItem.value;
    this.data.push(nItem);
};

CliPie.prototype.uniqueColor = function (cColor) {
    var color = null
      , clrStr = null
      ;

    if (cColor === undefined) {
        color = FlatColors();
    } else if (this.options.flat && FlatColors.colors.indexOf(cColor) === -1) {
        color = FlatColors(cColor);
    } else {
        color = toRgb(cColor);
    }

    clrStr = color.join(",");
    if (this.colors[clrStr]) debugger
    if (this.colors[clrStr] && Object.keys(this.colors).length !== FlatColors.colors.length) {
        return this.uniqueColor();
    }

    this.colors[clrStr] = color;
    return color;
};

CliPie.prototype.toString = function () {
    var self = this
      , circle = new CliCircle(self.radius, self.options.chr, self.options.circle_opts)
      ;

    function line(x1, y1, x2, y2, chr) {
        circle.graph.setFunctionX(function (x) {
            var y = (x - x1) * (y2 - y1) / (x2 - x1) + y1;
            return y;
        }, x1, x2, chr).setFunctionY(function (y) {
            var x = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
            return x;
        }, y1, y2, chr);
    }

    function toRad(a) {
        return a * (Math.PI / 180);
    }

    var cAngle = 1;
    function next(delta) {
        cAngle -= delta;
        return {
            x: self.radius * Math.cos(toRad(cAngle))
          , y: self.radius * Math.sin(toRad(cAngle))
        };
    }

    var cLetterCode = 96
      , cLetter = ""
      , letters = {}
      , i = 0
      , cPoint = null
      , str = ""
      ;

    self.data.forEach(function (cItem) {
        cItem.percent = (100 * cItem.value) / self.total;
        cItem.angle = cItem.percent * 3.6;
        ++cLetterCode;
        letters[cLetter = String.fromCharCode(cLetterCode)] = self.uniqueColor(cItem.color);
        for (i = 0; i <= cItem.angle; ++i) {
            cPoint = next(1);
            line(0, 0, cPoint.x, cPoint.y, cLetter);
        }
    });

    str = circle.toString().split("\n").map(function (c) {
        return c.split("").map(function (ch) {
            return new Array(self.options.circle_opts.aRatio + 2).join(ch);
        }).join("");
    }).join("\n");

    Object.keys(letters).forEach(function (c) {
        str = str.replace(new RegExp(c, "g"), Couleurs.bg(Couleurs.fg(c, letters[c]), letters[c]));
    });

    return str;
};

module.exports = CliPie;

@@ -146,16 +146,49 @@
 urs%22)()%0A
+  , Overlap = require(%22overlap%22)%0A
   ;%0A%0Afun
@@ -1219,16 +1219,27 @@
 color = 
+FlatColors.
 toRgb(cC
@@ -1286,46 +1286,8 @@
 %22);%0A
-    if (this.colors%5BclrStr%5D) debugger%0A
     
@@ -2053,17 +2053,18 @@
 Angle = 
-1
+90
 ;%0A    fu
@@ -2279,29 +2279,8 @@
  96%0A
-      , cLetter = %22%22%0A
     
@@ -2349,16 +2349,61 @@
 tr = %22%22%0A
+      , legend = null%0A      , cLegend = null%0A
       ;%0A
@@ -2580,18 +2580,15 @@
     
-letters%5BcL
+cItem.l
 ette
@@ -2623,16 +2623,60 @@
 terCode)
+;%0A        cItem.color = letters%5BcItem.letter
 %5D = self
@@ -2821,17 +2821,22 @@
 int.y, c
-L
+Item.l
 etter);%0A
@@ -3230,24 +3230,464 @@
 );%0A    %7D);%0A%0A
+    if (self.options.legend) %7B%0A        legend = self.data.map(function (c) %7B%0A            return Couleurs.fg(%22%E2%AC%9B%22, c.color) + %22 %22 + c.name;%0A        %7D);%0A        str = str.split(%22%5Cn%22);%0A        str = str.map(function (c, i) %7B%0A            cLegend = legend%5BMath.round(i - str.length / 2 + self.data.length / 2)%5D%0A            if (cLegend) %7B%0A                return c + %22 %22 + cLegend;%0A            %7D%0A            return c;%0A        %7D).join(%22%5Cn%22);%0A    %7D%0A%0A
     return s
@@ -3691,17 +3691,16 @@
 n str;%0A%7D
-;
 %0A%0Amodule

Support for legend