
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
     * contentBg    {string}    The background color for the element in hex
     * headerBg     {string}    The background color for the header of the
     *                          rounded element in hex
     * footerBg     {string}    The background color for the footer of the
     *                          rounded element in hex
     * borderColor  {string}    The border color of the element in hex
     * 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,
            contentBg:      '#ffffff',
            headerBg:       '#ffffff',
            footerBg:       '#ffffff',
            borderColor:    '#000000',
            corners:        { topLeft: true,
                              topRight: true,
                              bottomLeft: true,
                              bottomRight: true }
        }, arguments[1] || {});

        this._round();

    },

    // makes the rounding effect
    _round: function () {
        var content = this._createContent();
        this._el.appendChild(this._createHeaderOrFooter('header'));
        this._el.appendChild(content);
        this._el.appendChild(this._createHeaderOrFooter('footer'));
    },

    // creates the content area of the element
    _createContent: function () {

        var content = Builder.node('div', {
                style: 'background: ' + this._options.contentBg + '; '
                     + 'border-style: solid; '
                     + 'border-width: 0 1px; '
                     + 'border-color: ' + this._options.borderColor + '; '
            });

        Element.cleanWhitespace(this._el);

        while (this._el.firstChild) {
            content.appendChild(this._el.firstChild);
        } // while

        return content;

    },

    // does something
    _foobar: function (arg) {
        return -(Math.sqrt(1 - (arg * arg)) - 1);
    },

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

        var el          = Builder.node('b'),
            prevMargin  = this._options.radius,
            header      = (headerOrFooter == 'header');
            rows        = [],
            left        = header ? this._options.corners.topLeft : this._options.corners.bottomLeft,
            right       = header ? this._options.corners.topRight: this._options.corners.bottomRight,
            bg          = header ? this._options.headerBg : this._options.footerBg,
            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._foobar((radius - i) / radius) * radius),
                background  = (i == 0 ? this._options.borderColor : bg),
                borderWidth = prevMargin - margin == 0 ? 1 : prevMargin - margin;

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

            rows.push(row);

            prevMargin = margin;

        } // for

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

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

        return el;

    }

};
