/**
 * flashtitle.js
 *
 * @category  ray
 * @package   plugins
 * @author    nothing <info@nothing.ch>
 * @copyright 2008 nothing from outer space (http://www.nothing.ch)
 * @license   http://www.nothing.ch/licence nothing gpl licence
 * @version   SVN: $Id$
 */

/**
 * creates the singleton instance of the flashtitle plugin.
 *
 * @constructor
 * @scope     ray.plugins.flashtitle
 * @tags      plugin, flashtitle, title, header
 * @category  ray
 * @package   plugins
 * @author    loop <loop@nothing.ch>
 * @author    pi <pi@nothing.ch>
 */
ray.plugins.flashtitle = new JS.Singleton( ray.Plugin, {

    /**
     * the global ident of this plugin.
     * @type string
     */
    _name : "flashtitle",

    /**
     * the global configuration of this plugin.
     * @type object
     */
    _config: {},

    /**
     * iterates through all the nodes with class="flashtitle", and replaces
     * their content with the flash title.
     * attributes like text-transform, color and font-size are handed to
     * the flash title generator to influence rendering of the title
     *
     * @return void
     */
    init: function() {
        $( ".flashtitle" ).forEach( this.render, this );
    },

    /**
     * replace the content of the given element with a flash title.
     * attributes like text-transform, color and font-size are handed to
     * the flash title generator to influence rendering of the title
     *
     * @return void
     */
    render: function( element ) {
        // return if the title has already been rendered, or wants to
        // be explicitely initialised (remove class lazy before doing so).
        this.info("flashtitle#render", element );

        if( element.hasClass( "hidden" ) || element.hasClass( "lazy" ) ) {
            return;
        }
        this.index = this.index || 0;
        var index = this.index++;

        var config = this.getProperties( element, index );
        this.info( "prepared config", config );

        // http://code.google.com/p/swfobject/wiki/SWFObject_2_0_documentation
        JS.extend( config, {
            flashvars: {
                id: index,
                text_transform: element.getStyle( "textTransform" ),
                font_size: parseInt( element.getStyle( "fontSize" ) ),
                text: config.text,
                font_color: config.color,
                width: config.width
            },
            params: { menu: "false", wmode: "transparent" },
            attributes: {}
        });

        // create container div
        var div = ray.HTML.div({
                className: "flashtitle container",
                style: {
                    height: config.height,
                    marginLeft: element.getStyle( "marginLeft" ),
                    marginRight: element.getStyle( "marginRight" ),
                    marginTop: element.getStyle( "marginTop" ),
                    marginBottom: element.getStyle( "marginBottom" )
                }
            }, function( html ) {
                html.div( " ", { id: config.replaceId } );
            }
        );
        element.insert( div, "after" );
        config.container = $( div );

        // hide the original element, but only after the style information
        // has been read.
        element.addClass( "hidden ");

        this.info( "new flashtitle", config.width, config.height );
        // http://code.google.com/p/swfobject/wiki/SWFObject_2_0_documentation
        swfobject.embedSWF(
            "/frontend/flash/flashtitle.swf",
            config.replaceId,
            config.width,
            config.height,
            "8.0.0",
            false,
            config.flashvars,
            config.params,
            config.attributes
        );
    },

    /**
     *
     * @param {Object} element
     */
    getProperties: function( element, index ) {
        // read the html content
        var text = element.node.innerHTML;
        text = text.replace( /[\n\t]/g, " " );
        text = text.replace( /\s+/g, " " );
        text = text.replace( /&amp;/, "%26" );

        var color = this.getColor( element );

        // store the current configuration
        var config = {
            element: element,
            text: text,
            color: color,
            replaceId: "flashtitle" + index,
            width: element.getWidth(),
            height: element.getHeight()
        };
        this._config[index] = config;
        return config;
    },

    /**
     * attempt to match the color format as "rgb(r, g, b)" with a
     * decimal from 0-255. if matched, it needs to be converted to hex.
     * if the color format is in the "#rrggbb" format, the prefix needs
     * to be changed to the flash format "0x". hex numbers in the
     * shortened format "#rgb" need to be converted to the complete
     * format.
     *
     * @param {Object} element
     */
    getColor: function( element ) {
        var color = "0x";
        var c = element.getStyle( "color" );
        var m;
        if( (m = c.match( /rgb\(([0-9]+), ([0-9]+), ([0-9]+)\)/ ) ) != null ) {
            color += this.toHex( m[1]) + this.toHex( m[2]) + this.toHex( m[3]);
        } else if( c.indexOf( "#" ) != -1 )  {
            var chars = c.split( "" );
            chars.splice( 0, 1 );
            if( chars.length == 6 ) {
                color += chars.join( "" );
            } else {
                for( var j=0; j < chars.length; j++ ) {
                    color += chars[j] + chars[j];
                }
            }
        }
        return color;
    },

    /**
     * this function is called from flash after replacing
     * the static content with the flash variant.
     *
     * @param int id     the id of the element.
       @param int height the new height
     * @return <void>
     */
    adjustHeight: function( index, height ) {
        var config = this._config[index];
        if( config == null ) {
            throw new Exception( "no configuration found for index=" + index );
        }
       this.info( "flash callback", index, height );

        // adjust the height of the movie.
        $( "#flashtitle" + index ).setStyle({ height: height + "px" });

        // adjust the margins of the container box.
        var diff = (height - parseInt( config.height) ) / 2;
        var container = config.container;
        var top = parseInt( container.getStyle( "marginTop" ) ) - diff;
        var bottom = parseInt( container.getStyle( "marginBottom" ) ) - diff;
        var style = {
            height: height + "px",
            marginTop: (top < 0 ? 0 : top) + "px",
            marginBottom: (bottom < 0 ? 0 : bottom) + "px"
        };
        this.info( "new container style", style );
        container.setStyle( style );
    },

    /**
     * convert the given decimal number to a hexidecimal variant.

     * @param int the decimal number
     * @return string the hexadecimal value.
     */
    toHex: function( number ) {
        return Math.floor( number / 16 ).toString( 16 ) + Math.floor( number % 16 ).toString( 16 );
    }
});
// provide old interface, too.
flashText = ray.plugins.flashtitle;

