/*!
 * Website singleton class
 * @version 1.0
 * @author M.F.Endenburg
 * @copyright (c) Denbel Systems 2008
 */

// load namespace
Denbel.load( 'Website' );

( function(){
    /**
     * Static object
     */
	Denbel.Website =
	{
		// fields
		_config:
		{
	        dialogDefaultPosition: [150,100],
	        dialogDefaultCaption: document.domain,
	        debug: true,
	        showWait: true
		},
		_href: ( ( document.location.protocol == 'https:' ) ? 'https://' : 'http://' ) + document.domain,
		_isInitialized: null,
		_waitDialog: null,
		_messageDialog: null,
		_dialog: null,
		_valueCollection: null,
		_logReader: null,
		_resources: null,
		_animSpeed: 0.25,
		_fadeSpeed: 0.2,
		_checksum: 'daf2',
		_loader: null,
		
		// events
		ready: null,
		
		/**
		 * initializer
		 * @param bool set to true to use debug mode
		 * @return void
		 */
		init: function( debug, showWait )
		{
            this._config.debug = debug;
            
            try
            {
                Denbel.Website._config.dialogDefaultCaption = Denbel.util.XmlHelper.getNextChildTextValue( document.getElementsByTagName( 'title' )[0] );
            }
            catch( e )
            {
                Denbel.Website._config.dialogDefaultCaption = document.domain;
            }
            
            if( YAHOO.widget.SimpleDialog )
            {
                Denbel.Website._initWaitDialog();
                Denbel.Website._initMessageDialog();
                Denbel.Website._initDialog();
		    }
		    
		    if( Denbel.Website._config.debug )
		    {
		        Denbel.Website._initLogger();
		    }
		    
		    Denbel.Website._valueCollection = new Array();
		},
		
		/**
		 * Executed when Website class is ready
		 * @return void
		 */
		onReady: function()
		{
		    Denbel.Website._isInitialized = true;
		    Denbel.Website.ready.fire();
		},
		
		/**
		 * Create application fingerprint
		 * @return string
		 */
		createFP: function()
		{
            var d = new Date().getTime().toString();
            d = d.substring( 0, d.length - 3 );
            return Denbel.Website._checksum + Denbel.core.MD5.calc( Denbel.Website._checksum + '__' + Denbel.Website.getDomain() + '__' + Denbel.Website._checksum + '_' + d );
		},
		
		/**
		 * initializes a logger
		 * @return void
		 */
		_initLogger: function()
		{
		    Denbel.Website._logReader = new YAHOO.widget.LogReader( null,
		    {
                top: '+300px',
                height: '450px'
            } );
		},
		
		/**
		 * Gets a value indicating this Website was initialized
		 * @return bool
		 */
		isInitialized: function()
		{
		    return Denbel.Website._isInitialized;
		},
		
		/**
		 * Initializes the first tab in CMS
		 * @return bool
		 */
		initFirstTab: function()
		{
            return true;
		},
		
		/**
		 * Adds a key/value pair in the value collection
		 * @param string key
		 * @param mixed value
		 * @return bool true when added, false when key already exists 
		 */
		addValue: function( key, value )
		{
		    if( Denbel.Website._valueCollection[key] )
		    {
		        YAHOO.log( 'addValue: key already exists', 'warn' );
		        return false;
		    }
		    
		    Denbel.Website.setValue( key, value );
		    return true;
		},
		
		/**
		 * Sets a key/value pair in the value collection
		 * @param string key
		 * @param mixed value
		 * @return void
		 */
		setValue: function( key, value )
		{
		    Denbel.Website._valueCollection[key] = value;
		    
		    if( key == 'animSpeed' )
		    {
                Denbel.Website._animSpeed = value;
		    }
		    else if( key == 'fadeSpeed' )
		    {
                Denbel.Website._fadeSpeed = value;
		    }
		},
		
		/**
		 * Removes a key/value pair
		 * @param string key
		 * @return void
		 */
		removeValue: function( key )
		{
		    Denbel.Website._valueCollection[key] = null;
		},
		
		/**
		 * Returns the value by key
		 * @param string key
		 * @return mixed
		 */
		getValue: function( key )
		{
		    if( !Denbel.Website._valueCollection[key] )
		    {
		        YAHOO.log( 'unknown value for key ' + key );
		        return null;
		    }
		    
		    return Denbel.Website._valueCollection[key];
		},
		
		/**
		 * inserts a loader element
		 * @param DOMElement to insert the loader in
		 * @param string text to display
		 * @param string image URI
		 * @return bool
		 */
		insertLoader: function( element, text, imageSrc )
		{
		    if( !imageSrc )
		    {
		        imageSrc = '/media/img/cms/skins/' + Denbel.Website.getValue( 'skinName' ) + '/loader1.gif';
		    }
		    
		    if( !text )
		    {
		        text = null;
		    }
		    
		    var containerEl = Denbel.Website.createLoaderElement( text, imageSrc );
		    element.innerHTML = '';
		    return Denbel.Website.insertContents( element, containerEl );
		},
		
		/**
		 * inserts the contents in a container
		 * @param DOMElement parent
		 * @param DOMElement child(ren)
		 * @param bool when true the contents is handled as a string
		 * @return bool
		 */
		insertContents: function( element, contents, isString )
		{
		    if( !element )
		    {
		        YAHOO.log( 'No element specified', 'error' );
		        return false;
		    }
		    
		    var htmlString = '';
		    element.innerHTML = '';
		    
		    if( !isString )
		    {
                htmlString = Denbel.util.XmlHelper.xmlToString( contents );
		    }
		    else
		    {
                htmlString = contents;
		    }
		    
		    element.innerHTML = htmlString;
		    
		    var xmlDoc = null;
		    
            if( window.ActiveXObject )
            {
                xmlDoc = Denbel.util.XmlHelper.stringToXml( htmlString );
            }
            else
            {
                return true;
            }
            
            if( xmlDoc )
            {
                // execute marked imported scripts
                var scripts = xmlDoc.getElementsByTagName( 'script' );
                var js = '';
                
                YAHOO.log( 'executing exec scripts' );
                    
                for( var i = 0; i < scripts.length; i++ )
                {
                    if( scripts[i].getAttribute( 'class' ) == 'exec' )
                    {
                        for( var j = 0; j < scripts[i].childNodes.length; j++ )
                        {
                            js = scripts[i].childNodes[j].nodeValue;
                                
                            if( js )
                            {
                                try
                                {
                                    eval( js );
                                }
                                catch( e )
                                {
                                    YAHOO.log( 'Cannot exec script', 'error' );
                                    YAHOO.log( e, 'error' );
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                return true;
            }
		    
		    return true;
		},
		
		/**
		 * initializes the message dialog box
		 * @return void
		 */
		_initMessageDialog: function()
		{
		    this._messageDialog = new YAHOO.widget.SimpleDialog( 'message-dialog',
		    {
		        width: '35em',
		        fixedcenter: true,
		        xy: Denbel.Website._config.dialogDefaultPosition,
		        close: false,
		        draggable: true,
		        modal: true,
		        zIndex: 2000,
		        visible: false,
		        effect:
		        {
		            effect: YAHOO.widget.ContainerEffect.FADE,
		            duration: Denbel.Website._fadeSpeed
		        }
		    } );
		    
		    var kl = new YAHOO.util.KeyListener( document, { keys:27 },
		    {
		       fn: Denbel.Website._messageDialog.cancel,
		       scope: Denbel.Website._messageDialog,
		       correctScope: true
		    } );
		    
		    Denbel.Website._messageDialog.cfg.queueProperty( 'keylisteners', kl );
		    
		    Denbel.Website._messageDialog.render( document.body );
		},
		
		/**
		 * initializes the dialog box
		 * @return void
		 */
		_initDialog: function()
		{
		    if( Denbel.Website._dialog )
		    {
		        try
		        {
		            Denbel.Website._dialog.destroy();
		        }
		        catch( e )
		        {
		            // no need to log this.
		            // it is very likely that the dialog was destroyed already.
		        }
		    }
		
		    Denbel.Website._dialog = new YAHOO.widget.Dialog( 'dialog-box',
		    {
		        fixedcenter: false,
		        constaintoviewport: false,
		        xy: Denbel.Website._config.dialogDefaultPosition,
		        close: true,
		        draggable: true,
		        modal: true,
		        zIndex: 2000,
		        visible: false,
		        effect:
		        {
		            effect: YAHOO.widget.ContainerEffect.FADE,
		            duration: Denbel.Website._fadeSpeed
		        },
		        postMethod: 'async'
		    } );
		
		    // make sure we don't leave any traces
		    Denbel.Website._dialog.hideEvent.subscribe( function( e )
		    {
		        this.destroy();
		    } );
		    
		    var kl = new YAHOO.util.KeyListener( document, { keys:27 },
			{
			   fn: Denbel.Website._dialog.cancel,
			   scope: Denbel.Website._dialog,
			   correctScope: true
		    } );
		    
		    this._dialog.cfg.queueProperty( 'keylisteners', kl );
		},
		
		/**
		 * Shows the dialog
		 * @param string caption title
		 * @param mixed string or HTMLElement body
		 * @param Array JSON buttons
		 * @param bool set to true to show close button or set to false to hide the close button
		 * @param string ID of the dialog's Form element
		 * @return void
		 */
		showDialog: function( caption, body, buttons, showClose, formId )
		{
		    Denbel.Website.hideWaitDialog();
		    
		    if( Denbel.Website._dialog )
		    {
		        Denbel.Website._initDialog();
		    }
		    
		    if( !caption )
		    {
		        caption = Denbel.Website._config.dialogDefaultCaption;
		    }
		
		    Denbel.Website._dialog.setHeader( caption );
		    Denbel.Website._dialog.setBody( body );
		    
		    if( !buttons )
		    {
		        buttons = [
		        {
		            text: Denbel.Website.getResource( 'BTN_DIALOG_CLOSE' ),
		            handler: function( e )
		            {
		                this.hide();
		            },
		            isDefault: true
		        }];
		    }
		    
		    Denbel.Website._dialog.cfg.queueProperty( 'buttons', buttons );
		    
		    if( showClose != null )
		    {
		        Denbel.Website._dialog.cfg.queueProperty( 'close', showClose );
		    }
		    
		    if( Denbel.util.BrowserDetect.browser == 'Explorer' )
		    {
		        Denbel.Website._dialog.cfg.queueProperty( 'width', '500px' );
		    }
		    
		    Denbel.Website._dialog.render( document.body );
		    
		    if( formId )
		    {
		        var frm = YAHOO.util.Dom.get( formId );
		        
		        this._dialog.callback =
		        {
		            form: frm,
		            success: function( o )
		            {
		                if( parseInt( o.responseXML.getElementsByTagName( 'code' )[0].firstChild.nodeValue ) != 1 )
		                {
		                    Denbel.Website.showMessageDialog( null, o.responseXML.getElementsByTagName( 'message' )[0].firstChild.nodeValue );
		                }
		            },
		            failure: function( o )
		            {
		                Denbel.Website.showMessageDialog( null, 'FAILED' );
		            },
		            upload: function( o )
		            {
		            }
		        };
		        
		        Denbel.Website.setValue( 'dialogChangeListener', new Denbel.util.ChangeListener( frm ) );
		    }
		    
		    Denbel.Website._dialog.center();
		    Denbel.Website._dialog.show();
		},
		
		/**
		 * initializes the wait dialog
		 * @param string the loading image source
		 * @return void
		 */
		_initWaitDialog: function( imageSrc )
		{
		    Denbel.Website._waitDialog = new YAHOO.widget.Panel( 'wait-dialog',
		    {
		        width: '240px',
		        fixedcenter: true,
		        constraintoviewport: true,
		        xy: Denbel.Website._config.dialogDefaultPosition,
		        close: true,
		        draggable: true,
		        modal: true,
		        zIndex: 65535,
		        visible: false,
		        effect:
		        {
		            effect:YAHOO.widget.ContainerEffect.FADE,
		            duration:0.2
		        }
		    } );
		
		    if( !imageSrc )
		    {
		        imageSrc = '/media/img/cms/skins/' + skinName + '/loader1.gif';
		    }
		    
		    Denbel.Website._waitDialog.setHeader( '&nbsp;' );
		    Denbel.Website._waitDialog.setBody( '<div style="text-align:center;"><img alt="" src="' + imageSrc + '" /></div>' );
		    
		    Denbel.Website._waitDialog.render( document.body );
		},
		
		/**
		 * Creates a loader element in its container element
		 * @param string text to display while loading
		 * @param string image source
		 * @return DOMElement
		 */
		createLoaderElement: function( text, imageSrc )
		{
		    var containerEl = document.createElement( 'div' );
		    containerEl.setAttribute( 'style', 'padding:50px;text-align:center;' );
		    
		    var imageEl = document.createElement( 'img' );
		    imageEl.setAttribute( 'alt', imageSrc );
		    imageEl.setAttribute( 'src', imageSrc );
		    imageEl.setAttribute( 'style', 'vertical-align:middle;' );
		    
		    var textEl = document.createElement( 'span' );
		    textEl.setAttribute( 'style', 'margin-left:10px;' );
		    textEl.innerHTML = text;
		    
		    containerEl.appendChild( imageEl );
		    containerEl.appendChild( textEl );
		    
		    return containerEl;
		},
		
		/**
		 * shows the message dialog box
		 * @param string caption
		 * @param string text
		 * @param int icon index or string icon name
		 * @param int buttons
		 * @return void
		 */
		showMessageDialog: function( caption, text, icon, buttons )
		{
		    if( !Denbel.Website._messageDialog )
		    {
		        return;
		    }
		    
		    if( !caption )
		    {
		        caption = Denbel.Website._config.dialogDefaultCaption;
		    }
		    
		    if( !text )
		    {
		        text = '';
		    }
		    
		    if( icon )
		    {
	            switch( icon.toUpperCase() )
	            {
	                case 'INFO':
	                case 'INFOICON':
	                    icon = YAHOO.widget.SimpleDialog.ICON_INFO;
	                    break;
	                case 'ALARM':
	                case 'ALRTICON':
	                    icon = YAHOO.widget.SimpleDialog.ICON_ALARM;
	                    break;
	                case 'WARNING':
	                case 'WARN':
	                case 'WARNICON':
	                    icon = YAHOO.widget.SimpleDialog.ICON_WARN;
	                    break;
	                case 'ERROR':
	                case 'BLOCK':
	                case 'BLCKICON':
	                    icon = YAHOO.widget.SimpleDialog.ICON_BLOCK;
	                    break;
	                case 'TIP':
	                case 'TIPICON':
	                    icon = YAHOO.widget.SimpleDialog.ICON_TIP;
	                    break;
	                case 'HELP':
	                case 'HLPICON':
	                    icon = YAHOO.widget.SimpleDialog.ICON_HELP;
	                    break;
	                default:
	                    icon = YAHOO.widget.SimpleDialog.ICON_INFO;
	                    break;
	            }
            }
            else
            {
                icon = YAHOO.widget.SimpleDialog.ICON_INFO;
            }
		    
		    if( !buttons )
		    {
		        buttons = [
		        {
		            text: Denbel.Website.getResource( 'BTN_CLOSE' ),
		            handler: function( e )
		            {
		                this.hide();
		            },
		            isDefault: true
		        }];
		    }
		    
            Denbel.Website.hideWaitDialog();
		    
		    this._messageDialog.setHeader( caption );
		    this._messageDialog.setBody( text );
		
		    this._messageDialog.cfg.setProperty( 'icon', icon );
		    this._messageDialog.cfg.queueProperty( 'buttons', buttons );
		    
		    this._messageDialog.render();
		    this._messageDialog.show();
		},
		
		/**
		 * hide the message dialog box programmatically
		 * @return void
		 */
		hideMessageDialog: function()
		{
		    if( !Denbel.Website._messageDialog )
		    {
		        return;
		    }
		    
		    Denbel.Website._messageDialog.hide();
		},
		
		/**
		 * shows a wait dialog
		 * @param string caption
		 * @return void
		 */
		showWaitDialog: function( caption )
		{
            if( Denbel.Website._messageDialog.cfg.getProperty( 'visible' ) )
            {
                return;
            }
            
		    if( !Denbel.Website._config.showWait )
		    {
		        return;
		    }
		    
		    if( !Denbel.Website._waitDialog )
		    {
		        Denbel.Website._initWaitDialog();
		    }
		    
		    if( !caption )
		    {
		        caption = Denbel.Website.getResource( 'TXT_WAIT_CAPTION' );
		        
		        if( !caption || caption == 'TXT_WAIT_CAPTION' )
		        {
		            caption = 'Loading...'; //Denbel.Website._config.dialogDefaultCaption;
		        }
		    }
		    
		    Denbel.Website._waitDialog.setHeader( caption );
		    Denbel.Website._waitDialog.show();
		},
		
		/**
		 * hides the wait dialog
		 * @return void
		 */
		hideWaitDialog: function()
		{
		    if( !Denbel.Website._waitDialog )
		    {
		        return;
		    }
		    
		    Denbel.Website._waitDialog.hide();
		},
		
		/**
		 * Returns a resource value by its key
		 * @param string key
		 * @return string value
		 */
		getResource: function( key )
		{
		    if( !key )
		    {
		        YAHOO.log( 'no resource key given', 'error' );
		        return null;
		    }
		    
		    if( Denbel.Website._resources == null )
		    {
                YAHOO.log( 'no resources loaded', 'error' );
                return key;
		    }
		    
		    var val = Denbel.Website._resources.get( key );
		    return ( ( val ) ? val : key )
		},
        
        /**
         * Saves a larger amount of data to a cookie
         * @param string name
         * @param Variant data can be either string, number or Array
         * @return void
         */
        setData: function( name, data )
        {
            if( !name || !YAHOO.lang.isString( name ) )
            {
                YAHOO.log( 'setData expects name to be a string', 'error', 'Denbel.Website' );
                return null;
            }
            
            var d = Denbel.core.Base64.encode( data );
            
            if( d.length > 7168 )
            {
                YAHOO.log( 'Data too long. Maximum request header size exceeded.', 'error', 'Denbel.Website' );
                throw Error( 'Data too long. Maximum request header size exceeded.' );
                return null;
            }
            
            if( d.length > 2048 )
            {
                var chunk = '';
                var part = 1;
                
                for( var i = 0; i < d.length; i++ )
                {
                    if( chunk.length == 2048 )
                    {
                        YAHOO.util.Cookie.set( name + '_' + part, chunk );
                        part++;
                        chunk = '';
                    }
                    
                    chunk += d.charAt( i );
                }
                
                YAHOO.util.Cookie.set( name + '_' + part, chunk );
            }
            else
            {
                YAHOO.util.Cookie.set( name, d );
            }
        },
        
        /**
         * Gets a larger amount of data from cookie
         * @param string name
         * @return Variant
         */
        getData: function( name )
        {
            var data = '';
            var c = null;
            var i = 1;
            
            while( ( c = YAHOO.util.Cookie.get( name + '_' + i ) ) != null )
            {
                data += Denbel.core.Base64.decode( c );
                i++;
            }
            
            if( data.length == 0 )
            {
                return null;
            }
            
            return data;
        },
		
		/**
		 * Loads resources from server
		 * @param bool cache set to true to force no cache
		 * @return void
		 */
		loadResources: function( cache )
		{
            var msg = new Denbel.rpc.XmlRpcMessage( 'getResources' );
            var c = new Denbel.rpc.XmlRpcClient();

            c.callService( msg,
            {
                success: Denbel.Website.loadResourcesCompleted,
                failure: Denbel.Website.loadResourcesFailure,
                argument: null
            }, cache );
		},
		
		/**
		 * Callback for the loadResources function
		 * @param object returned parameters
		 * @return void
		 */
		loadResourcesCompleted: function( e )
		{
            Denbel.Website._resources = e.data[0];
            Denbel.Website.onReady();
		},
		
		/**
		 * callback for the loadResources function if it fails
		 * @param object returned parameters
		 * return void
		 */
		loadResourcesFailure: function( e )
		{
            Denbel.Website._resources = null;
            Denbel.Website.onReady();
		},
		
		/**
		 * called when AJAX call succeeded
		 * @param object
		 * @return void
		 */
		onAsyncSuccess: function( o )
		{
		    alert( o.responseText );
		},
		
		/**
		 * called when AJAX call failed
		 * @param object
		 * @return void
		 */
		onAsyncFailure: function( o )
		{
		    alert( o.status + ' ' + o.statusText );
		},
		
		/**
		 * called when ajax upload is done
		 * @param object
		 * @return void
		 */
		onAsyncUpload: function( o )
		{
		    alert( o.responseText );
		},
		
		/**
		 * Executes marked scripts. A marked script is a SCRIPT tag with 'exec' as a class.
		 * @return void
		 */
		execScripts: function()
		{
		    YAHOO.log( 'execScripts called' );
		    
		    var scripts = YAHOO.util.Dom.getElementsByClassName( 'exec' );
		    
		    for( var i = 0; i < scripts.length; i++ )
		    {
		        eval( scripts[i].innerHTML );
		    }
		    
		    YAHOO.log( 'execScripts executed ' + i + ' scripts', 'info', 'website' );
		    return;
		},
		
		/**
		 * returns the current domain
		 * @return string
		 */
		getDomain: function()
		{
		    return Denbel.Website._href;
		},
		
		/**
		 * returns the wait dialog
		 * @return YAHOO.widget.Dialog
		 */
		getWaitDialog: function()
		{
		    return Denbel.Website._waitDialog;
		},
		
		/**
		 * returns the message dialog
		 * @return YAHOO.widget.Dialog
		 */
		getMessageDialog: function()
		{
		    return Denbel.Website._messageDialog;
		},
		
		/**
		 * Returns the dialog box
		 * @return void YAHOO.widget.Dialog
		 */
		getDialog: function()
		{
		    if( !Denbel.Website._dialog )
		    {
		        Denbel.Website._initDialog();
		    }
		    
		    return Denbel.Website._dialog;
		},
		
		/**
		 * Loads a script module into the site
		 * @param mixed Array with names or a string with the name of the script (e.g. module.auth or xmlrpcclient)
		 * @param bool true to include debug version
		 * @return bool
		 */
		load: function( name, debug )
		{
            if( !name )
            {
                return false;
            }
            
            if( YAHOO.lang.isArray( name ) )
            {
                for( var i = 0; i < name.length; i++ )
                {
                    Denbel.Website.load( name[i], debug );
                }
            }
            else
            {
	            var v = '-min';
	            
	            if( debug )
	            {
	                v = '-debug';
	            }
	            
	            name = name.toLowerCase();
	            
	            var parts = name.split( '.' );
	            var fullpath = '';
	            
	            for( var i = 0; i < parts.length; i++ )
	            {
	                if( fullpath )
	                {
	                    fullpath += '/';
	                }
	                
	                fullpath += parts[i];
	            }
	            
	            fullpath = Denbel.Website._href + '/script/' + fullpath + v + '.js';
	            
	            var o =
	            {
		            'name': name,
		            'fullpath': fullpath,
		            'skinnable': false,
		            'type': 'js'
	            };
	            
	            try
	            {
	                if( !Denbel.Website._loader )
	                {
	                    Denbel.Website._loader = new YAHOO.util.YUILoader();
	                }
	                
	                var r = Denbel.Website._loader.addModule( o );
	                
	                if( r )
	                {
	                    YAHOO.log( 'Module added ' + fullpath );
	                }
	                else
	                {
	                    YAHOO.log( 'Cannot add module ' + fullpath, 'error' );
	                }
	            }
	            catch( e )
	            {
	                YAHOO.log( e, 'error' );
	                return false;
	            }
            }
		},
		
		/**
		 * converts this object to its string representation
		 * @return string
		 */
		toString: function()
		{
            return 'Denbel.Website';
		}
    };
} )();
