/**
 * @fileoverview  Süddeutsche Zeitung JavaScript core
 *
 * @author      Murat Purc <m.purc@edelweiss72.de>
 * @date        xx.01.2008
 * @package     Süddeutsche
 * @subpackage  JavaScript-Core
 */


/**
 * Namespacing and some properties
 * @namespace  sz
 */
var sz = {

    /**
     * User agent string (lowercase)
     * @type  {string}
     */
    ua: navigator.userAgent.toLowerCase(),

    /**
     * Flag about DOM support
     * @type  {bool}
     */
    bDOM: (document.getElementById && document.createTextNode),

    /**
     * Path to blind gif image
     * @type  {string}
     */
    sPixGif: "img/shim.gif"
};

/**
 * Is client a IE
 * @type  {bool}
 */
sz.isIE = (sz.ua.indexOf("msie") > -1 && sz.ua.indexOf("opera") == -1);

/**
 * Is client a IE < 7
 * @type  {bool}
 */
sz.isIElower7 = (sz.isIE && (sz.ua.indexOf("msie 5.") > -1 || sz.ua.indexOf("msie 6.") > -1));

/**
 * Does the client running on a Linux OS
 * @type  {bool}
 */
sz.isLinuxOS = (sz.ua.indexOf("linux") > -1 || sz.ua.indexOf("ubuntu") > -1);



/**
 * Writes more anchors using document.writeln()...
 *
 * @param  {string}  dest   Reference destination
 * @param  {string}  text   Text for anchor
 * @param  {string}  title  Text for title attribute
 * @param  {string}  class  Additional class name, optional
 */
sz.more = function(dest, text, title, classAttr){
    if (!title) {
        title = "";
    }

    classAttr = (!classAttr) ? "" : " " + classAttr;

    document.writeln('<a href="' + dest + '" class="more' + classAttr + '" title="' + title + '">' + text + '</a>');
}


/**
 * Toggles the visibility state between header navigation area and header login area
 */
sz.toggleLoginBox = function(){
    if (!this.bDOM) {
        return;
    }
    if (Element.getStyle("logfield", "display") == "none") {
        Element.setStyle("logout", { display: "none" });
        Element.setStyle("logfield", { display: "block" });
    } else {
        Element.setStyle("logfield", { display: "none" });
        Element.setStyle("logout", { display: "block" });
    }
}


// #################################################################################################

/**
 * Google functions related class.
 *
 * @class  sz.Google
 */
sz.Google = {

    /**
     * Handles google search, opens the search in a new window if running on web mode
     */
    getSearch: function(){
        if (!sz.bDOM) {
            return true;
        }

        var modi = 'archiv';
        for (var i = 0; i <= document.googleSearch.radiosearch.length; i++) {
            if (document.googleSearch.radiosearch[i].checked == true) {
                modi = document.googleSearch.radiosearch[i].value;
                break;
            }
        }
        if (modi == 'web') {
            var url = 'http://www.sueddeutsche.de/app/google/suche/index.html?q=' + escape(document.googleSearch.inputsearch.value)
                    + '&sa=Google-Suche&client=pub-8726208069393245&forid=1&channel=8700697642&ie=ISO-8859-1&oe=ISO-8859-1&'
                    + 'cof=GALT%3A%23003399%3BGL%3A1%3BDIV%3A%239E9898%3BVLC%3A003399%3BAH%3Acenter%3BBGC%3AFFFFFF%3BLBGC%3A336699'
                    + '%3BALC%3A000000%3BLC%3A000000%3BT%3A000000%3BGFNT%3A003399%3BGIMP%3A003399%3BFORID%3A11&hl=de&back=startsite';

            sz.newWindow(url, 'google', 800, 600, 1, 1, 1, 1, 1, 1, 1);
            return false;
        }
    },


    /**
     * Toggles google background image of searchfield.
     *
     * @param  {int}  show  Flag to display google background image ('1' or '0')
     */
    imageStatus: function(show) {
        if (show == '1') {
            Element.setStyle("inputsearch", { backgroundImage: "url(http://www.sueddeutsche.de/app/google/img/google_wasserzeichen.gif)" });
        }
        else {
            Element.setStyle("inputsearch", { backgroundImage: "none" });
        }
    }
}


// #################################################################################################


/**
 * Base formular handling class
 *
 * @class  sz.BaseForm
 */
sz.BaseForm = Class.create({

    /**
     * Sets the value of an element
     *
     * @param  {mixed}  elem      Id of element or element objevt itself
     * @param  {mixed}  newValue  New value to set
     */
    setValue: function(elem, newValue) {
        elem = this._getElement(elem);
        if (elem) {
            elem.value = newValue;
        }
    },


    /**
     * Sets default value of an element, if its stripped content is empty
     *
     * @param  {mixed}  elem      Id of element or element objevt itself
     * @param  {mixed}  defValue  Default value
     */
    setDefaultValue: function(elem, defValue) {
        elem = this._getElement(elem);
        if (elem && elem.value.strip() == "") {
            elem.value = defValue;
        }
    },


    /**
     * Deletes value of an element, if its content equals the "checkValue"
     *
     * @param  {mixed}  elem        Id of element or element objevt itself
     * @param  {mixed}  checkValue  Value to check
     */
    setEmptyValue: function(elem, checkValue) {
        elem = this._getElement(elem);
        if (elem && elem.value.strip() == checkValue) {
            elem.value = "";
        }
    },


    /**
     * Wrapper to access to elements using id or elementobject itself
     *
     * @param  {mixed}   elem  Id of element or element objevt itself
     * @param  {object}  The element object or null
     * @private
     */
    _getElement: function(elem) {
        if (typeof(elem) == "String") {
            elem = $(elem);
        }
        return (elem) ? elem : null;
    }

});


/**
 * Loginformular handling class.
 *
 * @extends  sz.BaseForm
 * @class    sz.LoginBox
 */
sz.LoginBox = Class.create(sz.BaseForm, {

    /**
     * Function to call on onFocus-event.
     * Hides default textfield and displays passwordfield.
     */
    onGetFocus: function(){
        Element.setStyle("passtxt", { display: "none" });
        Element.setStyle("login_passwort", { display: "inline" });
        $("login_passwort").focus();
    },

    /**
     * Function to call on onBlur-event.
     * Hides passwordfield and displays default textfield.
     */
    onLostFocus: function(){
        if($("login_passwort").value == '') {
            Element.setStyle("passtxt", { display: "inline" });
            Element.setStyle("login_passwort", { display: "none" });
        }
    }

});


/**
 * Instance of sz.LoginBox class
 * @type  {sz.LoginBox}
 */
var szLoginBox = new sz.LoginBox();



// #################################################################################################
// teaser mit Reiternavigation

/**
 * Tabbed teaser header. Used to switch tabbed elements inside a teaser. Changes header
 * class name, switches content by hiding previous and displaying new element content.
 *
 * Usage:
 * -----
 * <code>
 * <script>
 * oTTH = new sz.TabbedTeaserHeader("listId", "activeelementid");
 * </script>
 * <div id="headerA"><a href="#" onmouseover="oTTH.show('headerA');">Activate me</a></div>
 * <div id="headerB"><a href="#" onmouseover="oTTH.show('headerB');">or me</a></div>
 * </code>
 *
 * @param  {string}  listId  Id of list which holds the tabbed teaser
 * @param  {string}  activeElement  Id of element witch is the initial one
 * @class  sz.TabbedTeaserHeader
 */
sz.TabbedTeaserHeader = function (listId, activeElement) {
    this.listId        = listId;
    this.activeElement = activeElement;
    this.ok            = false;
    if (!sz.bDOM) {
        return;
    }

    var elem = $(this.listId);
    if (!elem){ return; }

    this.list = elem.getElementsByTagName("li");
    if (!this.list){ return; }

    this.ok = true;
}


/**
 * Switch to tab based on passed key.
 *
 * @param  {string}  key  Key of element to activate
 */
sz.TabbedTeaserHeader.prototype.show = function(key){
    if (!this.ok) {
        return;
    }

    if (key == this.activeElement) {
        // passed key is allready active, get out here
        return;
    }

    if (this.activeElement !== "") {
        // hide previous displayed element
        $(this.activeElement).style.display = "none";
    }

    // set active key, display new element and change classname
    // formatting definitions are set by different class selectors
    this.activeElement = key;
    $(this.activeElement).style.display = "block";

    // reset other list item
    for (var i=0; i < this.list.length; i++) {
        if (this.list[i].className == "first-active") {
            this.list[i].className = "first";
        } else if (this.list[i].className == "middle-active") {
            this.list[i].className = "middle";
        } else if (this.list[i].className == "last-active") {
            this.list[i].className = "last";
        }
    }

    // activate actual list item
    var item = $(key+"-item");
    if (item.className == "first") {
        item.className = "first-active";
    } else if (item.className == "middle") {
        item.className = "middle-active";
    } else if (item.className == "last") {
        item.className = "last-active";
    }

}


// #################################################################################################


/**
 * Static topic of the week gallery handler
 *
 * @class  sz.TOTWGallery
 */
sz.TOTWGallery = {

    /**
     * Topic of the week box element
     * @type  {object}
     */
    oTopic: null,

    /**
     * Number of topic of the week images
     * @type  {int}
     */
    numImages: null,

    /**
     * Identifier of actual image
     * @type  {string}
     */
    actImageId: "",

    /**
     * Position of initial "Topic of the week" theme
     * @type  {int}
     */
    pos: 1,

    /**
     * Path to image directoy which includes thes images
     * @type  {string}
     */
    imgDir: "./img/_test/thema/",

    /**
     * Delay in miliseconds used to change to the next theme
     * @type  {int}
     */
    delay: 4000,

    /**
     * Return value of window.setTimeout
     * @type  {int}
     */
    timeoutId: null,

    /**
     * Flag about successfull initialization
     * @type  {bool}
     */
    initialized: false,


    init: function() {
        if (!sz.bDOM) {
            return;
        }

        // get gallery list items
        if (!$("topicoftheweek-photoshow")) {
            return;
        }
        var items = $("topicoftheweek-photoshow").getElementsByTagName("li");
        if (!items) {
            return;
        }

        this.numImages = items.length;
        var elem, arr;
        for (var i=1; i<=items.length; i++) {
            if ($("topicoftheweek-link:" + i)) {
                elem = $("topicoftheweek-link:" + i);
                elem.onmouseover = function () {
                    var arr = this.id.split(":");
                    sz.TOTWGallery.show(arr[1]);
                }
                elem.onmouseout = function () {
                    var arr = this.id.split(":");
                    sz.TOTWGallery.setImgOutState("topicoftheweek-thumb:" + arr[1]);
                }
                elem.onclick = function () {
                    var arr = this.id.split(":");
                    sz.TOTWGallery.show(arr[1]);
                }

                // now hide image (because of you: ie<7))
                if (i > 1) {
                    sz.TOTWGallery.setImgOutState("topicoftheweek-thumb:" + i);
                }
            }
        }

        this.oTopic = $("topicoftheweek-box");
        this.initialized = true;
        this._showTopic();

    },

    setImgOverState: function (imgId) {
        if (Element.getStyle($(imgId), "display") != "block") {
            Element.setStyle($(imgId), { height: "53px", width: "53px", display: "block" });
        }
    },

    setImgOutState: function (imgId) {
        if (imgId == this.actImageId) { return; }
        Element.setStyle($(imgId), { height: "1px", width: "1px", display: "none" });
    },

    showNext: function () {
        if (++this.pos > this.numImages) {
            this.pos = 1;
        }
        this._showTopic();
    },

    show: function (pos) {
        if (pos < 1) {
            this.pos = 1;
        } else if (pos > this.numImages) {
            this.pos = this.numImages;
        } else {
            this.pos = pos;
        }
        this.clearTimer();
        this._showTopic();
    },

    setTimer: function () {
        this.timeoutId = window.setTimeout("sz.TOTWGallery.showNext()", this.delay);
    },

    clearTimer: function () {
        if (this.timeoutId !== null) {
            window.clearTimeout(this.timeoutId);
            this.timeoutId = null;
        }
    },

    _showTopic: function() {
        if (!this.initialized) { return; }

        var newTopic = $("topicoftheweek-coll-"+this.pos);
        if (!newTopic) {
            return;
        }

        // handle image over out states
        if (this.actImageId != "") {
            // reset previous over state
            var imgId = $(this.actImageId);
            this.actImageId = "";
            this.setImgOutState(imgId);
        }

        this.actImageId = "topicoftheweek-thumb:" + this.pos;
        // set image over state of actual topic
        this.setImgOverState(this.actImageId);

        // set new topic
        this.oTopic.innerHTML = newTopic.innerHTML;

        this.setTimer();
    }

}


Event.observe(window, "load", function(){
    /**
     * Aufruf der Funktion sz.TOTWGallery.init() bei onload
     */
    sz.TOTWGallery.init();
});


// #################################################################################################


/**
 * Static photoshow handler.
 *
 * @class  sz.photoShow
 */
sz.photoShow = {

    /**
     * Response success state
     * @type  {int}
     */
    RESPONSE_SUCCESS: 1,

    /**
     * Response warning state
     * @type  {int}
     */
    RESPONSE_WARNING: 2,

    /**
     * Response error state
     * @type  {int}
     */
    RESPONSE_ERROR: 3,

    /**
     * Width of content container containing the image element
     * @type  {int}
     */
    iContentWidth: 459,

    /**
     * Height of previous/next image
     * @type  {int}
     */
    iPrevNextImageHeight: 79,

    /**
     * Width of previous/next image
     * @type  {int}
     */
    iPrevNextImageWidth: 24,

    /**
     * Actual position iside the photo show
     * @type  {int}
     */
    iPos: 0,

    /**
     * Number of avilable photos
     * @type  {int}
     */
    iNum: 0,


    /**
     * Main method to initialize photoshow.
     *
     * @param  array  aImages Array of images objects
     */
    init: function() {
        if (!sz.bDOM) {
            return;
        }
        this.iPos = 1;
        this.iNum = 1;
        if ($("dynps-image")) {
            this._layerRepositioning();
        }
    },


    /**
     * Shows the next image. Will start from beginning, if the end of photoshow is reached
     */
    next: function() {
        this.show(this.iPos+1);
    },


    /**
     * Shows the previous image. Will start from end, if the begin of photoshow is reached
     */
    previous: function() {
        this.show(this.iPos-1);
    },


    /**
     * Shows the image at desired position, if it is between start and end of photoshow.
     * Calls several methods to perform the job.
     *
     * @param  {int}  pos  Position of image
     */
    show: function(pos) {
        if (pos != this.iPos) {
            this.iPos = pos;
            this._showImage();
        }
    },


    /**
     * Main method, which shows the image.
     *
     * @param   {int}  pos  Position of image
     * @private
     */
    _showImage: function(pos){
        if (!$("dynps-image")) {
            return false;
        }

        console.log('sz.photoShow._showImage: request for image:', this.iPos);

        new Ajax.Request('ajax_proxy.php', {
            method:     'post',
            parameters: {action: "getphoto", number:sz.photoShow.iPos},
            onSuccess:  function(transport){

                /**
                 * prepare and check response
                 * returned object contains following structure:
                 * - res.status   {int}     response status code (sz.photoShow.RESPONSE_* consts)
                 * - res.message  {string}  could contain a message, e. g. server sider error message or warning
                 * - res.debug    {string}  could contain any debug messages
                 * - res.result   {object}  the main result, containing image data in this case
                 */
                var res = transport.responseText.evalJSON(true);
                console.log('sz.photoShow._showImage: response message:', res.message)
                if (!res.status || res.status !== sz.photoShow.RESPONSE_SUCCESS) {
                    return;
                }

                // set image data
                img = res.result;
                sz.photoShow.iNum = img.numphotos;

                // update image element
                $("dynps-image").src = sz.sPixGif;
                $("dynps-image").width = img.width;
                $("dynps-image").height = img.height;
                $("dynps-image").src = img.src;
                $("dynps-image").alt = (img.alt) ? img.alt : "";
                $("dynps-image").title = (img.title) ? img.title : "";

                if ($("dynps-img-descr")) {
                    // update image description
                    $("dynps-img-descr").innerHTML = (img.descr) ? img.descr : "";
                }

                // update actual position
                if (sz.photoShow.iPos > sz.photoShow.iNum) {
                    sz.photoShow.iPos = 1;
                } else if (sz.photoShow.iPos == 0) {
                    sz.photoShow.iPos = sz.photoShow.iNum;
                }

                // update pager and call repositioning of prev/next layer
                sz.photoShow._updatePager();
                sz.photoShow._layerRepositioning();

            },
            onFailure: function(){
                // hmm, we should not land here
                console.error('sz.photoShow._showImage: Something went wrong...');
            }
        });

        return true;
    },


    /**
     * Composes the pager navigation and updates the element which includes the navigation.
     *
     * @private
     */
    _updatePager: function(){
        if (!$("dynps-nav-items")) {
            return;
        }

        var elem = $("dynps-nav-items").getElementsByTagName("a");
        if (!elem) {
            return;
        }

        console.log('_updatePager: this.iPos:', this.iPos);
        for (var i=0; i<elem.length; i++) {
            if (i == (this.iPos-1)) {
                Element.addClassName(elem[i], "act");
            } else if(Element.hasClassName(elem[i], "act")) {
                Element.removeClassName(elem[i], "act");
            }
        }
    },


    /**
     * Handles the repositioning of previous, next layer. Calculates new dimensions, spaces
     * and positions of the layer and sets them overwriting styles.
     *
     * @private
     */
    _layerRepositioning: function(){

        var height = $("dynps-image").height;
        var width  = $("dynps-image").width;
        var iTopSpace = 0;
        var iTotalHeight = height;

        var iImgTopSpace = Math.ceil((height / 2) - (this.iPrevNextImageHeight / 2));

        Element.setStyle("dynps-img-box-wrap", {paddingTop: iTopSpace + "px", height: iTotalHeight + "px" });

        // set top margin of main image box, used to center images vertically
        Element.setStyle("dynps-img-box", {height: iTotalHeight + "px"});

        // set styles of previous layer
        iWidth = Math.ceil(width / 4);
        iLeft  = (Prototype.Browser.IE) ? 0 : Math.ceil((this.iContentWidth - width) / 2);
        Element.setStyle("dynps-img-prev-layer", {
            backgroundPosition: "10px " + iImgTopSpace + "px",
            width:  iWidth + "px",
            height: height + "px",
            left:   iLeft + "px"
        });
        Element.setStyle("dynps-img-prev-img", {
            width:  iWidth + "px",
            height: height + "px"
        });

        // set styles of next layer
        iWidth = Math.ceil((width / 4) * 3);
        iLeft  = (Prototype.Browser.IE) ? (width / 4) : iLeft + (width / 4);
        iLeft  = Math.ceil(iLeft);
        iBgPos = Math.ceil((iWidth - this.iPrevNextImageWidth - 10));
        Element.setStyle("dynps-img-next-layer", {
            backgroundPosition: iBgPos + "px " + iImgTopSpace + "px",
            width:  iWidth + "px",
            left:   iLeft + "px",
            height: height + "px"
        });
        Element.setStyle("dynps-img-next-img", {
            width:  iWidth + "px",
            height: height + "px"
        });
    }

}

// #################################################################################################


/**
 * Class which provides a crossbrowser flash plugin check.
 *
 * The minimum required flash version ist 7.0.14 at the moment.
 *
 * @class  sz.FlashCheck
 */
sz.FlashCheck = {

    /**
     * Default major version
     * @type  {int}
     */
    reqMajorVer: 7,

    /**
     * Default minor version
     * @type  {int}
     */
    reqMinorVer: 0,

    /**
     * Default revision version
     * @type  {int}
     */
    reqRevision: 14,

    /**
     * Flag about checked state
     * @type  {bool}
     */
    checked: false,

    /**
     * Does the client complies with the requirements?
     * @type  {bool}
     */
    requirementsOk: false,


    /**
     * Main function to check for existing flash plugin. Parameter are optional, the default
     * settings will be used, if they were not passed.
     *
     * @param  {int}  mayor     Major version (optional)
     * @param  {int}  minor     Minor version (optional)
     * @param  {int}  revision  Revision (optional)
     */
    check: function(mayor, minor, revision) {
        if (typeof(mayor) !== "undefined") {
            this.reqMajorVer = mayor;
        }
        if (typeof(minor) !== "undefined") {
            this.reqMinorVer = minor;
        }
        if (typeof(revision) !== "undefined") {
            this.reqRevision = revision;
        }

        if (this.checked) {
            return this.requirementsOk;
        }
        var res = this._initSwfVersionScript();
        this.checked = true;
        return this.requirementsOk;
    },


    /**
     * Writes crossbrowser (ie & other) script code to detect installed flash version and
     * calls the flash version detection.
     *
     * @private
     */
    _initSwfVersionScript: function () {
        if (!sz.bDOM) {
            return;
        } else if ($("swfversionscript")) {
            return;
        }

        var isIE    = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
        var isWin   = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
        var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;

        if (isIE && isWin && !isOpera) {

            // flash detection code 4 ie

            document.write('<scr'+'ipt id="swfversionscript" type="text/vbscript">\n');
            document.write('Function szWhichFlash(i)\n');
            document.write('on error resume next\n');
            document.write('Dim swControl, swVersion\n');
            document.write('swVersion = 0\n');
            document.write('set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i))\n');
            document.write('if (IsObject(swControl)) then\n');
            document.write('swVersion = swControl.GetVariable("$version")\n');
            document.write('end if\n');
            document.write('szWhichFlash = swVersion\n');
            document.write('End Function\n');
            document.write('<\/scr'+'ipt>\n');
            document.write('\n');
        } else {

            // flash detection code 4 other browser

            document.write('<scr'+'ipt id="swfversionscript" type="text/javascript">\n');
            document.write('function szWhichFlash(i)\n');
            document.write('{\n');
            document.write('if (navigator.plugins != null && navigator.plugins.length > 0) {\n');
            document.write('if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {\n');
            document.write('var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";\n');
            document.write('var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;\n');
            document.write('descArray = flashDescription.split(" ");\n');
            document.write('tempArrayMajor = descArray[2].split(".");\n');
            document.write('versionMajor = tempArrayMajor[0];\n');
            document.write('versionMinor = tempArrayMajor[1];\n');
            document.write('if ( descArray[3] != "" ) {tempArrayMinor = descArray[3].split("r");} else {tempArrayMinor = descArray[4].split("r");}\n');
            document.write('versionRevision=tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;\n');
            document.write('// variable flashVer zusammensetzen -> analog zu ie\n');
            document.write('flashVer="x " + versionMajor + "," + versionMinor + "," + versionRevision;\n');
            document.write('}else{flashVer=-1;}\n');
            document.write('}\n');
            document.write('// MSN/WebTV 2.6 supports Flash 4\n');
            document.write('else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;\n');
            document.write('// WebTV 2.5 supports Flash 3\n');
            document.write('else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;\n');
            document.write('// older WebTV supports Flash 2\n');
            document.write('else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;\n');
            document.write('// Can\'t detect in all other cases\n');
            document.write('else {flashVer = -1;}\n');
            document.write('return flashVer;\n');
            document.write('}\n');
            document.write('<\/scr'+'ipt>\n');
            document.write('\n');
        }

        // now call detection
        this.requirementsOk = this._detectRequiredVersion(
            this.reqMajorVer, this.reqMinorVer, this.reqRevision
        );

        return this.requirementsOk;
    },


    /**
     * Flash detection method.
     *
     * Calls flash detection method beeing dynmically written before
     * (@see sz.FlashCheck._initSwfVersionScript()) and checks the version ogf found
     * plugin against required version.
     *
     * @param  {int}  reqMajorVer  Major version
     * @param  {int}  reqMinorVer  Minor version
     * @param  {int}  reqRevision  Revision
     * @private
     */
    _detectRequiredVersion: function (reqMajorVer, reqMinorVer, reqRevision) {
        if (!sz.bDOM) {
            return;
        }

        var reqVer = parseFloat(reqMajorVer + "." + reqRevision);
        // loop backwards through the versions until we find the newest version
        for (var i=25; i>0; i--) {
            var sVersion = szWhichFlash(i);
            if (sVersion == -1 ) {
                return false;
            } else if (sVersion != 0) {
                var aVersion  = new Array();
                var tmp       = sVersion.split(" ");
                tmp           = tmp[1];
                aVersion      = tmp.split(",");
                var iMajor    = aVersion[0];
                var iMinor    = aVersion[1];
                var iRevision = aVersion[2];
                var iVersion  = parseFloat(iMajor + "." + iRevision); // 7.0r24 == 7.24
                // is the major.revision >= requested major.revision AND the minor version >= requested minor
                if ((iMajor > reqMajorVer) && (iVersion >= reqVer)) {
                    return true;
                } else {
                    return ((iVersion >= reqVer && iMinor >= reqMinorVer) ? true : false);
                }
            }
        }
    }

}
sz.FlashCheck.check();


/**
 * Flash player class. Used to display a video player with desired video.
 *
 * @class  sz.FlashPlayer
 */
sz.FlashPlayer = {

    /**
     * Path to video player
     * @type  {string}
     */
    playerPath: "app/video/",

    /**
     * Flash player allready initialized or not
     * @type  {bool}
     */
    initialized: false,

    /**
     * Flag about successfull flash check
     * @type  {bool}
     */
    flashOk: false,


    /**
     * Initialization. Is to call once to run the flash detection.
     */
    init: function(){
        if (this.initialized) {
            return;
        }
        this.initialized = true;
        this.flashOk = sz.FlashCheck.check();
        return true;
    },


    /**
     * Loads flash player.
     *
     * @param  {string}  videoid     Video element id (suffix)
     * @param  {string}  flashvars   Parameter for the video flash player
     * @param  {int}     width       Width of player
     * @param  {int}     height      Height of player
     * @param  {string}  playername  Flash file name ("sz-video.swf")
     */
    loadVideo: function (videoid, flashvars, width, height, playername) {
        if (!sz.bDOM) {
            return;
        }

        var res = this.init();
        var videoId = "flashvideoswf" + videoid;

        console.log('sz.FlashPlayer.loadVideo: this.flashOk', this.flashOk);

        if (this.flashOk == true) {
            var player = this.playerPath + playername;
            $(videoId).innerHTML = '<div style="'+width+'">'
                                 + '  <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '+
                                 + '    codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" '
                                 + '    width="' + width + '" height="' + height + '" id="cec-video" align="middle">'
                                 + '    <param name="allowScriptAccess" value="sameDomain" />'
                                 + '    <param name="FlashVars" value="' + flashvars + '" />'
                                 + '    <param name="movie" value="'+player+'" />'
                                 + '    <param name="quality" value="high" />'
                                 + '    <param name="bgcolor" value="#ffffff" />'
                                 + '    <embed src="'+player+'" quality="high" bgcolor="#ffffff" width="' + width + '" '
                                 + '      height="' + height + '" name="cec-video" align="middle" FlashVars="' + flashvars + '" '
                                 + '      allowScriptAccess="sameDomain" type="application/x-shockwave-flash" '
                                 + '      pluginspage="http://www.macromedia.com/go/getflashplayer" />'
                                 + '    </embed>'
                                 + '  </object>'
                                 + '</div>';
        } else {
            $(videoId).innerHTML = '<div style="width:100%;height:152px;background-color:#f0f0f0;font-size:9px;font-family:verdana;">'
                                 + '  Der benötigte Flash Player ' + sz.FlashCheck.reqMajorVer + ' wurde nicht gefunden.<br /><br />'
                                 + '  <strong>Mögliche Ursachen:</strong><br /><br />'
                                 + '  <ul><li>JavaScript erkennt den Player nicht korrekt.</li>'
                                 + '  <li>Der Player ist nicht vorhanden.<br />'
                                 + '  <a class="color-1a" href="http://www.macromedia.com/go/getflash/" target="_blank">Jetzt installieren</a></li></ul>'
                                 + '</div>';
            Element.setStyle(videoId, { zIndex: 3 });
        }
    },


    /**
     * Loads tiny flash player. Calls loadVideoMethod() method with tiny video parameter.
     *
     * @param  {string}  videoid    Video element id (suffix)
     * @param  {string}  flashvars  Parameter for the video flash player
     */
    loadVideoS: function (videoid, flashvars) {
        var width  = 180;
        var height = 154;
        var flashvars = flashvars + "&width=" + width + "&height=" + height + "&autostart=true&usefullscreen=false";
        this.loadVideo(videoid, flashvars, width, height, "sz-video.swf");
    },


    /**
     * Loads big flash player. Calls loadVideoMethod() method with big video parameter.
     *
     * @param  {string}  videoid    Video element id (suffix)
     * @param  {string}  flashvars  Parameter for the video flash player
     */
    loadVideoL: function (videoid, flashvars) {
        var width  = 456;
        var height = 361;
        var flashvars = flashvars + "&width=" + width + "&height=" + height + "&autostart=true&usefullscreen=false";
        this.loadVideo(videoid, flashvars, width, height, "sz-videoXL_new.swf");
    }

}


// ############################

/**
 * Simple popup handler class
 *
 * @class  sz.popup
 */
sz.popup = {

    /**
     * Default popup window width
     * @type  {int}
     */
    defaultWidth:  530,

    /**
     * Default popup window height
     * @type  {int}
     */
    defaultHeight: 530,

    /**
     * Default popup window name
     * @type  {int}
     */
    defaultName: "SZ",


    /**
     * Main methods to open popup windows. Works as a wrapper for window open
     *
     * @param  {string}  url     URL to load
     * @param  {string}  name    Window name (optional, uses defaultName if argument not passed)
     * @param  {int}     width   Width of window (optional, uses defaultWidth if argument not passed)
     * @param  {int}     height  Height of window (optional, uses defaultHeight if argument not passed)
     * @param  {int}     left    Left position (optional, centers window if argument not passed)
     * @param  {int}     top     Top position (optional, centers window if argument not passed)
     */
    open: function(url, name, width, height, left, top) {
        name   = (typeof(name) !== "undefined") ? name : this.defaultName;
        width  = (typeof(width) !== "undefined") ? width : this.defaultWidth;
        height = (typeof(height) !== "undefined") ? height : this.defaultHeight;
        left   = (typeof(left) !== "undefined") ? left : (screen.width / 2) - (width / 2);
        top    = (typeof(top) !== "undefined") ? top : (screen.height / 2) - (height / 2);
        window.open(url, name, "height=" + height + ",width=" + width + ",status=no,toolbar=no,menubar=no,location=no,resizable=yes,titlebar=yes,scrollbars=yes,fullscreen=no,top=" + top + ",left=" + left);
    },

    /**
     * Open video popup. Wrapper for sz.popup.open() using predefined parameter.
     *
     * @param  {string}  url  URL to load
     */
    openVideo: function(url) {
        this.open(url, "SZMiniVideo", 530, 530);
    },

    /**
     * Open default popup. Wrapper for sz.popup.open() using predefined parameter.
     *
     * @param  {string}  url  URL to load
     */
    openWin: function(url) {
        this.open(url, "SZMaxVideo", 530, 530);
    },

    /**
     * Open newsticker popup. Wrapper for sz.popup.open() using predefined parameter.
     *
     * @param  {string}  url  URL to load
     */
    openNewsticker: function(url) {
        this.open(url, "SZNewsticker", 500, 600);
    }
}


/**
 * Just another way to open new windows. Provides more detail settings for opened windows.
 *
 * @param  {string}  url        URL to load
 * @param  {string}  name       Window name (optional, uses defaultName if argument not passed)
 * @param  {int}     width      Width of window (optional, uses defaultWidth if argument not passed)
 * @param  {int}     height     Height of window (optional, uses defaultHeight if argument not passed)
 * @param  {int}     toolbar    Flag to display toolbar (1 or 0)
 * @param  {int}     status     Flag to display status (1 or 0)
 * @param  {int}     scrollbar  Flag to display scrollbar (1 or 0)
 * @param  {int}     resizable  Flag to allow resizing of opened window (1 or 0)
 * @param  {int}     menubar    Flag to display menubar (1 or 0)
 * @param  {int}     location   Flag to display location (1 or 0)
 */
sz.newWindow = function (url, name, width, height, toolbar, status, scrollbar, resizable, menubar, location) {
    if (width < 240) {
        width = 240 + 58;
    } else {
        width = width + 58;
    }
    if (width > 768) {
        width = 768;
        scrollbar="1";
    }
    if (height == 400 ) {
        height = height + 30;
    }
    else {
        height = height + 199;
        if (height > 550 ) {
            height = 550;
            scrollbar="1";
        }
    }
    var win = window.open(url, name, "width=" + width + ",height=" + height + ", toolbar=" + toolbar + ",status=" + status + ",scrollbars=" + scrollbar + ",resizable=" + resizable + ",menubar=" + menubar + ",location=" + location);
    win.focus();
    return false;
}


// #################################################################################################

/**
 * Todo's on dom ready state.
 */
Event.observe(document, "dom:loaded", function() {
/*
    if (sz.isLinuxOS) {
        // check fontsize for clients running on linux
        var fontSize = Element.getStyle(document.body, 'fontSize');
        if (fontSize && (fontSize != '10px')) {
            // overwrite default fontsize
            Element.setStyle(document.body, { fontSize: '10px' });
        }
    }
*/
});


if (sz.isLinuxOS) {
    // additional style 4 linux
    document.write('<link rel="stylesheet" type="text/css" href="css/linux.css" />');
}


/**
 * NOTE:
 * der flash videoplayer (http://www.sueddeutsche.de/app/video/sz-video.swf) ruft die
 * js-funktion winOpen_New() auf (bei klick auf zoom-button) daher brauchen wir hier
 * einen wrapper, der den aufruf an die neue funktion delegiert.
 */
if (typeof(winOpen_New) !== "function") {
    function winOpen_New(url) {
        sz.popup.open(url);
    }
}


/**
 * NOTE: 2 prevent javascript errors
 */
/*
function new_callIVW (code) {
var get_rand = "d=" + (Math.random()*100000);
var get_referer = "r=" + escape(document.referrer);
var countIVW = new Image();
countIVW.src = "http://sueddeut.ivwbox.de/cgi-bin/ivw/CP/" + code + "?" + get_referer + "&" + get_rand;
}
*/
if (typeof(new_callIVW) == "undefined") {
    function new_callIVW(key) { }
}


// #######################################################################################

/**
 * Firebug emulation, to prevent errors if firebug is not available
 * TODO: is to remove after finishing development
 */
if (!("console" in window) || !("firebug" in console)) {
(function(){
    window.console = {
        log:   function(){},
        debug: function(){},
        info:  function(){},
        warn:  function(){},
        error: function(){}
    }
})();
}

