/**
 * Stern.de
 * All javascript-functions reside in here. We have the following objects:
 *
 *  SearchSuggest   - a class handling the search suggest :-)
 *  FontSize        - a class handling the switch of the fontsize
 *  KnowledgeTest   - a class taking care of the js-jumpgs for the tests
 *  lightbox        - a class used for the creation/handling of the lightbox
 *  cookie          - object providing accessing/creating cookies
 *  tab             - object used to switch between tabs in a box
 *  accordion       - object implements the accordion style for faqs
 *  layers          - object used for simple layer switching
 *  bookmark        - object for the bookmarks inside the bookmark layer
 *  gmaps           - object to insert a googlemaps implementation
 *  scroller        - object used for scrolling divs
 *  slider          - object used for the mboxes (sliding of floating divs)
 *  emptyFields     - object which binds js functions on ceratin input fields
 *  selectAllFields - object which binds js functions on ceratin input fields
 *  hooks           - object to place hooks inside an article
 *  user            - object to provide helper methods for user specifif access
 *  pageHooks	      - object which encapsulates triggers (like loggedIn etc)
 *  navigation      - object regarding navigational helper methods
 *  blog            - object to encapsule blog functions
 *
 * @author  felix seeberg <seeberg.felix_fr@guj.de>
 */
var Stern =
{
  url: '',

  // usually does binds
  initialize: function()
  {
    // init fontsize
    new this.FontSize();

    // zoom article Images...
    Stern.ArticleImageZoom.initialize();

    // init knowledgetest
    new this.KnowledgeTest();

    // the (light)box overlay as well
    this.lightbox.initialize();

    // search suggest
    Stern.SearchSuggest.initialize();

    // bind on input fields
    Stern.emptyFields.bind();
    Stern.selectAllFields.bind();

    // set article hooks
    Stern.hooks.place();

    // execute pageHooks - commonly needed methods
    this.pageHooks.execute();
  },

  hideTopBanner: function()
  {
    if ($('ad_div_id_banner1')) {
      $('ad_div_id_banner1').style.visibility = 'hidden';
    }
  },

  showTopBanner: function()
  {
    if ($('ad_div_id_banner1')) {
      $('ad_div_id_banner1').style.visibility = 'visible';
    }
  },

  ArticleImageZoom:
  {
	  initialize: function()
	  {
		$$('.articleImageZoom').each(function(item)
		{
			Element.observe(item, 'click', function (event)
			{
				img = this.select('img.toZoom');
				div = this.select('div.zoom');
				div_img = div[0].select('img');
				if(img[0].src.indexOf('180_120.jpg') > 0)
				{
					img[0].src = img[0].src.replace(/180_120\.jpg/, "420_280.jpg");
					div_img[0].src = div_img[0].src.replace(/plus\.gif/, "minus.gif");
				}
				else
				{
					img[0].src = img[0].src.replace(/420_280\.jpg/, "180_120.jpg");
					div_img[0].src = div_img[0].src.replace(/minus\.gif/, "plus.gif");
				}


				if(this.getWidth() == 180)
				{
					width    = 420;
					height   = 280;
					margin   = 0;
					css_left = 388;
					css_top  = 248;
				}
				else
				{
					width     = 180;
					height    = 120;
					margin    = 15;
					css_left  = 148;
					css_top   = 88;
				}
				this.morph("width: " + width + "px; margin-right: " + margin + "px");
				img[0].morph("width: " + width + "px; height: " + height + "px");
				div[0].morph("left: " + css_left + "px; top: " + css_top + "px");
			});
	    });
	  }
  },

  /**
   * Search Suggest
   * This class hadles the the search suggestions boxes on the site.
   */
  SearchSuggest:
  {
    /**
     * init search suggest. attaches to input-fields.
     */
    initialize: function()
    {
      inputFields = $$('.searchSuggest').each(function(item) {
        new Ajax.Autocompleter(item.id, item.id + "Suggest", '/suchen/suggest?renderer=PageRenderer&amp;rendererSet=Search/', {
          minChars: 2,
          afterUpdateElement: function(input, selected) {
            Stern.SearchSuggest.sendSearchSuggest(input, selected);
          }
        });
      });
    },

    sendSearchSuggest: function(input, selected)
    {
      var f = $$('form').each(function(item) {
        if (input.descendantOf(item)) {
          item.submit();
        }
      });
    }
  },

  changeProContraTab: function(tab)
  {
    if(tab == "pro") {
      $('boxcontenPro').show();
      $('boxcontenContra').hide();
      if($('gridBox1')){
        $('gridBox1').removeClassName('gridBgContra');
        $('gridBox1').addClassName('gridBgPro');
      }
    } else {
      $('boxcontenPro').hide();
      $('boxcontenContra').show();
      if($('gridBox1')){
        $('gridBox1').removeClassName('gridBgPro');
        $('gridBox1').addClassName('gridBgContra');
      }
    }
    $('moduleXL14Top').scrollTo();
  },

  /**
   * FontSize
   * This class handles the setting of the fontsize. The size is stored in
   * a cookie after setting the dom-elements and is restored once upon the
   * dom is ready and the cookie still exists
   */
  FontSize: Class.create(
  {
    initialize: function()
    {

      // bind listeners
      if ((linkBtnSmall = $('div_font_small'))) linkBtnSmall.observe('click', this.setSmall.bind(this));
      if ((linkBtnMedium = $('div_font_medium'))) linkBtnMedium.observe('click', this.setMedium.bind(this));
      if ((linkBtnLarge = $('div_font_big'))) linkBtnLarge.observe('click', this.setLarge.bind(this));

      // restore from cookie
      if (linkBtnSmall) {
        this.restoreFromCookie();
      }
    },

    restoreFromCookie: function()
    {
      if ((value = Stern.cookie.get('fontsize'))) {
        switch (value.toLowerCase()) {
          case 'small':
            this.setSmall();
            break;
          case 'large':
            this.setLarge();
            break;
          case 'medium':
          default:
            this.setMedium();
          break;
        }
      }
    },

    setSmall: function(event) {
      this.set('Small', $('div_font_small'));
    },
    setMedium: function(event) {
      this.set('Medium', $('div_font_medium'));
    },
    setLarge: function(event) {
      this.set('Large', $('div_font_big'));
    },

    set: function(fontSize, element)
    {
      Stern.cookie.set('fontsize', fontSize);

      var fontSizeClass = 'fontSize' + fontSize;

      // set correct color for the selected letter
      $('div_font_small').setStyle({color:'#666'});
      $('div_font_medium').setStyle({color:'#666'});
      $('div_font_big').setStyle({color:'#666'});
      element.setStyle({color:'#000'});

      // set correct classNames
      if ((articleIntro = $('div_article_intro'))) {
        this.removeClass(articleIntro);
        articleIntro.addClassName(fontSizeClass);
      }
      if ((xl17module = $('div_module_xl7'))) {
        this.removeClass(xl17module);
        xl17module.addClassName(fontSizeClass);
      }
      if ((xl15module = $('div_module_xl5'))) {
          this.removeClass(xl15module);
          xl15module.addClassName(fontSizeClass);
      }
      if ((pagerList = $('div_pager_list'))) {
        this.removeClass(pagerList);
        pagerList.addClassName(fontSizeClass);
      }
    },

    removeClass: function(item)
    {
      item.removeClassName('fontSizeSmall');
      item.removeClassName('fontSizeMedium');
      item.removeClassName('fontSizeLarge');
    }

  }),

  /**
   * KnowledgeTest
   * This class takes care that the formular-action is set correctly, each
   * time the back-link or the next-image-button are pressed the
   */
  KnowledgeTest: Class.create(
  {
    initialize: function()
    {
      // bind events and submit the formular
      var nextButton = $('btnKnowledgeNext');
      if (nextButton) {
        nextButton.observe('click', this.jumpNext.bind(this));
      }
      // and bind to hidden submit button to allow pressing enter
      var nextSubmitButton = $('frmKnowledge'); // <-- observe the form NOT the submit button!! STRBUGS-67
      if (nextSubmitButton) {
    	nextSubmitButton.observe('submit', this.jumpNext.bind(this));
      }

      // listen on click for backbutton
      var backButton = $('btnKnowledgeBack');
      if (backButton) {
        backButton.observe('click', this.jumpBack.bind(this));
      }

      // check for knowledgetestteaser
      var teaserButton = $$('.btnKnowledgeTeaser');
      for(var i = 0; i < teaserButton.length; i++) {
        teaserButton[i].observe('click', function() {
          var forms = $$('.frmKnowledgeTeaser');
          for(var j = 0; j < forms.length; j++) {
            if(this.descendantOf(forms[j])) {
              forms[j].submit();
              return false;
            }
          }
        });
      }
    },

    // callbacks
    jumpNext: function() {
      this.jump('knowledgeNextPage');
    },
    jumpBack: function() {
      var questionTrigger = $('knowledgeTestIsQuestion');
      if (questionTrigger) {
        questionTrigger.setValue('0');
      }
      this.jump('knowledgePrevPage');
    },

    // submit the form with the corresponding target
    jump: function(item) {
      var form = $('frmKnowledge');
      if (form) {
        form.setAttribute('action', $(item).getValue());
        form.submit();
      }
    },

    colorClasses: new Array(
      'boxBgOk',
      'boxBgWrong',
      'boxBgNone'
    ),

    // ansers: true, false, null
    answers: new Array(
    ),

    addAnswer: function(result)
    {
      this.answers.push(result);
    },

    drawProgressBar: function(result) {
      $('boxStatusContainer').addClassName('boxStatus' + this.answers.length);
      for (var i=0; i<this.answers.length; i++) {
        switch (this.answers[i]) {
          case 1:
            this.addTab(i, 'Ok');
            break;
          case 0:
            this.addTab(i, 'Wrong');
            break;
          default:
            this.addTab(i, 'None');
            break;
        }
      }
    },

    addTab: function(id, bg)
    {
      var tab = new Element('span', { 'id':id, 'class':'boxSingleStatus boxBg' + bg });
      tab.insert(new Element('span', { 'class':'boxRoundLeft' }));
      tab.insert(new Element('span', { 'class':'boxRoundRight' }));
      $('boxStatusContainer').insert(tab);
    }

  }),


  /**
   * Our overlays - used for status messages (e.g. wrong login)
   *
   * Created By: Chris Campbell
   * Website: http://particletree.com
   * Date: 2/1/2006
   *
   * Adapted By: Simon de Haan
   * Website: http://blog.eight.nl
   * Date: 21/2/2006
   *
   * Inspired by the lightbox implementation found at http://www.huddletogether.com/projects/lightbox/
   * And the lightbox gone wild by ParticleTree at http://particletree.com/features/lightbox-gone-wild/
   */
  lightbox:
  {
    /**
     * The box needs a invisible div which acts as the a positioner
     */
    initialize: function()
    {
      // links are not used, yet
      $$('.lbOn').each(function(item) {
        new Stern.lightbox.box(item);
      });

      // also use for the content itself
      $$('.lbContent').each(function(item) {
        new Stern.lightbox.box(item, true);
      });
    },

    box: Class.create
    ({
      yPos: 0,
      xPos: 0,
      content: false,

      initialize: function(ctrl, open)
      {
        if (!$('lightboxOverlay')) {
          var overlay = new Element('div', { id:'lightboxOverlay' });
          $(document.getElementsByTagName('body')[0]).insert(overlay);
        }

        // the content-div can be used too, so decide based upon rel-attribute
        if ($(ctrl).hasAttribute('rel')) {
          this.content = $(ctrl).getAttribute('rel');
          $(ctrl).observe('click', this.activate.bind(this));
          $(ctrl).onclick = function() {
            return false;
          };
        } else {
          this.content = $(ctrl).getAttribute('id');
          if (open) {
            this.activate();
          }
        }
      },

      // Turn everything on - mainly the IE fixes
      activate: function()
      {
        if (Prototype.Browser.IE) {
          this.getScroll();
          this.prepareIE('100%', 'hidden');
          this.setScroll(0, 0);
          this.hideSelects('hidden');
        }

        this.displayLightbox('block');
      },

      // Ie requires height to 100% and overflow hidden or else you can scroll down past the lightbox
      prepareIE: function(height, overflow)
      {
        var bod = $(document.getElementsByTagName('body')[0]);
        bod.setStyle({
          height:height,
          overflow:overflow
        });

        htm = $(document.getElementsByTagName('html')[0]);
        htm.setStyle({
          height:height,
          overflow:overflow
        });
      },

      // In IE, select elements hover on top of the lightbox
      hideSelects: function(vis)
      {
        selects = document.getElementsByTagName('select');
        for (var i=0; i<selects.length; i++) {
          $(selects[i]).setStyle({ visibility:vis });
        }
      },

      // Taken from lightbox implementation found at http://www.huddletogether.com/projects/lightbox/
      getScroll: function()
      {
        if (self.pageYOffset) {
          this.yPos = self.pageYOffset;
        } else if (document.documentElement && document.documentElement.scrollTop){
          this.yPos = document.documentElement.scrollTop;
        } else if (document.body) {
          this.yPos = document.body.scrollTop;
        }
      },

      setScroll: function(x, y)
      {
        window.scrollTo(x, y);
      },

      displayLightbox: function(display)
      {
        $('lightboxOverlay').setStyle({ display: display });
        $(this.content).setStyle({ display: display });
        if (display != 'none') {
          this.bindActions();
        }
      },

      // Example of creating your own functionality once lightbox is initiated
      deactivate: function()
      {
        if (Prototype.Browser.IE) {
          this.setScroll(0, this.yPos);
          this.prepareIE('auto', 'auto');
          this.hideSelects('visible');
        }

        this.displayLightbox('none');
      },

      bindActions: function()
      {
        var links = $$('.lbAction');
        for (var i=0; i<links.length; i++) {
          var item = $(links[i]);
          if (item.hasAttribute('rel')) {
            var rel = item.getAttribute('rel');
            item.observe('click', this[rel].bind(this));
            item.onclick = function() {
              return false;
            };
          }
        }
      }

    })
  },

  /**
   * Encodes the given text with a rot13-algorithm. Oooooooh
   */
  rot13: function(text)
  {
    var keycode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var text    = new String(obj.form.Text.value);
    var rot13   = new String();

    for(var i = 0; i < text.length; i++) {
      var codechar = text.substring(i, i + 1);
      var pos = keycode.indexOf(codechar.toUpperCase());
      if (pos >= 0) {
        pos = (pos + keycode.length / 2) % keycode.length;
        codechar = (codechar == codechar.toUpperCase()) ? keycode.substring(pos, pos + 1) : keycode.substring(pos, pos + 1).toLowerCase();
      }
      rot13 = rot13 + codechar;
    }
    return rot13;
  },


  /**
   * Cookie functions are encapsulated whithin here
   */
  cookie:
  {
    /**
     * Sets a cookie - valid for the whole domain and one year
     */
    set: function(name, value)
    {
      var a = new Date();
      a = new Date(a.getTime() + 1000*60*60*24*365);
      var cookieValue = name + '=' + value + '; expires=' + a.toGMTString() + '; path=/';
      document.cookie = cookieValue;
    },

    /**
     * Returns the wanted cookie value - if it exists
     */
    get: function(name)
    {
      cookieValue = null;
      if (document.cookie) {
        var string = 'document.cookie.match(/' + name + '=([^;]*)/);';
        var match  = eval(string);
        if (match != null && match.length == 2) {
          cookieValue = match[1];
        }
      }
      return cookieValue;
    }

  },

  /**
   * get Values from CookieStore cookie (see: CookieStore.class.php)
   */
  cookieStore:
  {
    cookieStoreName: 'CookieStore',

    /**
     * get a value for given key
     * return default if not existing
     */
    get: function(key, defaultValue)
    {
      var json  = unescape(Stern.cookie.get(this.cookieStoreName)).evalJSON(true);
      if (json && json[key] != undefined) {
        return json[key][0];
      } else {
        return defaultValue;
      }
    }
  },

  /**
   * Changes the content and tabs
   */
  tab:
  {
    change: function(tab, newClass, boxClass)
    {
      tab = $(tab);
      var curClasses = $w(tab.className);
      var curClass   = curClasses.last();
      if (curClass != newClass)
      {
        this.getTabs(tab).each(function(item, index)
        {
          item.removeClassName(newClass);
          item.addClassName(curClass);
        });
        tab.removeClassName(curClass);
        tab.addClassName(newClass);
        this.switchContentBox(tab, boxClass);
      }
    },

    changeMore: function(tab, newClass, boxClass, number)
    {
      tab = $(tab);
      var curClasses = $w(tab.className);
      var curClass   = curClasses.last();
      if (curClass != newClass)
      {
        this.getTabs(tab).each(function(item, index)
        {
          item.removeClassName(newClass);
          item.addClassName(curClass);
        });
        tab.removeClassName(curClass);
        tab.addClassName(newClass);
        this.switchContentBoxMore(tab, boxClass, number);
      }
    },

    getTabs: function(tab)
    {
      return tab.up().childElements();
    },

    getBoxes: function(tab, boxClass)
    {
      return tab.up().next().select('.' + boxClass);
    },

    switchContentBox: function(tab, boxClass)
    {
      this.getBoxes(tab, boxClass).each(function(item, index) {

        item.toggle();

        if (item.visible()) {
          Stern.scroller.enable(index);
        } else {
          Stern.scroller.disable(index);
        }

      });
    },

    switchContentBoxMore: function(tab, boxClass, number)
    {
      this.getBoxes(tab, boxClass).each(function(item, index) {

        if(item.hasClassName(boxClass + '_' + number))
        {
          item.show();
        }
        else
        {
          item.hide();
        }

        if (item.visible()) {
          Stern.scroller.enable(index);
        } else {
          Stern.scroller.disable(index);
        }

      });
    }
  },

  /**
   * Layer control
   */
  layers:
  {
    /**
     * every opened layer is pushed in this array, so that we can close only
     * opened ones
     */
    storage: new Array(),

    /**
     * Adds the given id to the storage - only if non existant
     */
    addToStorage: function(id)
    {
      if (this.storage.indexOf(id) == -1) {
        this.storage.push(id);
      }
    },

    /**
     * Checks if the layer is visible, checks for attribute existance
     */
    layerIsVisible: function(id)
    {
      return $(id).getStyle('display') == 'block';
    },

    closeAll: function()
    {
      this.storage.each(function(id) {
        Stern.layers.close(id, true);
      });
    },

    close: function(id, keepFlashElementsHidden)
    {
      if ($(id).getStyle('display') == 'block') {

        $(id).setStyle({
          display:'none'
        });
        this.getLineByLayerId(id).setStyle({
          backgroundColor:'transparent'
        });
        this.getTabByLayerId(id).setStyle({
          borderColor:'',
          backgroundColor:''
        });
        this.switchLinkColor(id);

        // the topnavigation has a red arrow which needs switching
        this.switchArrow(id);

        // remove from storage
        this.storage = this.storage.without(id);

        // show flash elements - only if a single tab is closed
        if (keepFlashElementsHidden != true) {
          this.showFlashElements();
        }
      }
      return false;
    },

    /**
     * Procedure: Put tab in storage - close tabs - activate current
     */
    open: function(id, options)
    {
      // if already open, close it
      if (this.layerIsVisible(id)) {
        return this.close(id);
      }

      // close all and add to opened layer storage
      this.closeAll();
      this.addToStorage(id);

      // we need to hide flash elements first - they can
      this.hideFlashElements();

      // check attribute existance because the display-property is defined in the css-file
      if (!$(id).hasAttribute('display') || !$(id).visible()) {

        $(id).setStyle({
          display: 'block'
        });

        // due to the reverted position of the bottom layers, set the correct top position
        if (this.getTabByLayerId(id).next()) {
          this.setLayerTopPosition(id);
        }

        // if we have a white link - switch it
        this.switchLinkColor(id);

        this.getTabByLayerId(id).setStyle({
          backgroundColor:'#fff',
          borderColor:'#999'
        });
        this.getLineByLayerId(id).setStyle({
          backgroundColor:'#999'
        });

        // the topnavigation has a red arrow which needs switching
        this.switchArrow(id);

      }

      return false;
    },

    switchLinkColor: function(id)
    {
      var link = this.getLinkByLayerId(id);
      if (link.hasClassName('jsColorBlack')) {
        if (link.getStyle('color') == 'black') {
          var newColor = '';
        } else {
          var newColor = 'black';
        }
        link.setStyle({ color: newColor });
      }
    },

    switchArrow: function(id)
    {
      var link = this.getLinkByLayerId(id);
      if (link.hasClassName('arrowDown')) {
        var classToRemove = 'arrowDown';
        var classToAdd = 'arrowUp';
      } else {
        var classToRemove = 'arrowUp';
        var classToAdd = 'arrowDown';
      }
      link.removeClassName(classToRemove).addClassName(classToAdd);
    },

    getTabByLayerId: function(id)
    {
      return $(id + '_tab');
    },

    getLineByLayerId: function(id)
    {
      return $(id + '_line');
    },

    getLinkByLayerId: function(id)
    {
      return $(id + '_link');
    },

    setLayerTopPosition: function(id)
    {
      var topPosition = ($(id).offsetHeight - 3 ) * -1;
      $(id).setStyle({ top:topPosition + 'px' });
    },

    /**
     * we dont want to have certain elements (e.g. ad-flashs) on the page
     */
    getFlashTagName: function()
    {
      return 'embed';
    },
    getFlashTagNameIE: function()
    {
      return 'object';
    },

    hideFlashElements: function()
    {
      // we hide the damn banner too (interferes with layers)
      if ($('top_sbanner')) {
        $('top_sbanner').hide();
      }
      if ($('ad_div_id_banner1')) {
        $('ad_div_id_banner1').style.visibility = 'hidden';
      }
      $$(this.getFlashTagName()).each(function(item) {
        item.style.visibility = 'hidden';
      });
      $$(this.getFlashTagNameIE()).each(function(item) {
        item.style.visibility = 'hidden';
      });
    },

    showFlashElements: function()
    {
      // show the top ad banner
      if ($('top_sbanner')) {
        $('top_sbanner').show();
      }
      if ($('ad_div_id_banner1')) {
        $('ad_div_id_banner1').style.visibility = 'visible';
      }
      $$(this.getFlashTagName()).each(function(item) {
        item.style.visibility = 'visible';
      });
      $$(this.getFlashTagNameIE()).each(function(item) {
        item.style.visibility = 'visible';
      });
    }
  },


  /**
   * Toggler for the faq-accordion
   */
  accordion:
  {
    getItem: function(callerLink)
    {
      return $(callerLink).next();
    },

    toggle: function(link)
    {
      var item = this.getItem(link);
      if (item.visible()) {
        this.close(link);
      } else {
        this.open(link);
      }
    },

    open: function(openerLink)
    {
      var item = this.getItem(openerLink);
      if (item != undefined && !item.visible()) {
        item.toggle();
        openerLink.removeClassName('close').addClassName('open');
      }
    },

    close: function(openerLink)
    {
      var item = this.getItem(openerLink);
      if (item.visible()) {
        item.toggle();
        openerLink.removeClassName('open').addClassName('close');
      }
    },

    toggleAll: function(callerLink, linkClassName)
    {
      var callerLink = $(callerLink);
      var openerLinks = $$('.' + linkClassName);
      if (callerLink.hasClassName('openAll')) {
        openerLinks.each(function(openerLink) {
          Stern.accordion.open(openerLink);
        });
        var removeClassName = 'openAll';
        var addClassName = 'closeAll';
        var text = 'alle schließen';
      } else {
        openerLinks.each(function(openerLink) {
          Stern.accordion.close(openerLink);
        });
        var removeClassName = 'closeAll';
        var addClassName = 'openAll';
        var text = 'alle öffnen';
      }
      callerLink.removeClassName(removeClassName).addClassName(addClassName).update(text);
      return false;
    },

    openByIndex: function(index, linkClassName)
    {
      var openerLinks = $$('.' + linkClassName);
      this.open(openerLinks[index]);
    }
  },

  /**
   * Edelweiß provided this popup function
   */
  popup: function(URL, popname, W, H, scroll, rezisable, X, Y)
  {
    // var URL,popname, W, H,scroll,rezisable,X,Y;
    if (!popname) popname = 'popup';
    if (!W) W = 520;
    if (!H) H = 460;
    if (!scroll) scroll = 0;
    if (!rezisable) rezisable = 0;
    if (!X) X = screen.width/2 - (W/2);
    if (!Y) Y = screen.height/2 - (H/2) - 20;
    properties = "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars="+scroll+",resizable="+rezisable+",";
    properties += "width="+W+",height="+H+",left="+X+",top="+Y;
    popwin = window.open(URL, popname, properties);
    popwin.focus();
  },

  /**
   * Useability for the bookmarks layer
   * shows the name of the highlighted bookmark icon
   * default is Facebook
  */
  bookmark:
  {
    timeout: false,

    getTextHolder: function(link)
    {
      return $(link).up().next();
    },

    show: function(link, title)
    {
      if (this.timeout) {
        window.clearTimeout(this.timeout);
      }
      this.getTextHolder(link).update(title);
    },

    hide: function(link)
    {
      this.timeout = window.setTimeout(function() {
        Stern.bookmark.getTextHolder(link).update('Facebook');
      }, 500);
    },

    post: function(was)
    {
      sburl   = encodeURIComponent(location.href);
      sbtitle = encodeURIComponent(document.title);
      switch(was) {
      case 'facebook':
        window.open('http://www.facebook.com/share.php?u='+sburl+'&t='+sbtitle);
        break;
      case 'mrwong':
        window.open('http://www.mister-wong.de/index.php?action=addurl&bm_url='+sburl+'&bm_description='+sbtitle);
        break;
      case 'delicious':
        window.open('http://delicious.com/post?url='+sburl+'&title='+sbtitle);
        break;
      case 'wikio':
        window.open('http://www.wikio.com/vote?url='+sburl);
        break;
      case 'webnews':
        window.open('http://www.webnews.de/einstellen?url='+sburl+'&title='+sbtitle);
        break;
      case 'digg':
        window.open('http://digg.com/submit?phase=2&url='+sburl+'&title='+sbtitle);
        break;
      case 'yigg':
        window.open('http://yigg.de/neu?exturl='+sburl+'&exttitle='+sbtitle);
        break;
      case 'myspace':
        window.open('http://www.myspace.com/Modules/PostTo/Pages/?l=3&u='+sburl+'&t='+sbtitle);
        break;
      case 'blinkList':
        window.open('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url='+sburl+'&Title='+sbtitle);
        break;
      case 'furl':
        window.open('http://www.furl.net/storeIt.jsp?u='+sburl+'&t='+sbtitle);
        break;
      case 'folkd':
        window.open('http://www.folkd.com/submit/page/'+sburl);
        break;
      case 'linkarena':
        window.open('http://linkarena.com/bookmarks/addlink/?url='+sburl+'&title='+sbtitle+'&desc=&tags=');
        break;
      case 'google':
        window.open('http://www.google.com/bookmarks/mark?op=add&hl=de&bkmk='+sburl+'&title='+sbtitle);
        break;
      }
    }
  },

  /**
   * Googlemaps helper object
   */
  gmaps:
  {
    lon:  null,
    lat:  null,
    zoomLevel:  null,
    infoText: null,
    mapType: null,

    load: function(mapHolderId)
    {
      if (GBrowserIsCompatible()) {

        var map = new GMap2($(mapHolderId));
        map.addControl(new GSmallMapControl());
        map.addControl(new GMapTypeControl());
        var mtype = G_NORMAL_MAP;
        if(this.mapType == 1)
        {
          mtype = G_SATELLITE_MAP;
        }
        else if(this.mapType == 2)
        {
          mtype = G_HYBRID_MAP;
        }
        map.setCenter(new GLatLng(this.lat, this.lon), this.zoomLevel, mtype);

        GEvent.addListener(map, 'dragend', function () {
          gmapsArtivw(1);
        });
        GEvent.addListener(map, 'zoomend', function () {
          gmapsArtivw(1);
        });
        GEvent.addListener(map, 'moveend', function () {
          gmapsArtivw(0);
        });
        GEvent.addListener(map, 'maptypechanged', function () {
          gmapsArtivw(1);
        });
        var point = new GLatLng(this.lat, this.lon);
        var marker = this.createMarker(point);
        map.addOverlay(marker);
        marker.openInfoWindowHtml(this.infoText);
      }
    },

    createMarker: function(point)
    {
      var marker = new GMarker(point);
      if(this.infoText)
      {
        var itext = this.infoText;
        GEvent.addListener(marker, 'click', function() {
          marker.openInfoWindowHtml(itext);
        });
      }
      GEvent.addListener(marker, 'infowindowopen', function () {
        gmapsArtivw(0);
      });
      GEvent.addListener(marker, 'infowindowclose', function () {
        gmapsArtivw(0);
      });
      return marker;
    }
  },

  /**
   * Based upons scriptaculous slider library
   */
  scroller:
  {
    storage: new Array(),

    scroll: function(scrollableId, handleId, trackId)
    {
      var scroller = new Control.Slider(handleId, trackId, {
        axis: 'vertical',
        onSlide: function(v) {
          Stern.scroller.scrollVertical(v, $(scrollableId), scroller);
        },
        onChange: function(v) {
          Stern.scroller.scrollVertical(v, $(scrollableId), scroller);
        }
      });

      // disable vertical scrolling if text doesn't overflow the div
      if ($(scrollableId).scrollHeight <= $(scrollableId).offsetHeight) {
        scroller.setDisabled();
        $(trackId).hide();
      }

      this.storage.push(scroller);
    },

    scrollVertical: function (value, element, slider)
    {
      element.scrollTop = Math.round(value / slider.maximum * (element.scrollHeight - element.offsetHeight));
    },

    enable: function(index)
    {
      if (this.storage.indexOf(index) != -1) {
        this.storage[index].setEnabled();
      }
    },

    disable: function(index)
    {
      if (this.storage.indexOf(index) != -1) {
        this.storage[index].setDisabled();
      }
    }
  },

  /**
   * The m-boxes slider,
   */
  slider:
  {
    /**
     * Sliders are storage whithin this array
     */
    storage:
    {
    },

    big: Class.create
    ({
      initialize: function(sliderId, sliderData, itemWidth, buildCallback, itemsToScroll)
      {
        this.sliderId       = sliderId;
        this.sliderData     = sliderData;
        this.itemWidth      = itemWidth;
        this.buildCallback  = buildCallback;
        this.clickCounter   = 1; // set bigimage on M08Photoshow and highlight items
        this.iterator       = 1; // iterate Items (M08 -> second items highlighted, see photoMultiItems)
        this.objects        = new Array();
        this.itemsToScroll  = itemsToScroll;//count of items to scroll

        if (this.itemsToScroll == undefined)
        {
          this.itemsToScroll = 1;//default
        }

        for (var i=0; i<sliderData.length; i++) {
          this.objects.push(this.buildCallback(sliderData[i]));
        };

        this.placeItems();

        return this;
      },

      isActive: false,

      placeItems: function()
      {
        if (this.objects.length > 0) {

          var items = new Array();

          //add last items to first to enable backward-moving from startpoint
          for (var i=1; i<=this.itemsToScroll; i++)
          {
            items.push(this.objects.length-i);
          }

          for (var i = 0; i < this.objects.length - this.itemsToScroll; i++)
          {
            items.push(i);
          }

          $(this.sliderId).update();
          for (var i = 0; i < items.length; i++)
          {
            var id   = this.sliderId + '_item' + i;
            var item = this.objects[items[i]];
            item.setAttribute('id', id);
            $(this.sliderId).insert(item);
          }

          // if we have only 1 item -> reset offset left position
          if (items.length == 1)
          {
            $(this.sliderId).setStyle({ left:'0px' });
          }

        }
      },

      moveToLeft: function()
      {
        // only move if not active (avoids flashing of content) and more than 1 item
        if (this.isActive || this.objects.length < 2) {
          return;
        }

        // set to active
        this.isActive = true;

        for (i=1; i<=this.itemsToScroll; i++)
        {
          var first = $(this.sliderId).firstDescendant();
          first.remove();
          $(this.sliderId).insert(first);
          $(this.sliderId).setStyle({ left:'0px' });
        }

        new Effect.Move(this.sliderId, {
          x: 0 - this.itemWidth,
          duration: 0.5,
          afterFinish: this.finishMovement.bind(this)
        });
      },

      moveToRight: function()
      {
        // only move if not active (avoids flashing of content) and more than 1 item
        if (this.isActive || this.objects.length < 2) {
          return;
        }

        // set to active
        this.isActive = true;

        new Effect.Move(this.sliderId, {
          x: this.itemWidth,
          duration: 0.5,
          afterFinish: this.moveToRightAfterFinish.bind(this)
        });
      },

      moveToRightAfterFinish: function(ite)
      {
        for (i=1; i<=this.itemsToScroll; i++)
        {
          var last = $(this.sliderId).childElements().last();
          last.remove();
          $(this.sliderId).insert({ top: last });
          $(this.sliderId).setStyle({ left: 0 - (this.itemWidth) + 'px' });
        }
        this.finishMovement();
      },

      finishMovement: function()
      {
        this.isActive = false;
      },

      setMultiItems: function(opaqueId, highlightId)
      {
        // special for M08
        opaqueElement       = this.sliderId + '_link' + opaqueId;
        highlightElement    = this.sliderId + '_link' + highlightId;

        $(highlightElement).addClassName('high');
        $(highlightElement).removeClassName('opaque');

        $(opaqueElement).addClassName('opaque');
        $(opaqueElement).removeClassName('high');
      },

      setLeaderLeft: function()
      {
        itemCount     = $(this.sliderData).length;
        // IMAGES start @0, pos marker @-1, so (POS+1) is current image, while POS+2 is the next (to the right)
        highlightItem = this.cycleInc(this.clickCounter, 2, itemCount - 1);
        fadeOutItem   = this.cycleInc(this.clickCounter, 1, itemCount - 1);
        leaderItem    = fadeOutItem;
        this.showLeader(leaderItem);
        this.setMultiItems(fadeOutItem, highlightItem);
        this.clickCounter = (this.clickCounter + 1) % itemCount;
      },
      setLeaderRight: function()
      {
        itemCount     = $(this.sliderData).length;

        // Restart from other end of the picture list
        if (this.clickCounter < 0) {
          this.clickCounter = itemCount - 1;
        }
        // IMAGES start @0, pos marker @-1, so (POS+1) is current image, while POS is the previous (to the left)
        highlightItem =  this.clickCounter;
        fadeOutItem   =  this.cycleInc(highlightItem, 1, itemCount - 1);
        leaderItem    =  this.cycleDec(highlightItem, 1, itemCount - 1);

        this.showLeader(leaderItem);
        this.setMultiItems(fadeOutItem, highlightItem);
        this.clickCounter--;
      },
      cycleInc: function(from, step, max)
      {
        return (from + step) % (max + 1);
      },
      cycleDec: function(from, step, max)
      {
        return (from - step) >= 0 ? this.cycleInc(from - step, 0, max) : (max + 1) + ((from - step) % (max + 1));
      },
      showLeader: function(item)
      {
         /* special for M08, M11 */
         var leaderData = eval(this.sliderData);
         var url        = leaderData[item].url;
         var title      = leaderData[item].titleAttribute;

         var boxLeaderId = 'boxLeader_' + this.sliderId;
         $(boxLeaderId).hide();

         $('boxLeaderSpitzmarke_' + this.sliderId).update(leaderData[item].spitzmarke);
         $('boxLeaderHeadline_' + this.sliderId).update(leaderData[item].headlineShort);

         if ($('boxLeaderIcon_' + this.sliderId))
         {
           $('boxLeaderIcon_' + this.sliderId).setAttribute("href", url);
           $('boxLeaderIcon_' + this.sliderId).setAttribute("title", title);
           $('boxLeaderTrans_' + this.sliderId).setAttribute("href", url);

           $('boxLeaderImage1_' + this.sliderId).src = leaderData[item].teaserImage1Url;
           $('boxLeaderImage2_' + this.sliderId).src = leaderData[item].teaserImage2Url;
           $('boxLeaderImage3_' + this.sliderId).src = leaderData[item].teaserImage3Url;
         }
         if ($('boxLeaderTeaser_' + this.sliderId))
         {
           $('boxLeaderTeaser_' + this.sliderId).update(leaderData[item].teaserTextShort);
         }
         if ($('boxLeaderAuthor_' + this.sliderId))
         {
           $('boxLeaderAuthor_' + this.sliderId).update(leaderData[item].author);
         }
         $('boxLeaderUrl_' + this.sliderId).setAttribute("href", url);
         $('boxLeaderUrl_' + this.sliderId).setAttribute("title", title);
         if ($('boxLeaderUrlMore_' + this.sliderId))
         {
           $('boxLeaderUrlMore_' + this.sliderId).setAttribute("href", url);
           $('boxLeaderUrlMore_' + this.sliderId).setAttribute("title", title);
         }
         $(boxLeaderId).show();
      }
    }),

    builder:
    {
      photoMultiItem: function(data)
      {
        var container = new Element('div', { 'class': 'scrollSmallItems' });

        if (this.iterator == $(this.sliderData).length)
        {
          this.iterator = 0;
        }

        var className = 'high';
        /* the second item is highlighted */
        if (this.iterator != 2)
        {
          className = 'opaque';
        }

        var link = new Element('a', { id: this.sliderId + '_link' + this.iterator, 'class': className, title: data.titleAttribute, href: data.url });
        link.insert(new Element('span', {}).insert('&nbsp;'));
        container.insert(link);

        var img = new Element('img', { src: data.imageUrl, width: '75', height: '50', alt: data.spitzmarke, title: data.titleAttribute });
        container.insert(img);
        this.iterator++;

        return container;
      },

      columnMultiItem: function(data)
      {
        var container = new Element('div', { 'class': 'scrollSmallItems' });

        if (this.iterator == $(this.sliderData).length)
        {
          this.iterator = 0;
        }

        var className = 'high';
        // the second item is highlighted
        if (this.iterator != 2)
        {
          className = 'opaque';
        }

        var link = new Element('a', { id: this.sliderId + '_link' + this.iterator, 'class': className, title: data.titleAttribute, href: data.url });
        link.insert(new Element('span', {}).insert('&nbsp;'));
        container.insert(link);

        var img = new Element('img', { src: data.custom, width: 50, height: 50, alt: data.spitzmarke, title: data.titleAttribute });
        container.insert(img);
        this.iterator++;

        return container;
      },

      videoItem: function(data)
      {
        var container = new Element('div', { 'class': 'scrollItems' });

        var linkVideo = new Element('a', { 'class': 'linkVideoPlay', title: 'Video abspielen...', href: '#' });
        linkVideo.onclick = function() {Stern.video.showPlayer(data.container,data.renderer,data.id,data.urlPrefix);return false;};
        linkVideo.insert(new Element('img', { src: data.imageUrl, width: '240', height: '134', alt: data.spitzmarke, title: 'Video abspielen...' }));
        linkVideo.insert(new Element('span', { 'class': 'buttonPlay' }));
        var boxVideo = new Element('div', { 'class': 'boxVideoDescription' });
        var boxVideoLink = new Element('a', { 'class': 'h2', href: data.url, title: 'Zum Video...' });
        var boxVideoLinkSpan = new Element('span').insert(data.spitzmarke);
        var boxVideoLinkHeadline = new Element('span', { 'class': 'boxHeadline' }).insert(data.headline);
        boxVideoLink.insert(boxVideoLinkSpan);
        boxVideoLink.insert(boxVideoLinkHeadline);
        boxVideo.insert(boxVideoLink);

        container.insert(linkVideo);
        container.insert(boxVideo);

        return container;
      },

      videoBrightcoveItem: function(data)
      {
        var container = new Element('div', { 'class': 'scrollItems' });

        var linkVideo = new Element('a', { 'class': 'linkVideoPlay', title: data.titleAttribute, href: '#' });
        linkVideo.onclick = function() {loadVideoInPlayer(data);return false;};
        linkVideo.insert(new Element('img', { src: data.imageUrl, width: '120', height: '90', alt: data.titleAttribute, title: data.titleAttribute }));
        linkVideo.insert(new Element('span', { 'class': 'buttonPlay' }));
        var boxVideo = new Element('div', { 'class': 'boxVideoDescription' });
        var boxVideoLink = new Element('a', { 'class': 'h2', href: '#', title: data.titleAttribute });
        boxVideo.onclick = function() {loadVideoInPlayer(data);return false;};
        var boxVideoLinkHeadline = new Element('span', { 'class': 'boxHeadline' }).insert(data.headline);
        boxVideoLink.insert(boxVideoLinkHeadline);
        boxVideo.insert(boxVideoLink);

        container.insert(linkVideo);
        container.insert(boxVideo);

        return container;
      },

      videoShowroomItem: function(data)
      {
        var container = new Element('div', { 'class': 'scrollItems' });

        var boxVideo             = new Element('div', { 'class': 'colImage' });

        var boxVideoLink         = new Element('a', { 'class': 'h3', href: data.url, title: data.titleAttribute });
        var boxVideoLinkPlayBut  = new Element('span', { 'class': 'buttonPlay' }).insert('&nbsp;');
        var boxVideoLinkSpitz    = new Element('span', { 'class': 'headText' }).insert(data.spitzmarke);
        var boxVideoLinkHeadline = new Element('span', { 'class': 'linkText' }).insert(data.headline);
        var boxVideoImage        = new Element('img', { src: data.imageUrl, alt: data.headline, title: data.titleAttribute, width: 150, height: 100 });
        boxVideoLink.insert(boxVideoImage);
        boxVideoLink.insert(boxVideoLinkPlayBut);
        boxVideoLink.insert(boxVideoLinkSpitz);
        boxVideoLink.insert(boxVideoLinkHeadline);

        var linkIcon = new Element('a', { 'class': 'spriteIcons iconMedium videoMedium', title: data.headline , href: data.url });
        var span     = new Element('span', { 'class': 'hideMe' });
        var transImg = new Element('img', { width: '2', height: '2', alt: '', src: '/img/trans.gif' });
        span.insert(transImg);
        linkIcon.insert(span);

        boxVideo.insert(linkIcon);
        boxVideo.insert(boxVideoLink);

        container.insert(boxVideo);

        return container;
      },

      magazineItem: function(data)
      {
        var container = new Element('div', { 'class': 'scrollItems' });
        var layerCont = new Element('div', { 'class': 'layerCont' });
        var divFix = new Element('div', { 'class': 'clearfix' });

        if (Stern.isValidImageUrl(data.image)) {
          var boxLink = new Element('a', { 'class': 'boxImage', href: data.url_to_toc, title: data.headline });
          var boxLinkImage = new Element('img', { src: data.image, alt: data.headline, title: data.headline, width: 242, height: 166 });
          boxLink.insert(boxLinkImage);
          divFix.insert(boxLink);
        }

        var boxHeadlineLink = new Element('a', { 'class': 'h2', href: data.url_to_toc, title: data.headline });
        var boxHeadlineLinkSpanHeadline = new Element('span', { 'class': 'boxHeadline' }).update(data.headline);
        var boxHeadlineLinkSpanSub = new Element('span').update(data.sub_headline);
        boxHeadlineLink.insert(boxHeadlineLinkSpanHeadline);
        boxHeadlineLink.insert(boxHeadlineLinkSpanSub);
        divFix.insert(boxHeadlineLink);

        layerCont.insert(divFix);
        container.insert(layerCont);

        return container;
      },

      sternTvItem: function(data)
      {
        var container = new Element('div', { 'class': 'scrollItems' });

        var layerCont = new Element('div', { 'class': 'layerCont' });

        var icon;
        if (data.articleType == "special")
        {
          icon = 'faqSmall';
        }
        else
        {
          icon = data.articleType + 'Small';
          if (data.articleType == "special")
          {
            if (data.articles.length > 0) {
            icon = data.articles[0].articleType + 'Small';;
            }
          }
          if (data.articleType == "standard")
          {
            icon = 'articleSmall';
          }
        }

        var iconLink = new Element('a', { 'class': 'spriteIcons iconLarge ' + icon , href: data.url, title: data.titleAttribute }).update('&nbsp;');
        layerCont.insert(iconLink);

        var divFix = new Element('div', { 'class': 'clearfix' });

        if (typeof data.teaserText == "undefined")
        {
          if (data.articles.length > 0) {

          var data = data.articles[0];

          if (Stern.isValidImageUrl(data.imageUrl)) {
            var boxLink = new Element('a', { 'class': 'boxImage', href: data.url, title: data.titleAttribute });
            var boxLinkImage = new Element('img', { src: data.imageUrl, alt: data.spitzmarke, title: data.titleAttribute, width: 120, height: 80 });
            boxLink.insert(boxLinkImage);
            divFix.insert(boxLink);
          }

          var boxHeadlineLink = new Element('a', { 'class': 'h2', href: data.url, title: data.titleAttribute });
          var boxHeadlineLinkSpan = new Element('span').update(data.spitzmarke);
          var boxHeadlineLinkHeadline = new Element('span', { 'class': 'boxHeadline' }).update(data.headline);
          boxHeadlineLink.insert(boxHeadlineLinkSpan);
          boxHeadlineLink.insert(boxHeadlineLinkHeadline);
          divFix.insert(boxHeadlineLink);

          divFix.insert(data.teaserTextShort);

          }
        }
        else
        {
          if (Stern.isValidImageUrl(data.imageUrl)) {
            var boxLink = new Element('a', { 'class': 'boxImage', href: data.url, title: data.titleAttribute });
            var boxLinkImage = new Element('img', { src: data.imageUrl, alt: data.spitzmarke, title: data.titleAttribute, width: 120, height: 80 });
            boxLink.insert(boxLinkImage);
            divFix.insert(boxLink);
          }

          var boxHeadlineLink = new Element('a', { 'class': 'h2', href: data.url, title: data.titleAttribute });
          var boxHeadlineLinkSpan = new Element('span').update(data.spitzmarke);
          var boxHeadlineLinkHeadline = new Element('span', { 'class': 'boxHeadline' }).update(data.headline);
          boxHeadlineLink.insert(boxHeadlineLinkSpan);
          boxHeadlineLink.insert(boxHeadlineLinkHeadline);
          divFix.insert(boxHeadlineLink);

          divFix.insert(data.teaserTextShort);
        }

        layerCont.insert(divFix);
        container.insert(layerCont);

        return container;
      },

      simpleExtraItem: function(data)
      {
        var container = new Element('div', { 'class': 'scrollItems' });

        var layerCont = new Element('div', { 'class': 'specialImgCont' });
        var firstHeadlineLinkSpan = new Element('span', { 'class': 'hideMe' });
        var iconLink = new Element('a', { 'class': 'spriteIcons iconMedium specialMedium', href: data.url, title: data.titleAttribute }).update(firstHeadlineLinkSpan);
        layerCont.insert(iconLink);

        var divFix = new Element('div', { 'class': 'clearfix' });

        if (data.articles.length > 0) {
          var boxLink = new Element('a', { 'class': 'boxImage', href: data.url, title: data.titleAttribute });
          if (Stern.isValidImageUrl(data.mTeaserImageUrl)) {
            var boxLinkImage = new Element('img', { 'src' : data.mTeaserImageUrl, alt: data.spitzmarke, title: data.titleAttribute, width: 268, height: 80 });
            boxLink.insert(boxLinkImage);
          }
          divFix.insert(boxLink);

          var titlediv = new Element('div', { 'class': 'titleCont' });
          var boxHeadlineLink = new Element('a', { 'class': 'h2', href: data.url, title: data.titleAttribute });
          var boxHeadlineLinkSpan = new Element('span').update(data.spitzmarke);
          var boxHeadlineLinkHeadline = new Element('span', { 'class': 'boxHeadline' }).update(data.headline);
          var test = new Element('span').update(data);

          boxHeadlineLink.insert(boxHeadlineLinkSpan);
          boxHeadlineLink.insert(boxHeadlineLinkHeadline);
          titlediv.insert(boxHeadlineLink);
          divFix.insert(titlediv);
          layerCont.insert(divFix);

          if (data.ebookletLogo)
          {
            var ebdiv  = new Element('div', {'class': 'boxPartnerlogo'});
            ebdiv.insert(new Element('span').update('präsentiert von'));
            var link = new Element('a', { href: data.ebookletLogoUrl, title: data.headline });
            link.insert(new Element('img', {'src': data.ebookletLogo}));
            ebdiv.insert(link);
            if(data.ebookletCount)
            {
              ebdiv.insert(new Element('img', {'src': data.ebookletCount + ad_server_rand, 'width': 1, 'height':1 }));
            }
            ebdiv.insert(new Element('br'));
          }
        }
        container.insert(layerCont);
        if (ebdiv) { container.insert(ebdiv); }

        return container;

      },

      extraItem: function(data)
      {
        var container = new Element('div', { 'class': 'scrollItems' });

        var boxHeadline = new Element('span', { 'class': 'boxExtraHeadline' });

        var firstHeadlineLinkSpan = new Element('span', { 'class': 'hideMe' });
        var firstHeadlineLink = new Element('a', { 'class': 'spriteIcons iconLarge specialMedium', href: data.url }).update(firstHeadlineLinkSpan);
        var secondHeadlineLink = new Element('a', { href: data.url, title: data.titleAttribute }).update(data.headline);

        boxHeadline.insert(firstHeadlineLink);
        boxHeadline.insert(secondHeadlineLink);

        container.insert(boxHeadline);

        var layerCont = new Element('div', { 'class': 'layerCont' });
        var divFix = new Element('div', { 'class': 'clearfix' });

        if (data.articles[0])
        {
          var article = data.articles[0];

          if (Stern.isValidImageUrl(article.imageUrl)) {
            var boxLink = new Element('a', { 'class': 'boxImage', href: article.url, title: article.titleAttribute });
            var boxLinkImage = new Element('img', { src: article.imageUrl, alt: article.spitzmarke, title: article.titleAttribute, width: 120, height: 80 });
            boxLink.insert(boxLinkImage);
            divFix.insert(boxLink);
          }

          var boxLink = new Element('a', { 'class': 'h2', href: article.url, title: article.titleAttribute });
          if (article.spitzmarkeShort.length > 0)
          {
            var span1 = new Element('span').update(article.spitzmarkeShort);
            boxLink.insert(span1);
          }
          var span2 = new Element('span', { 'class': 'boxHeadline' }).update(article.headlineShort);
          boxLink.insert(span2);

          divFix.insert(boxLink);

        }
        layerCont.insert(divFix);

        if (data.articles[1])
        {

          var list = new Element('ul');
          var datalength = data.articles.length;
          if(data.ebookletImage)
          {
            datalength--;
          }
          for (i=1; i<2; i++) {

            var article  = data.articles[i];
            var listItem = new Element('li');

            var link = new Element('a', { href: article.url, title: article.titleAttribute });
            link.insert(new Element('span').update(article.spitzmarke));
            link.insert(new Element('br'));
            link.insert(new Element('span', { 'class': 'boxMoreExtraHeadline' }).update(article.headline));

            listItem.insert(link);
            list.insert(listItem);

          }

          if (data.ebookletLogo)
          {
            var listItem = new Element('li');
            var div  = new Element('div', {'class': 'boxPartnerlogo'});
            div.insert(new Element('span').update('präsentiert von'));
            var link = new Element('a', { href: data.ebookletLogoUrl, title: data.headline });
            link.insert(new Element('img', {'src': data.ebookletLogo}));
            div.insert(link);
            if(data.ebookletCount)
            {
              div.insert(new Element('img', {'src': data.ebookletCount + ad_server_rand, 'width': 1, 'height':1 }));
            }
            div.insert(new Element('br'));
            listItem.insert(div);
            list.insert(listItem);
          }
          layerCont.insert(list);
        }

        container.insert(layerCont);
        return container;
      }
    }
  },

  /**
   * The multipleslider needs a command chain
   */
  multiSlider:
  {
    moveToLeft: function(slider)
    {
      if (!slider.isActive) {
        slider.moveToRight();
        slider.setLeaderRight();
      }
    },
    moveToRight: function(slider)
    {
      if (!slider.isActive) {
        slider.moveToLeft();
        slider.setLeaderLeft();
      }
    }
  },


  /**
   * If an input-textfield owns this class, it's default value is removed
   * on focus and restored if no change has been made
   */
  emptyFields:
  {
    cssClass: 'jsRestoreBehaviour',
    currentVal: false,

    bind: function()
    {
      $$('.' + this.cssClass).each(function(item) {
        $(item).observe('focus', function(event) {
          var item = Event.findElement(event);
          Stern.emptyFields.currentVal = item.getValue();
          item.setValue('');
        });
        $(item).observe('blur', function(event) {
          var item = Event.findElement(event);
          if (item.getValue() == '') {
            item.setValue(Stern.emptyFields.currentVal);
          } else {
            $(item).stopObserving('focus');
          }
          Stern.emptyFields.currentVal = '';
        });
      });
    }
  },

  /**
  * If an input-textfield owns this class, it's current value is selected
  * on focus
  */
  selectAllFields:
  {
    cssClass: 'jsSelectAllBehaviour',

    bind: function()
    {
      $$('.' + this.cssClass).each(function(item)
      {
        $(item).observe('focus', function(event)
        {
          var item = Event.findElement(event);
          item.select();
        });
      });
    }
  },

  ajax:
  {
    encoding: 'ISO-8859-1',
    evalJS: 'force',

    /**
    * request the given url, ajax request
    */
    getUrl: function(url)
    {
      new Ajax.Request(Stern.ajax.addTimestamp(url), {
        method: 'get',
        encoding: Stern.ajax.encoding
      });
    },

    getParameters: function(formid, method)
    {
      if (formid && $(formid) && method == 'post') {
        return Form.serializeElements($(formid).getElements());
      }
      return false;
    },

    getMethod: function(method, params)
    {
      if (!method && params) {
        return 'post';
      } else if (!method) {
        return 'get';
      }
      return method;
    },

    /**
     * replaced the element given by id by the response of ajax request
     *
     * @param url: request this url
     * @param id: replace this DOM element
     * @param formid: submit this form if post
     * @param method: post/get(default)
     * @param cachable: no timestamp added to url if set (so its squid cachable)
     */
    replace: function(url, id, formid, method, cachable)
    {
      var params = this.getParameters(formid, method);
      var method = this.getMethod(method, params);
      if(!cachable) {
        url= Stern.ajax.addTimestamp(url);
      }

      new Ajax.Request(url, {
        method: method,
        parameters: params,
        encoding: Stern.ajax.encoding,
        evalJS: Stern.ajax.evalJS,
        onComplete: function(obj) {
          $(id).replace(obj.responseText);
          return false;
        }
      });
    },

    update: function(url, id, formid, method)
    {
      var params = this.getParameters(formid, method);
      var method = this.getMethod(method, params);

      new Ajax.Request(Stern.ajax.addTimestamp(url), {
        method: method,
        parameters: params,
        encoding: Stern.ajax.encoding,
        evalJS: Stern.ajax.evalJS,
        onComplete: function(obj) {
          $(id).update(obj.responseText);
          return false;
        }
      });
    },

    showIndicator: function(url)
    {
      ajaxUrl = Object.extend(url);
      Ajax.Responders.register(Stern.ajax.registerIndicator);
    },

    registerIndicator:
    {
      onCreate: function()
      {
        if(Ajax.activeRequestCount>0)
        {
          ajaxIndicator = new Element('div', { id: 'ajaxIndicator' });
          ajaxIndicatorContent = new Element('div', { id: 'ajaxIndicatorContent' });
          $(ajaxIndicator).hide();
          $(ajaxIndicatorContent).innerHTML = 'Laden...';
          $(ajaxIndicator).insert(ajaxIndicatorContent);
          $(ajaxUrl).insert(ajaxIndicator);
          $(ajaxIndicator).show();
        }
      },

      onComplete: function()
      {
        if(Ajax.activeRequestCount==0)
        {
          $(ajaxIndicator).hide();
        }
      }
    },

    lightbox: function(url, id, formid, method)
    {
      var params = this.getParameters(formid, method);
      var method = this.getMethod(method, params);

      new Ajax.Request(Stern.ajax.addTimestamp(url), {
        method: method,
        parameters: params,
        encoding: Stern.ajax.encoding,
        evalJS: Stern.ajax.evalJS,
        onComplete: function(obj) {

          var id = 'lbAjaxContent';
          var container = new Element('div', { id:id, 'class':'lbContent' });
          $(document.getElementsByTagName('body')[0]).insert(container);
          $(id).update(obj.responseText);

          var box = new Stern.lightbox.box($(id));
          box.activate();
          document.location = '#';

        }
      });
    },

    /**
     * add timestamp to url to disable ajax caching
     */
    addTimestamp: function(url)
    {
      var date = new Date();
      var timestamp = date.getTime();
      if(url.indexOf("?") != -1) {
        url= url + '&';
      } else {
        url= url + '?';
      }
      return url + 'random=' + timestamp;
    }
  },

  /**
   * Automatic placement of hooks inside the invisible placeholders
   */
  hooks:
  {
    containerClass: 'moduleHookContainer',
    contentClass: 'moduleHook',
    ignore: new Array(),

    addToIngoreList: function(hookId)
    {
    },

    place: function()
    {
      var container = $$('.' + this.containerClass);
      var hooks = $$('.' + this.contentClass);
      hooks.each(function(item, index) {
        item.removeClassName('displayNone');
        if (container[index]) {
          container[index].update(item);
        }
      });
    }
  },

  /**
   * User specific methods e.g. login
   */
  user:
  {
    loggedIn: function()
    {
      if(!Stern.cookie.get('sternLoggedIn')) {
        return false;
      }
      return (Stern.cookie.get('sternLoggedIn').length > 1);
    }
  },

  /**
   * pageHooks - register callbacks and trigger them manually
   *
   * Per default, upon DOM completion the so far registered
   * hooks will be executed
   */
  pageHooks:
  {
    storage: new Array(),

    register: function(callback)
    {
      this.storage.push(callback);
    },

    execute: function()
    {
      this.storage.each(function(callback) {
        callback();
      });
    }
  },

  /**
   * Navigational methods
   */
  navigation:
  {
    loginText: function()
    {
      if (Stern.user.loggedIn() && $('login_logout_links'))
      {
        $('login_logout_links').update('<a class="login track_me track_code_ajax_logout" href="/sso/logout" rel="nofollow">Ausloggen<\/a>|<a href="/sso/profil" class="register" rel="nofollow">Profil<\/a>');
      }
    },

    bookmarkLink: function()
    {
      var ausgabe = '';
      ausgabe += '<a class="spriteTopNavi homepage" rel="nofollow" ';
      ausgabe += 'href="#" onclick="Stern.navigation.bookmarkCreate(\'stern.de\', \'http://www.stern.de\');return false;"';
      ausgabe += '>Startseite<\/a>';
      document.write(ausgabe);
    },

    bookmarkCreate: function(title,url)
    {
      if (window.sidebar) // firefox
      {
         window.sidebar.addPanel(title, url, "");
      }
      else if(window.external) // ie
      {
         window.external.AddFavorite(url, title);
      }
      else if(window.opera && window.print) // opera
      {
         var elem = document.createElement('a');
         elem.setAttribute('href',url);
         elem.setAttribute('title',title);
         elem.setAttribute('rel','sidebar');
         elem.click();
      }
    }
  },

  /**
   * Blog methods
   *  o reloadPage() - if in blogs reload the page after login
   */
  blog:
  {
    isBlogPage: function()
    {
      var elem = $$('.gridBlog #Container #Subcontainer #Content #Nextpost');
      return elem != false && elem != undefined;
    },
    reloadPage: function()
    {
      if (Stern.blog.isBlogPage()) {
        document.location.href = document.location.href;
      }
    }
  },

  /**
  * forum methods
  *  o reloadPage() - if in forum reload the page after login
  */
 forum:
 {
   isForumPage: function()
   {
	  return document.location.href.indexOf('stern.de/foren/') > 0;
   },
   reloadPage: function()
   {
     if (Stern.forum.isForumPage()) {
       document.location.href = document.location.href;
     }
   }
 },

  /**
   * Comments methods
   */
  comments:
  {
    replaceLoginBox: function(url)
    {
      var box = $('SB18WriteCommentsBoxContainer');
      if (Stern.user.loggedIn() && box != undefined) {
        Stern.ajax.replace(url, 'SB18WriteCommentsBoxContainer', false, 'get');
      }
    }
  },

  /**
  * Plays Videos
  */
 video:
 {
    showPlayer: function(container, renderer, videoId, urlPrefix)
    {
      if (typeof stopPE != 'undefined')
      {
        stopPE['' + container + ''] = true; //stops the periodical executer
      }

      if (typeof urlPrefix == 'undefined')//enable urlPrefix from partial (neofonie topicpages)
      {
        urlPrefix = '';
      }
      $(container + '_bcVideo').show();
      $(container + '_bcVideo').src = urlPrefix + '?renderer=' + renderer + '&ajax=1&vid=' + videoId;
      $(container).hide();
    },

    hidePlayer: function(container)
    {
      if (typeof stopPE != 'undefined')
      {
          stopPE['' + container + ''] = true; //stops the periodical executer
      }

      if ($(container + '_bcVideo').src != 'about:blank')
      {
        $(container).show();
        $(container + '_bcVideo').src = 'about:blank';
        $(container + '_bcVideo').hide();
      }
    }
 },

 /**
  * Element methods
  */
 elements:
 {
   switchCheckboxes: function(className, newValue)
   {
     $$('.' + className).each(function(item) {
       item.checked = newValue;
     });
   }
 },

 /**
  * URL of the thumbnail server -> check
  */
 isValidImageUrl: function(url)
 {
   var match = new String(url).match(/^http(.*)\.(\w{3,4})$/i);
   return match != null;
 },

 /**
  * Print methods.
  */
 print:
 {
   showWindow: function(url)
   {
     printWindow = window.open(url, "Druckansicht", "width=660,height=550,status=yes,scrollbars=yes,resizable=yes");
     printWindow.focus();
   }
 }

};

// our class is initialized as soon as the dom is ready
Event.observe(window, 'load', function() {
  Stern.initialize();
});
