/*******************************************************************************
* This file describes all the messenging API system                            *
*                                                                              *
* This software is proprietary and shall not be disclosed without the formal   *
* agreement of the author and or the customer (Albert Longa)                   *
* This code can not be reproduced, even in part without the copyright owner    *
* authorisation                                                                *
*                                                                              *
* Copyright 2006, 2007 Florian Delizy <florian.delizy@unfreeze.net>            *
* Copyright 2006, 2007 TOOMAG Cie (C)                                          *
*******************************************************************************/

// Message API, based on outputHelpers.php.inc
// Todo refactor this into classes, 
// allow messages as tooltips on the element ....
// Use Animator to timeout and add fading
// refactor with Prototype lib
// finish the printing system



// Logger is the object container for all logging features:
var Logger =
{

    // Message types (used to set the style)

    MSG_ADMIN   : 0,
    MSG_INFO    : 1,
    MSG_WARNING : 2,
    MSG_FATAL   : 3,

    // type => class Style translation table:

    msgStyles: new Array ( 'admin', 'info', 'warning', 'fatal' ),

    // message holder (keeps reference to hide them when needed
    messages: new Array(),

    // control global messages display
    enableMessages: true,
    // used to keep track of the global messages place (ul)
    globalHolder: null,
    
    Enable : function() { Logger.enableMessages = true;  },
    Disable: function() { Logger.enableMessages = false; },
    Enabled: function() { return Logger.enableMessages;  },

    // Removes the specified message (aimed at being used by setTimeout()
    RemoveMessage: function( idx )
    {
        Logger.messages[idx].Remove();
        //Logger.messages.remove( idx );
    },

    // Get or create the global messages holder
    GetGlobalHolder: function()
    {
        if ( !Logger.globalHolder )
        {
            var anchor = $('JScriptMessages' );
            if ( !anchor ) return false;

            var ul = Element.extend( document.createElement( 'ul' ) );
            ul.addClassName('messages' );
            anchor.appendChild( ul );

            Logger.globalHolder = ul;
        }        
        return Logger.globalHolder;
    },

    // This function confirms the choice of a user
    ConfirmUrlLoad: function ( message, destUrl )
    {
       if ( confirm( message ) )
       {
            location.replace( destUrl );
       }
    },

    ReferenceMe: function( elem ) { Logger.messages.push( elem ); return Logger.messages.length - 1; },
    UnReferenceMe: function( idx ) { Logger.messages.remove( idx ); }

};

// This holds a site message ready to be shown/deleted
function SiteMessage ( message, severity )
{
    this.Remove = function() { this.msg.remove(); }

    this._message = message;

    if ( !Logger.Enabled() ) return;
     
    var holder = Logger.GetGlobalHolder();
    if ( !holder )
    {
        // The document does not contain the anchor
        // We have to issue an alert then ...
        alert( message );
        return;
    }

    // Create the ul if it does not exists :

    var msg = Element.extend( document.createElement( "li" ) );
    msg.addClassName( Logger.msgStyles[ severity ] );
    msg.appendChild( document.createTextNode( message ) );

    this.msg = msg;
    holder.appendChild( msg );
    var idx = Logger.ReferenceMe( this );
    setTimeout( 'Logger.RemoveMessage( ' + idx + ');', 5000 );

    window.scrollTo( 0, 0 ); // Hack!!
}

// This creates a message shown just under the element position
function TooltipMessage( elem, message, severity )
{
    this.Remove = function () 
    { 
        this._page.Close(); 
    }

    // Create the ul if it does not exists :

    var ul = $( document.createElement( 'ul' ) );
    ul.addClassName( 'messages' );

    var msg = Element.extend( document.createElement( "li" ) );
    msg.addClassName( Logger.msgStyles[ severity ] );
    msg.appendChild( document.createTextNode( message ) );
    ul.style.margin = "0px";
    msg.style.margin = "0px";
    ul.style.padding = "0px;";
    ul.appendChild( msg );
    
    msg.style.minWidth= "250px";
    

    // Create a new page:

    var element = $( elem );
    var offset = Position.cumulativeOffset( element );

    var height = element.clientHeight;
    if ( "SELECT" == element.tagName )
    {
        // Since selects have a non visible part, their 'height' is wrong
        height = element.offsetHeight;
    }

    var options = { autosize: true
                  , autoclose: true
                  , x: offset[0]
                  , y: offset[1] + height 
                  , noloading: true
                  };

    if ( Prototype.Browser.IE )
    {
        options.width  = 250;
        options.height = 50;

        msg.style.height = "44px";
        msg.style.width = '250px';
    }

    this._page = new PageHolder( options );
    this._page._page.style.backgroundColor = 'transparent'; // HACK
    this._page.SetContent( ul );
    this._page.HideSelects();

    this.msg = msg;
    var idx = Logger.ReferenceMe( this );

    setTimeout( 'Logger.RemoveMessage( ' + idx + ');', 5000 );
}

// This function confirms the choice of a user

// DEPRECATED! use Logger and messages instead:
var MSG_ADMIN   = Logger.MSG_ADMIN;
var MSG_INFO    = Logger.MSG_INFO;
var MSG_WARNING = Logger.MSG_WARNING;
var MSG_FATAL   = Logger.MSG_FATAL;
var msgStyles   = Logger.msgStyles;
var MSG_TEMP    = true;
var MSG_STAY    = false;
function RaiseMessage( message, severity, temporary ) { new SiteMessage( message, severity ); }
function ConfirmChoice( message, destUrl ) { Logger.ConfirmUrlLoad( message, destUrl ); }



// This function is used to print the current window content (the includedPage item)
// it turns any non-printable widget into printable widget, desactivates all menus/links..
// and finally print the window

function PrintIt()
{
    var content = document.getElementById( 'includedPage' );

    if ( !content )
    {
        alert( "no content!");
        return false;
    }


    var newContent = content.cloneNode( true );

    var printWnd = window.open( '', ''
                              ,  'location=no'
                              + ',status=yes'
                              + ',menubar=no'
                              + ',fullscreen=no'
                              + ',width=950'
                              + ',scrollbars=yes'
                              //+ ',height=160'
                              + ',resizable=0'
                              );

    // Create the base document for print
    
    var destDoc = printWnd.document;
    destDoc.write(
                    '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
                   +'<?xml version="1.0" encoding="iso-8859-1" ?>'
                   +'<html xml:lang="fr" lang="fr">'
                   +'<head>'
                   +'</head>'
                   +'<body id="body">'
                   +'<img src="images/design/title.png" alt="creaparis"/>'
                   +'<div id="insertPoint"></div>'
                   +'<div class="disclaimer" style="width:90%;text-align:center">'
                   +"©2003/2006, Creaparis - protection IDDN - Infos et photos non contractuelles susceptibles d'être modifiées sans préavis - Visa CNIL #1056793"
                   +'</div>'
                   +'</body>'
                   +'</html>');

    // First add css rulez from the initial document

    var i = 0;


    var copyNode = [ 'link', 'styles' ];
    var destNode = destDoc.getElementsByTagName( 'head' )[0];

    for ( i = 0; i < copyNode.length ; i ++ )
    {
        var j = 0;
        var copySet = document.getElementsByTagName( copyNode[i] );

        for ( j = 0; j < copySet.length ; j ++ )
        {
            var content = copySet[j].cloneNode( true );
            destNode.appendChild( content );
        }
    }
     

    // Now rework the content to print to remove links, edit text ... 


    // delete scripts

    var tagRemoval = [ 'script', 'button' ];
    var idx;

    for( idx = 0; idx < tagRemoval.length; idx ++ )
    {
        var scripts = newContent.getElementsByTagName( tagRemoval[idx] );
        for( i = scripts.length - 1; i >= 0; i-- ) 
        {
            // Since we delete elements here, we have
            // to make sure that we are not deleting
            // elements that were childs of previously
            // removed elements ...
            if ( scripts[i] && scripts[i].parentNode )
            {
                var parentNode = scripts[i].parentNode;
                parentNode.removeChild( scripts[i] );
            }
        }
    }
    

    // freeze anchors links
    var anchors = newContent.getElementsByTagName( "a" );
    for ( i = 0; i < anchors.length; i++ ) 
        anchors[i].removeAttribute( 'href' );

    // change the input/select/textareas into div

    var inputs = newContent.getElementsByTagName( 'input' );
    for ( i = inputs.length - 1; i >= 0 ; i -- )
    {
        var parentNode = inputs[i].parentNode;
        var type = inputs[i].getAttribute("type");

        switch( type )
        {
            case 'password' :
            case 'text':
                var divnode = destDoc.createElement( 'span' );
                divnode.innerHTML = ('' != inputs[i].value)? inputs[i].value : '&nbsp;';
                parentNode.replaceChild( divnode, inputs[i] );
                break;
            case 'checkbox' :
            case 'radio' :
                if ( !inputs[i].checked )
                {
                    if( inputs[i].nextSibling )
                        parentNode.removeChild(inputs[i].nextSibling);
                }
                parentNode.removeChild(inputs[i]);
                break;
        }

    }

    // Replace selects by their text content
    var selects = newContent.getElementsByTagName( 'select' );
    for (i = selects.length - 1; i >= 0; i-- )
    {
        var parentNode = selects[i].parentNode;
        var divnode = destDoc.createElement( 'span' );

        var options = selects[i].getElementsByTagName( 'option' );
        var j;

        var text =  "&nbsp;";

        for ( j = 0; j < options.length; j++ )
        {
            if ( options[j].value == selects[i].value )
            {
                text = options[j].text;
                break;
            }
        }

        divnode.innerHTML = text;
        parentNode.replaceChild( divnode, selects[i] );
    }

    // finally apply basic textarea substitutions

    var textareas = newContent.getElementsByTagName( 'textarea' );
    for (i = textareas.length - 1; i >= 0; i --)
    {
        var parentNode = textareas[i].parentNode;
        var divnode = destDoc.createElement( 'span' );

        divnode.innerHTML = (textareas[i].value) ? textareas[i].value : '&nbsp;';
        divnode.className = "textarea";
        parentNode.replaceChild( divnode, textareas[i]);
    }

    // Finally adds the result 
    destDoc.getElementById("insertPoint").appendChild( newContent );

    // Removes OKCancelWidgets and control tabs ... This must be done 
    // on the document, since this is the only one having the getElementById
    // function ...

    var widget;
    var widgetRemoval = [ "okcancelwidget", "pricewidget", "imagewidget", "modificationwidget" ];

    for( i = 0; i < widgetRemoval.length; i ++)
    {
	widget = destDoc.getElementById( widgetRemoval[i] );
	if (widget)
        {
            widget.parentNode.removeChild( widget );
        }
    }
    printWnd.creator = self;
    printWnd.focus();
    printWnd.print();
    return true;
}

// vim:sw=4:smartindent:

