// ------------------------------------------------------------
// Copyright (c) 2002 bestsolution.at Systemhaus GmbH.
// All Rights Reserved.
// 
// bestsolution.at MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
// THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
// OR NON-INFRINGEMENT. bestsolution.at SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED
// BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE
// OR ITS DERIVATIVES.
// ------------------------------------------------------------

// ------------------------------------------------------------
// Original File Name:  rdf_ticker.js
// Creation Date:       2002-04-20   ## yyyy-mm-dd
// Description:         The superclass of all rdfTickers
// ------------------------------------------------------------



// -----------------------------------------------------------
// rdfTickerSuperClass
// -----------------------------------------------------------
//
// arguments:
//      none
//
// description
//      The class who does most of the magic. This is the super
//  	of all rdfTickers. This is the class definition.
//
// return value(s):
//  	Object
function rdfTickerSuperClass()
{
    this.newsControl      = null;
    this.newsContentFrame = null;
    this.newsHeadline     = null;
    this.newsBlock        = null;
    this.newsFoot         = null;
    this.newsLine         = null;
    this.newsTeaser       = null;
    this.newsLink         = null;
    this.tickerItems      = new Array();
    this.lastLoad         = null;
    this.newsDuration     = 6000;
    this.reloadTime       = 300000;
    this.activeItem       = -1;
    this.newsIntervalId   = null;
    this.teaserText       = null;
    this.teaserLink       = null;

    this.loadInfo         = "fetching new data ...";
    this.linkInfo         = "more...";
    this.headLineInfo     = "Newsticker";
    this.footInfo         = "Last Update:";
    this.xmlfile          = null;
    this.redrawType       = null;

    this.init                   = init;
    this.applyStyleClasses      = applyStyleClasses;
    this.createElements         = createElements;
    this.drawTickerConstruction = drawTickerConstruction;
    this.startTicker            = startTicker;
    this.fillHeader             = fillHeader;
    this.fillFooter             = fillFooter;
    this.getAndProcessXMLDocument         = getAndProcessXMLDocument;
    this.processXML             = processXML;
    this.ignition        = ignition;
    this.showNextItem    = showNextItem;
    this.nextItem        = nextItem;
    this.redrawItem      = redrawItem;
    this.reloadXMLDoc    = reloadXMLDoc;
    this.showActiveUrl   = showActiveUrl;
    this.overwriteDefaults = overwriteDefaults;
    this.testXMLFile     = testXMLFile;
    this.redrawByReplace = redrawByReplace;
    this.redrawByFadeOut = redrawByFadeOut;
    
    
    // -----------------------------------------------------------
    // testXMLFile
    // -----------------------------------------------------------
    //
    // arguments:
    //      String file ... the xml-file-name
    //
    // description
    //      Tests whether we got an xml-filename or not
    //
    // return value(s):
    //	    boolean rc
    function testXMLFile( file )
    {
        var rc = true;
        
        if( file == null )
        {
            alert( "No xml-file. Aborting" );
            rc = false;
        }
        
        return rc;
    }
    
    
    // -----------------------------------------------------------
    // overwriteDefaults
    // -----------------------------------------------------------
    //
    // arguments:
    //      Array parameters ... values to be replaced
    //
    // description
    //      Overwrites default values which are set when the class is
    //	    istanciated
    //
    // return value(s):
    //	    void
    function overwriteDefaults( parameters )
    {
        var parameterNames = new Array( "xmlfile", "loadInfo","linkInfo","headLineInfo","footInfo" );
        
        for( var i = 0; i < parameterNames.length; i++ )
        {
            this[parameterNames[i]] = ( parameters[parameterNames[i]] != null )?parameters[parameterNames[i]]:this[parameterNames[i]];
        }
    }

    
    // -----------------------------------------------------------
    // init
    // -----------------------------------------------------------
    //
    // arguments:
    //      none
    //
    // description
    //      Inits the ticker by creating all ticker-components and
    //	    drawing them in the actual browser window
    //
    // return value(s):
    //	    void
    function init() 
    {  
        var tickerDivElements = new Array( "newsControl", "newsContentFrame", "newsHeadline", "newsBlock", "newsFoot", "newsLine" );
        var tickerSpanElements = new Array( "newsTeaser", "newsLink" );
        var textNodeElements   = new Array( "newsHeadline","newsFoot", "newsTeaser", "newsLink" );

        this.createElements( tickerDivElements, tickerSpanElements, textNodeElements );        
        this.applyStyleClasses( tickerDivElements, tickerSpanElements );
        this.drawTickerConstruction();
    }
    
    
    // -----------------------------------------------------------
    // createElements
    // -----------------------------------------------------------
    //
    // arguments:
    //      Array tickerDivElements .... Div-Containers (=> Block)
    //	    Array tickerSpanElements ... Span-Containers (=> Inline)
    //	    Array textNodeElements ..... Text-Node-Elements (=> Text)
    //
    // description
    //      This method creates all tickerElements (Containers,Textnodes)
    //	    simply by invoking the documents createElement-method. The
    //	    elements are stored inside instance variables
    //
    // return value(s):
    //	    void
    function createElements( tickerDivElements, tickerSpanElements, textNodeElements )
    {
        for( var i = 0; i < tickerDivElements.length; i++ )
        {
            this[tickerDivElements[i]] = document.createElement( 'div'  );
        }
        
        for( var i = 0; i < tickerSpanElements.length; i++ )
        {
            this[tickerSpanElements[i]] = document.createElement( 'span' );
        }
        
        for( var i = 0; i < textNodeElements.length; i++ )
        {
            this[textNodeElements[i]].appendChild( document.createTextNode( "" ) );
        }
    }


    // -----------------------------------------------------------
    // drawTickerConstruction
    // -----------------------------------------------------------
    //
    // arguments:
    //      none
    //
    // description
    //      The construction of the ticker is very simply hirachical
    //	    joining of the tickercomponents. The last step is to add
    //	    the tickerControl (=> outest tickercontainer) to the body
    //	    of the browserpage
    //
    // return value(s):
    //	    void
    function drawTickerConstruction()
    {
        this.newsLine.appendChild( this.newsTeaser );
        this.newsLine.appendChild( this.newsLink );
        
        this.newsBlock.appendChild( this.newsLine );

        this.newsContentFrame.appendChild( this.newsHeadline );
        this.newsContentFrame.appendChild( this.newsBlock );
        this.newsContentFrame.appendChild( this.newsFoot );
        
        this.newsControl.appendChild( this.newsContentFrame );
        
	if( document.getElementById( "tickerParent" ) )
	{
	    document.getElementById( "tickerParent" ).appendChild( this.newsControl );
	}
	else
	{
            document.body.appendChild( this.newsControl );
	}
    }
    
    // -----------------------------------------------------------
    // fillHeader
    // -----------------------------------------------------------
    //
    // arguments:
    //      none
    //
    // description
    //      Replace the current headline-textnode through the
    //	    text stored inside the instance variable
    //
    // return value(s):
    //	    void
    function fillHeader() 
    {
        this.newsHeadline.replaceChild( document.createTextNode( this.headLineInfo ), this.newsHeadline.firstChild );
    }
    
    // -----------------------------------------------------------
    // fillFooter
    // -----------------------------------------------------------
    //
    // arguments:
    //      none
    //
    // description
    //      Replace the current foot-textnode through a new one
    //	    which holds the foot-info plus the current time
    //
    // return value(s):
    //	    void
    function fillFooter() 
    {
        var footString = this.footInfo + " " + this.lastLoad.getHours() + ":" + (( this.lastLoad.getMinutes() < 10 )? "0" + this.lastLoad.getMinutes():this.lastLoad.getMinutes());
        
        var newFoot = document.createTextNode( footString );
        
        this.newsFoot.replaceChild( newFoot, this.newsFoot.firstChild );
    }

    // -----------------------------------------------------------
    // processXML
    // -----------------------------------------------------------
    //
    // arguments:
    //      Object xmldocument ... the XML-Document-object
    //
    // description
    //      The heart of the XML-Ticker. It fetches all item-Nodes
    //	    from the given XML-Document and stores them for later
    //	    usage. After wards the footer is filled and turn around the
    //	    ignition key. At this stage work stops and fun starts
    //
    // return value(s):
    //	    void
    function processXML( xmldocument ) 
    {
        this.tickerItems = xmldocument.getElementsByTagName( 'item' );
        this.lastLoad = new Date();
        
        this.fillFooter();
        this.ignition();
    }
    
    // -----------------------------------------------------------
    // startTicker
    // -----------------------------------------------------------
    //
    // arguments:
    //      none
    //
    // description
    //      3,2,1 GO. Starting the ticker is as simply as this.
    //	    All work has been done the ticker is shown in the
    //	    browser window, there's nothing more to do than
    //	    adding the link to read more about the tickernews,
    //	    filling the header and fetching the XML-Document
    //
    // return value(s):
    //	    void
    function startTicker() 
    {
        this.newsLink.onclick = rdfTicker.showActiveUrl;
        this.newsLink.replaceChild( document.createTextNode( " " + this.linkInfo ), this.newsLink.firstChild )
        
        this.fillHeader();
        this.getAndProcessXMLDocument();
    }
    
    // -----------------------------------------------------------
    // ignition
    // -----------------------------------------------------------
    //
    // arguments:
    //      none
    //
    // description
    //      The xml-Document has arrived, and the tickeritems are
    //	    processed. Now it's time to present the whole world
    //	    our news. But we want to be up-to-date all the time.
    //	    Let's set a time out where we will look for a new-version
    //	    of our rdf-File simply by setting a timeout.
    //	    And one more time (=>Interval) is created which will loop us
    //	    though the ticker-items.
    //
    // return value(s):
    //	    void
    function ignition()
    {
        this.showNextItem();
        window.setTimeout( this.reloadXMLDoc, this.reloadTime );
        this.newsIntervalId = window.setInterval( this.showNextItem, this.newsDuration );
    }
    
    // -----------------------------------------------------------
    // showNextItem
    // -----------------------------------------------------------
    //
    // arguments:
    //      none
    //
    // description
    //      Simply calls the redraw-item function
    //
    // return value(s):
    //	    void
    function showNextItem() 
    {
        rdfTicker.redrawItem();
    }
    
    // -----------------------------------------------------------
    // redrawItem
    // -----------------------------------------------------------
    //
    // arguments:
    //      none
    //
    // description
    //      We redraw the item by selecting the appropiate redraw
    //	    method, defined by the actual value of the redrawType
    //
    // return value(s):
    //
    function redrawItem()
    {
        switch(this.redrawType)
        {
            case "FadeOut":
                this.redrawByFadeOut();
                break;
            default: 
                this.redrawByReplace();
                break;
        }
    }
    
    // -----------------------------------------------------------
    // redrawByFadeOut
    // -----------------------------------------------------------
    //
    // arguments:
    //      none
    //
    // description
    //      NOT IMPLEMENTED AT THE MOMENT
    //
    // return value(s):
    //	    void
    function redrawByFadeOut()
    {
        var nextItem = this.nextItem();
        
        //alert( this.newsLine.style.width );
        
        //this.newsLine.style.width = 60;
        
    }

    // -----------------------------------------------------------
    // redrawByReplace
    // -----------------------------------------------------------
    //
    // arguments:
    //      none
    //
    // description
    //      Pruistic but very effective. Redraws the item by simply
    //	    replace the old-node through the new one
    //
    // return value(s):
    //	    void
    function redrawByReplace()
    {
        var nextItem = this.nextItem();
        this.teaserText = this.tickerItems[nextItem].getElementsByTagName( 'title' )[0].firstChild.nodeValue;
        this.teaserLink = this.tickerItems[nextItem].getElementsByTagName( 'link' )[0].firstChild.nodeValue;

        this.newsTeaser.replaceChild( document.createTextNode( this.teaserText ), this.newsTeaser.firstChild );


    }

    // -----------------------------------------------------------
    // nextItem
    // -----------------------------------------------------------
    //
    // arguments:
    //      none
    //
    // description
    //      Selected the next item in the list and returns it
    //
    // return value(s):
    //	    Int this.activeItem ... the active ItemId
    function nextItem()
    {
        this.activeItem++;
        
        if( this.activeItem >= this.tickerItems.length )
        {
            this.activeItem = 0;
        }
        
        return this.activeItem;
    }

    // -----------------------------------------------------------
    // reloadXMLDoc
    // -----------------------------------------------------------
    //
    // arguments:
    //      none
    //
    // description
    //      Stops the Intervaltimer, replaces the foot-node to inform
    //	    the user that the xml-document is reloaded and start the
    //	    reload process
    //
    // return value(s):
    //
    function reloadXMLDoc()
    {
        window.clearInterval( rdfTicker.newsIntervalId );
        rdfTicker.newsFoot.replaceChild( document.createTextNode( rdfTicker.loadInfo ), rdfTicker.newsFoot.firstChild );
        rdfTicker.getAndProcessXMLDocument();
    }
    
    // -----------------------------------------------------------
    // showActiveUrl
    // -----------------------------------------------------------
    //
    // arguments:
    //      none
    //
    // description
    //      Well that's why we did all this things. The user clicked
    //	    on the link. Let's display the complete article
    //
    // return value(s):
    //	    void
    function showActiveUrl()
    {
        location.href = rdfTicker.teaserLink;
    }
    
    // -----------------------------------------------------------
    // These are the only method who need a browser specific
    // implementation because the differ too much
    // -----------------------------------------------------------
    function applyStyleClasses() {}
    function getAndProcessXMLDocument() {}
}


// -----------------------------------------------------------
// loadTicker
// -----------------------------------------------------------
//
// arguments:
//      none
//
// description
//      That's where magic starts and logic ends. We are loading
//  	the browser-specific class on the fly.
//
// return value(s):
//
function loadTicker()
{
    var ticker;
    var browserSpecificScript;

    var isOpera = ( navigator.userAgent.search( "Opera" ) == -1 )?false:true;
    
    if( navigator.appName == "Netscape" && document.getElementById && ! isOpera )
    {
        browserSpecificScript = document.createElement( "script" );
        browserSpecificScript.setAttribute( "src", "/javascript/rdf_tickerNN.js" );
        document.body.appendChild( browserSpecificScript );
    }
    else if ( navigator.appName == "Microsoft Internet Explorer" && document.getElementById && ! isOpera )
    {
        browserSpecificScript = document.createElement( "script" );
        browserSpecificScript.setAttribute( "src", "/javascript/rdf_tickerIE.js" );
        document.body.appendChild( browserSpecificScript );
    }
    else
    {
        //alert( "unknow browser" );
    }
    
}

// -----------------------------------------------------------
// Storing some user-defined values in a more practical 
// type
// -----------------------------------------------------------

var parameters = new Array();
parameters["loadInfo"]      = window.LOAD_INFO;
parameters["linkInfo"]      = window.LINK_INFO;
parameters["headLineInfo"]  = window.HEADLINE_INFO;
parameters["footInfo"]      = window.FOOT_INFO;
parameters["xmlfile"]       = window.XMLFILE;


// ------------------------------------------------------------
// $Source: /usr/bestsolution/cvsroot/web/fides/src/htdocs/javascript/rdf_ticker.js,v $
// $Revision: 1.2 $
// $State: Exp $
// locked by $Locker:  $
// checked out with tagname $Name:  $
// 
// last modified $Date: 2003-01-31 09:25:15 $ by $Author: heli $
// ------------------------------------------------------------
