function sector(cx, cy, r, startAngle, endAngle) {
    var rad = Math.PI / 180,
        x1 = cx + r * Math.cos(-startAngle * rad),
        x2 = cx + r * Math.cos(-endAngle * rad),
        xm = cx + r / 2 * Math.cos(-(startAngle + (endAngle - startAngle) / 2) * rad),
        y1 = cy + r * Math.sin(-startAngle * rad),
        y2 = cy + r * Math.sin(-endAngle * rad),
        ym = cy + r / 2 * Math.sin(-(startAngle + (endAngle - startAngle) / 2) * rad);

    var color = ["M", x1, y1, "A", r, r, 0, +(Math.abs(endAngle - startAngle) > 180), 1, x2, y2];
    color.middle = {x: xm, y: ym};

    var trans = ["M", x2, y2, "L", cx, cy, "L", x1, y1, "A", r, r, 0, +(Math.abs(endAngle - startAngle) > 180), 1, x2, y2 ];
    trans.middle = {x: xm, y: ym};
    return {trans: trans, color: color};
}

function sector_labels(cx, cy, r, startAngle, endAngle, midAngle, font_attrs) {
    var rad = Math.PI / 180,
        xm = cx + (r + 80) / 2 * Math.cos(-(startAngle + (endAngle - startAngle) / 2) * rad),
        ym = cy + (r + 80) / 2 * Math.sin(-(startAngle + (endAngle - startAngle) / 2) * rad);

    var anchor = "middle";
    /* gli anngoli non vengono precisi, quindi diamo una soglia di un grado */
    if ((midAngle >= -90-1 && midAngle <= -90+1) || (midAngle >= 90-1 && midAngle <= 90+1)) {
        anchor = "middle";
    } else if (midAngle > -90) {
        anchor = "end";
    } else if (midAngle < -90) {
        anchor = "start";
    }
    /* In ii negli spicchi superiori il testo si appoggia sui punti medi quindi
     * spostiamoci sotto della dimensione del testo, l'1.2 è arbitrario per far contento Mauro */
    if (endAngle > 0 || endAngle < -200) {
         ym += font_attrs['font-size'] * 1.2;
    }
    return {x: xm, y: ym, anchor: anchor};
}

function sector_print(cx, cy, r, startAngle, endAngle) {
    var rad = Math.PI / 180,
        x1 = cx + r * Math.cos(-startAngle * rad),
        y1 = cy + r * Math.sin(-startAngle * rad);

    return {x: x1, y: y1, start: startAngle, end: endAngle};
}

/* Based on g.pie.js:
 * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)
 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
 */
Raphael.fn.g.foochart = function (cx, cy, r, values, opts) {
    opts = opts || {};
    var paper = this;
    var angle = opts.start || 0;
    var sectors = [];
    var series = paper.set();
    var covers = paper.set();
    var chart = paper.set();
    var outer_circle = paper.set();
    var len = values.length;
    var nodes = [];
    var center_single_label = typeof(opts.center_single_label) == 'undefined' ? true : opts.center_single_label;

    var total = 100;
    var endangle;
    chart.covers = covers;

    for (var i = 0; i < len; i++) {
        var mangle = angle - 360 * values[i].value / total / 2;
        if (!i) {
            angle = 90 - mangle;
            mangle = angle - 360 * values[i].value / total / 2;
        }

        endangle = angle - 360 * values[i].value / total;
        if (len == 1) {
             /* se gli faccio fare 360 gradi completi non viene disegnato il cerchio */
             endangle = endangle > 0 ? endangle-0.02 : endangle+0.02; 
        }
        var path = sector(cx, cy, r, angle, endangle);
        var trans = paper.path(path.trans).attr({fill: opts.nofill && "none"|| opts.colors && opts.colors[i] || "#666", stroke: "none", "stroke-width": opts.strokewidth || 1, "stroke-linejoin": "round"});
        var color = paper.path(path.color).attr({fill: opts.nofill && "none"|| opts.colors && opts.colors[i] || "#666", stroke: values[i].stroke && values[i].stroke || "none", "stroke-width": opts.strokewidth || 1, "stroke-linejoin": "round"});

        if (values[i].label) {
            var sec = sector_labels(cx, cy, r, angle, endangle, angle - 360 * values[i].value / 2 / total, values[i].label.attrs);
            if (len == 1 && center_single_label) {
                var label = paper.text(cx, cy, values[i].label.text).attr(values[i].label.attrs);
            } else {
                var label = paper.text(sec.x, sec.y, values[i].label.text).attr(values[i].label.attrs).attr({'text-anchor': sec.anchor});
            }
            nodes.push(label.node);
        }

        /* Salviamo i clienti, nel caso non si abbia la label metto il mio indice */
        if (values[i].label) {
            jQuery.data(trans.node, 'clients', values[i].label.clients);
        } else {
            jQuery.data(trans.node, 'clients', [i]);
        }

        /* WORKAROUND: settiamo il link pure sul bordo colorato */
        if (values[i].label) {
            color.attr({href: values[i].label.href});
        } else {
            color.attr({href: values[i].href});
        }

        trans.value = values[i].value;
        trans.middle = path.trans.middle;
        trans.mangle = mangle;
        trans.color = color;
        trans.label = label;
        sectors.push(trans);
        series.push(trans);
        angle = endangle;
    }

    /* Mettiamo i link sugli spicchi */
    for (var i = 0; i < len; i++) {
        var p = paper.path(sectors[i].attr("path")).attr(paper.g.shim);
        if (values[i].label && values[i].label.href) {
            p.attr({href: values[i].label.href});
        } else if (values[i].href) {
            p.attr({href: values[i].href});
        }
        p.attr = function () {};
        series.push(p);
        covers.push(p);
    }

    chart.hover = function (fin, fout) {
        fout = fout || function () {};
        var that = this;
        for (var i = 0; i < len; i++) {
            (function (sector, cover, j) {
                var o = {
                    sector: sector,
                    cover: cover,
                    cx: cx,
                    cy: cy,
                    mx: sector.middle.x,
                    my: sector.middle.y,
                    mangle: sector.mangle,
                    r: r,
                    value: values[j].value,
                    total: total,
                    label: that.labels && that.labels[j]
                };
                cover.mouseover(function () {
                    fin.call(o);
                }).mouseout(function () {
                    fout.call(o);
                });
            })(series[i], covers[i], i);
        }
        return this;
    };
    // x: where label could be put
    // y: where label could be put
    // value: value to show
    // total: total number to count %
    chart.each = function (f) {
        var that = this;
        for (var i = 0; i < len; i++) {
            (function (sector, cover, j) {
                var o = {
                    sector: sector,
                    cover: cover,
                    cx: cx,
                    cy: cy,
                    x: sector.middle.x,
                    y: sector.middle.y,
                    mangle: sector.mangle,
                    r: r,
                    value: values[j].value,
                    total: total,
                    label: that.labels && that.labels[j]
                };
                f.call(o);
            })(series[i], covers[i], i);
        }
        return this;
    };
    chart.click = function (f) {
        var that = this;
        for (var i = 0; i < len; i++) {
            (function (sector, cover, j) {
                var o = {
                    sector: sector,
                    cover: cover,
                    cx: cx,
                    cy: cy,
                    mx: sector.middle.x,
                    my: sector.middle.y,
                    mangle: sector.mangle,
                    r: r,
                    value: values[j].value,
                    total: total,
                    label: that.labels && that.labels[j]
                };
                cover.click(function () { f.call(o); });
            })(series[i], covers[i], i);
        }
        return this;
    };

    chart.push(series, covers);
    chart.series = series;
    chart.covers = covers;
    chart.nodes = nodes;
    return chart;
}

/* n_slice multiplo di n_words */
Raphael.fn.textchart = function(cx, cy, r, delta, words, opts) {
    opts = opts || {font_family: 'Arial', font_color: '#000', font_size: '10'};

    var paper = this;
    var n_words = words.length;
    var words_circle = [];
    var angle = 0;
    var total = 100;
    var word_size = total / n_words;

    var n_slice = opts.slices || n_words;
    var slice_size = total / n_slice;
    var ratio = n_slice / n_words;

    var positions = [];
    var rotations = 0;

    function calc_rotation(coords) {
        var rotate;
        if (coords.start == 0 || coords.start == -180) {
            rotate = 0;
        } else if (coords.start >= -90) {
            rotate = -coords.start;
        } else if (coords.start < -90) {
            rotate = 180 - coords.start;
        }
        return rotate;
    }

    for (var i = 0; i < n_slice; i++) {
        var mangle = angle - 360 * slice_size / total / 2;
        if (!i) {
            angle = 90;
            mangle = angle - 360 * slice_size / total / 2;
        }
        var coords = sector_print(cx, cy, r+delta, angle, angle -= 360 * slice_size / total);
        coords.rotate = calc_rotation(coords);

        if (i % ratio == 0) {
            var font_color = words[i/ratio].active ? opts.font_color : opts.font_color_na;
            var font_attrs = {'font-size': opts.font_size, 'font-family': opts.font_family, 'text-anchor': coords.start >= -90 ? 'start': 'end'};
            var txt = paper.text(coords.x, coords.y, words[i/ratio].name).attr({fill: font_color, start: coords.start, end: coords.end }).attr(font_attrs);
            txt.rotate(coords.rotate, coords.x, coords.y);
            if (words[i/ratio].active) {
                txt.attr({href: words[i / ratio].href});

                if ($.browser.msie) {
                    $(txt.node).parent().parent().attr('href', words[i / ratio].href);
                    $(txt.node).parent().attr('href', words[i / ratio].href);
                    $(txt.node).parent().parent().css({cursor: "pointer"});
                    $(txt.node).parent().css({cursor: "pointer"});
                    $(txt.node).css({cursor: "pointer"});
                    $(txt.node).parent().parent().click(function() {
                        window.location = $(this).attr('href');
                    });
                }
            }

            jQuery.data(txt.node, 'media', words[i / ratio].media);

            words_circle.push(txt);
        }
        positions.push(coords);
    }

    return {circle: words_circle, positions: positions};
}

function full_arc(value, total, R, pos) {
    var alpha = 360 / total * value,
                a = (90 - alpha) * Math.PI / 180,
                x = pos + R * Math.cos(a),
                y = pos - R * Math.sin(a),
                color = this.attrs.stroke,
                path;
    if (total == value) {
        path = [["M", pos, pos - R], ["A", R, R, 0, 1, 1, pos-0.01, pos - R]];
    } else {
        path = [["M", pos, pos - R], ["A", R, R, 0, +(alpha > 180), 1, x, y]];
    }
    return {path: path, stroke: color};
}

