var Rounded = Class.create();

Rounded.prototype = {

    /**
     * Class constructor, initializes the variables and makes the rounded corners
     *
     * The constructor takes either one or two parameters. The first one is
     * mandatory and it's the element that is going to have the rounded corners.
     * The second one is an object with the settings for rounding, but it's not mandatory.
     * If the settings aren't given as an argument, the default values will be used.
     * Available rounding settings are:
     *
     * radius       {int}       The radius of the rounding effect
     * corners      {object}    Which corners will be rounded, contains properties
     *                          topLeft, topRight, bottomLeft, bottomRight and each of those
     *                          properties has a boolean value, which tells whether the
     *                          corner should be rounded or not
     *
     * @param   {element}   The element to be rounded
     */
    initialize: function (el) {

        this._el = el;
        this._options = Object.extend({
            radius:         10,
            corners:        { topLeft: true,
                              topRight: true,
                              bottomLeft: true,
                              bottomRight: true },
            headerClass:    'roundedHeader',
            footerClass:    'roundedFooter',
            borderClass:    'roundedBorder'
        }, arguments[1] || {});

        this._round();

    },

    // makes the rounding effect
    _round: function () {
        this._el.parentNode.insertBefore(this._createHeaderOrFooter('header'), this._el);
        this._el.parentNode.appendChild(this._createHeaderOrFooter('footer'));
    },

    // counts the sector's arc's distance from a certain point in the corresponding circle's radius.
    // <var>arg</var> is the point's y-coordinate (0 is in the middle of the circle)
    _countSectorArcDistanceFromRadius: function (arg) {
        return -(Math.sqrt(1 - (arg * arg)) - 1);
    },

    // creates the header or the footer element, depending of the argument
    _createHeaderOrFooter: function (headerOrFooter) {

        var prevMargin  = this._options.radius,
            header      = (headerOrFooter == 'header');
            cls         = header ? this._options.headerClass : this._options.footerClass,
            el          = Builder.node('b', { className: cls }),
            rows        = [],
            left        = header ? this._options.corners.topLeft : this._options.corners.bottomLeft,
            right       = header ? this._options.corners.topRight : this._options.corners.bottomRight,
            radius      = (left || right) ? this._options.radius : 1;

        // create the rows
        for (var i = 0; i < radius; i++) {

            // overall styles for the row
            var margin      = Math.round(this._countSectorArcDistanceFromRadius((radius - (i + 1)) / radius) * radius),
                cls         = (i == 0 ? this._options.borderClass : (header ? this._options.headerClass : this._options.footerClass)),
                borderWidth = prevMargin - margin == 0 ? 1 : prevMargin - margin;

            var row = Builder.node('b', {
                    className: cls,
                    style: 'display: block; '
                         + 'font-size: 1px; '
                         + 'overflow: hidden; '
                         + 'height: 1px; '
                         + 'margin: 0 ' + (right ? margin + 'px' : '0') + ' 0 '
                         + (left ? margin + 'px' : '0') + '; '
                         + 'border-style: solid; '
                         + 'border-width: ' + (i == 0 ? '0' : ('0 ' + (right ? borderWidth : '1')
                         + 'px 0 ' + (left ? borderWidth : '1') + 'px')) + '; '
                });

            rows.push(row);

            prevMargin = margin;

        } // for

        if (!header) {
            rows.reverse();
        }

        rows.each(function (item) { el.appendChild(item); });

        return el;

    }

};