/**
 * Browser Check:
 *
 *  Name                    - text/html   - application/xhtml+xml
 * ---------------------------------------------------------------------
 *  Firefox 1.5             - pass        - pass
 *  Firefox 2.0             - pass        - pass
 *  Internet Explorer 6.0   - pass        - failed [xhtml]
 *  Netscape 7.2            - pass        - failed [innerHTML]
 *  Netscape 8.1            - pass        - failed [innerHTML]
 *  Netscape 9.0            - pass        - pass
 *  Opera 7.5               - pass        - pass
 *  Opera 8.5               - pass        - pass
 *  Opera 9.2               - pass        - pass
 *  Safari 3.0              - pass        - pass
 */


//
// NAMEN
//

//-- ID des Tickerraumes
var cfgDivName   = 'ticker';

//-- ID des Tickertextes
var cfgSpanName  = 'tickertext';

//-- CSS Klassenname der News Hyperlinks
var cfgCssName   = 'news';

//
// CONFIGURATION
//

//-- Die einzelnen cfgNews Elemente(kann HTML Code enthalten!)
//var cfgNews       = new Array();      //wird extern definiert
//cfgNews[ 0 ]       = new News("Haben Sie schon eimal darüber nachgedacht, Ihre Website mit einem Validator zu prüfen?","http://www.validome.org/");

//-- Trennzeichen zwischen den einzelnen cfgNews des Arrays
var cfgSeparator  = ' <span style="font-family:Courier,monospace;font-weight:bold;">+++</span> ';

//-- cfgInterval in MilliSekunden
var cfgInterval   = 50;

//-- Verschiebung printervalHandle Interval in Pixel
var cfgRange      = 1;

//-- Beim MouseOver den Text anhalten/verlangsamen?
//  0   --> nicht anhalten
//  1   --> anhalten
//  2   --> Geschwindigkeit um diesen Faktor verringern
//  3   --> Geschwindigkeit um diesen Faktor verringern
// ...  --> Geschwindigkeit um diesen Faktor verringern
var cfgMode       = 3;

//-- Wird an die News angehängt, falls diese die definierte Wortanzahl überschritten wird
var cfgAppend     = '...';

//-- Nach wie vielen Wörtern des News soll durch cfgAppend abgekürzt werden
//  0   --> nicht abschneiden
//  1   --> Nach einem Wort abschneiden
//  2   --> Nach zwei Wörtern abschneiden
//  3   --> Nach drei Wörtern abschneiden
// ...  --> Nach X Wörtern abschneiden
var cfgCutoff     = 8;

//-- Schreibt bei jedem Interval Aufruf die Aktuelle Position in das
//   Cookie. ACHTUNG. Aus Performance technischen Gründen sollte die
//   Funktion ERST beim verlassen der Seite und NICHT regelmäßig
//   aufgerufen werden
//  0   --> Keine Cookies verwenden
//  1   --> Cookies automatisch schreiben
var cfgAutoCookie = 0;


// --<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--


// >- Zugriff auf das SPAN Element tickertext
var tt;

// >- Zugriff auf das DIV Element, welches das SPAN Element umschliesst
var t;

// >- Die errechnete Ticker-Text-Breite
var txtWidth;

// >- Die Breite des DIV Elementes
var tickerWidth;

// >- Enthält die Referenz auf das begonnene Interval
var intervalHandle;

// >- Aktuelle Position des SPAN Elementes
var pos;


// --<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--


/**
 * Struktur, welche die einzelnen News aufnimmt
 * @param text Der News Text
 * @param link Der Hyperlink, welcher aufgerufen werden soll, wenn auf
 * die News Zeile geklickt wird
 *
function News( text, link )
{
    this.text = text;
    this.link = link;
}*/


// --<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--


/**
 * Generischer DOM Accessor
 * @param id Die ID des HTML Elementes, welcher benoetigt wird
 * @return Die Instanz des HTML Elementes
 *
function _id( id )
{
    if( document.getElementById )
        return document.getElementById( id );
    else if( document.all )
        return document.all.id;
    else if( document.layers )
        return document.layers[ id ];
}*/

/**
 * Öffnet ein neues Fenster. Equivalent zu target=_blank, aber XHTML
 * kompatibel!
 * @param string Die URL der Zieldatei
 * @param string Name des Fensters zur weiteren Verwendung
 * @return object Das "Handle" des Fensters
 *
 *
function openWin( url, name )
{
    width = screen.width - 100;
    height = screen.height - 100;
    params = 'width=' + width + ',height=' + height;

    params += ',left=' + ( (screen.availWidth - width ) / 2 );
    params += ',top=' + ( screen.availHeight - height ) / 2;

    params += ',location=1,menubar=1,toolbar=1,status=1,scrollbars=1';

    win = window.open( url, name, params );
    win.focus();

    return win;
}*/


// --<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--


/**
 * Formatiert den News String. Falls das Kürzen der News gewünscht ist,
 * werden die News nach cfgCutoff Wörtern abgeschnitten und es wird
 * cfgAppend angehängt
 * @param str Der zu kürzende String
 * @return Der (gegebenenfalls) gekürzte/formatierte String
 */
function cut( str )
{
    var spaceCounter = -1, i = 0, c = '', inHTML = 0;

    if( cfgCutoff > 0 )
    {
        spaceCounter = 0;
        for( ; i < str.length ; i = i + 1 )
        {
            c = str.charAt( i );

            if( inHTML == 0 && c == ' ' )
                spaceCounter = spaceCounter + 1;
            /* In HTML Tags keine Leerzeichen zählen, erst wieder
             * weiter zählen, wenn das Tag geschlossen wurde
             */
            else if( c == '<' )
                inHTML = inHTML + 1;
            else if( c == '>' )
                inHTML = inHTML - 1;

            /* Abbrechen, wenn die Wortanzahl erreicht ist */
            if( spaceCounter == cfgCutoff )
                break;
        }
    }

    if( spaceCounter == cfgCutoff )
        return str.substring( 0, i ) + cfgAppend;
    else
        return str + cfgAppend;
}

/**
 * Verkettet die einzelnen News. Dabei werden, sofern in der Struktur
 * definiert, die Hyperlinks erstellt und die News Zeile formatiert
 * @return Der generierte String
 */
function joinNews()
{
    var str = cfgSeparator;

    for( var i = 0 ; i < cfgNews.length ; i = i + 1 )
    {
        if( cfgNews[ i ].link.length > 1 )
        {
            str += '<a href="#" onclick="writeCookie();newsWin();" class="' + cfgCssName + '">';
        }
        str += cut( cfgNews[ i ].text );
        if( cfgNews[ i ].link.length > 1 )
        {
            str += '</a>';
        }
        str += cfgSeparator
    }

    return str;
}

/**
 * Prueft, ob die benötigten JavaScript Funktionen vom Client unter-
 * stützt werden
 * @return Werden die Funktionen unterstützt
 */
function selfCheck()
{
    var check = window.setInterval ? 1 : 0;
    check = check && window.clearInterval ? 1 : 0;
    check = check &&(document.all||document.getElementById||document.layers) ? 1 : 0;
    return check;
}


// --<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--


/**
 * Versucht, die aktuelle Ticker Position aus dem Cookie auszulesen
 * @return Der gelesene oder der Default Wert
 */
function readCookie ()
{
    var str = document.cookie;

    var def = tt.style.right == '' ? (tickerWidth * -1) : parseInt( tt.style.right )

    if( typeof RegExp == 'function' )
    {
        var chk = /POS=-?\d+/;
        if( !chk.test( str ) )
        {
            return def;
        }
    }
    else if( str.indexOf( 'POS=' ) != 0 )
    {
        return def;
    }

    str = str.substr( 4, str.length - 4 );
    return parseInt( str );
}

/**
 * Speichert die aktuelle Ticker Position in einem Session Cookie
 */
function writeCookie ()
{
    var expires = new Date();
    expires.setTime(expires.getTime() + 1000 * 60 * 60);

    document.cookie = 'POS=' + parseInt( pos ) + '; expires='+expires.toGMTString()+'; path=/';
}


// --<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--<|>--


/**
 * Initialisiert den Ticker und ruft danach start() auf
 */
function init()
{

    /* Selbsttest */
    if( !selfCheck() )
        return;

    var txt = joinNews();

    /* Referenz auf die HTML Elemente speichern */
    t   = _id( cfgDivName );
    tickerWidth = t.offsetWidth;

    tt  = _id( cfgSpanName );
    tt.innerHTML = txt;
    txtWidth = tt.offsetWidth;

    /* Aktuelle Position herausfinden */
    pos = readCookie ();
    tt.style.right = pos + 'px';

    /* Ticker starten */
    start( true );
}

/**
 * Startet das Ticker Interval
 * @param ignore Sperre ignorieren
 */
function start( ignore )
{
    if( cfgMode == 0 && !ignore )
        return;
    // > 1 bedeutet Verlangsamung, daher muss dieses Interval zuerst
    // aufgehoben werden, bevor das neue gesetzt werden kann
    if( cfgMode > 1 )
        window.clearInterval( intervalHandle );
    intervalHandle = window.setInterval( 'move()', cfgInterval );
}

/**
 * cfgStoppt das Ticker Interval
 */
function stop()
{
    if( cfgMode == 0 )
        return;
    window.clearInterval( intervalHandle );
    // > 1 bedeutet Verlangsamung, daher muss das verlangsamte Interval
    // nach dem stoppen gestartet werden
    if( cfgMode > 1 )
        intervalHandle = window.setInterval( 'move()', cfgInterval * cfgMode );
}

/**
 * Verschiebt den Tickertext
 */
function move()
{
    pos   = pos + cfgRange;

    // Prüfen, ob wir noch im sichtbaren Bereich sind
    if( pos > txtWidth )
        pos =(tickerWidth * -1);

    if( cfgAutoCookie == 1 )
        writeCookie ();

    // Verschieben
    tt.style.right = pos + 'px';
}