// this file needs the prototype.js framework

function info () {
  var offset_top_iframe_wrapper = $('iframe-wrapper')
  var vp_offset = offset_top_iframe_wrapper.viewportOffset()
  var c_offset = offset_top_iframe_wrapper.cumulativeOffset()
  var message = 'Info:\n+++++++++++++++++++++++++++++++\n'
  message += 'client height:\t'+$('body').getHeight()
  message += '\nfont smoothing: '+screen.fontSmoothingEnabled
  message += '\noffset iframe-wrapper: '+offset_top_iframe_wrapper.offsetTop
  message += '\nviewportOffset (Prototype):\n\tleft:'+vp_offset.left+'\n\ttop:'+vp_offset.top
  message += '\ncumulativeOffset (Prototype):\n\tleft:'+c_offset.left+'\n\ttop:'+c_offset.top
  message += '\nDifferenz between iframe.offsetTop and iframe.viewportOffset().top (Prototype):\n\t'+(offset_top_iframe_wrapper.offsetTop-vp_offset.top)
  message += '\niframe height: '+offset_top_iframe_wrapper.getHeight()
  message += '\nhtml offsetHeight: '+document.getElementsByTagName('html')[0].offsetHeight
  message += '\nhtml getHeight(): '+$(document.getElementsByTagName('html')[0]).getHeight()
  message += '\nall-wrapper height: '+$('all-wrapper').getHeight()
  return message

}

function debugMessage (s) {
  if ( debug ) {
    alert('*******************************************\n**** Debug Message for development ****\n*******************************************\n'+ s +'\n*******************************************')
  }
}

function consolelog (s) {
  if ( debug ) {
    try {
      console.log(s);
    }
    catch(e) {
      alert('no console.log object present: can\'t log');
    }
  };
}

function controlMainMenu (event) {
  // alert('we\'re inside')
  // alert('here we are:'+event.element().nodeName)
  // alert('event type:'+event.type) // what's the event?
  // get the element where the event was registered
  var elem = event.element()
  var main_panel = $('top-menu-main-wrapper')
  var sub_panel = $('top-menu-sub-wrapper')
  var teaser_panel = $('optionen')
  var iframe = $('iframe1')
  // some specials for the firmengr
  // if the href of elem is an absolute url with a fqdn we do not want to load in in the iframe but
  // accept the default behavior
  if ( elem.href ) {
    if ( elem.href.match(/^http/) ) {
      return
    };
  }
  else {
    return // if elem has no href set, we want to do nothing
  }
  event.stop()

  // we load the content into the iframe
  loadIntoIframe(elem)
  // if we are in the firmengr subdir we skip all of that (at least for now)
  if ( window.top.document.location.pathname.match(/firmengr/) ) {
    return
  };
  // which menu items does have submenus anyhow?
  // var items_with_sub_menu = ['zahnaerzte','patienten'] // not needed
  // alert('jo: '+items_with_sub_menu.indexOf(elem.id))
  // selecting all - but the current - activated main menu items and hiding
  // their sub menus

  var other_elems = main_panel.select('a.active').findAll(function(e){
    return e!=elem
  })
  // now lets unmark (active) the other elements
  other_elems.invoke('removeClassName','active')
  main_panel.select('li.active').invoke('removeClassName','active') // markierte LIs
  // ... and hide all submenus
  other_elems.each(function(e){
    if ( $(e.id+'-sub') ) {
      $(e.id+'-sub').hide() }
  })

  // we want to have something done, only if we have a click event
  if ( event.type == 'click' ) {

    // we also want to reset all selected elements in
    // the sub_panel, so we collect them and unmark them
    // but only if we didn't click on the element which triggered
    // the event in the first place
    sub_panel.select('a.active').invoke('removeClassName','active')
    // further we shall hide all teaser elements if we had a click
    // on the main menu
    teaser_panel.select('ul').each(function(e){
      e.hide() // without effects
      // Effect.BlindUp(e,{duration:0.5}) // some effects
    })

  }
  // if ( items_with_sub_menu.indexOf(elem.id) >= 0 ) {
  if ( $(elem.id+'-sub') ) {
    // debugMessage('clicked id: '+$(elem.id+'-sub').id)
    // unhiding the panel
    sub_panel.style.visibility = 'visible'
    // now showing the sub menu for main menu item selected
    $(elem.id+'-sub').show()
  }
  else {
    // in this case, we does not need to show the sub menu panel
    sub_panel.style.visibility = 'hidden'
  }
  elem.addClassName('active')
  elem.up().addClassName('active')
  // debugMessage('up: '+elem.up().nodeName)

}

function loadIntoIframe (link) {
  // debugMessage('inside loadIntoIframe (0).')
  var iframe = $('iframe1')
  var href = link.href
  // alert('HREF: '+href)
  if ( href != '#'  ) {
    // debugMessage('inside loadIntoIframe (1).')
    iframe.setAttribute('src',href)
    // debugMessage('frames["contentframe"]: '+frames['contentframe'].location.href)
    frames['contentframe'].location.href = href
    return true
  }
  // debugMessage('No link set yet.')
  return false
}

/**
  * Pawel 2011-12-09: Breadcrumbs logic is now in that class. There some extensions, that it behaves slightly differen in
  *                   Opticas Berufsgruppen. Also some bugs where fixed. E.g. it seems Breadcrumbs never worked for firmengr 
  *                   though nowbody seems to noticed that ;-)
  * For use there have to be an instance of that class. The initialization needs the container, where the breadcrumbs should be in
  * also the root element (generally rechenzentrum or firmengr) should be passed. 
  * The instance can then use the update() method with an argument which should be the location object for which the breadcrumbs should
  * be displayed. Basically it's the iframes location obj also saved in siteprops.loc. 
  **/
function Breadcrumbs (bc_container,root) {
  this.bc_container = $(bc_container)?$(bc_container):null;
  this.root = root;
  // this.loc_obj = null; // the location obj passed to the update method
  this.loc = '';
  this.path = '';
  this.crumbs = null; // list of crumbs.
  this.bc_pre_root = null;
  this.bc_post_root = null;
  this.bc_pre_root_url = '';
  this.root_index = null;
  
  this.initialize = function() {
    // if the bc_container is not an object, we return null
    if ( ! this.bc_container ) {
      return null;
    };
    return this; // return ourself so we can do chain stuff like with element
  };
  
  /**
    * Updates the breadcrumbs
    **/
  this.update = function(loc_obj) {
    /* clear everything */
    this.bc_container.update('');
    /* get location and path */
    this.loc = loc_obj.href;
    this.path = loc_obj.pathname;
    /* prepare crumbs (splitting) */
    this.crumbs = this.path.replace(/^\//,'').split('/'); // list of crumbs. We replace a leading slash to avoid empty items
    // consolelog('this.crumbs: '+this.crumbs+'\npathname: '+this.path);
    this.bc_pre_root = this.getPreRootCrumbs();
    this.bc_post_root = this.getPostRootCrumbs();
    /* check for exceptions of the rule. If there are none, we continue */
    if ( ! this.doBiggerException() ) {
      /* TODO fiddel it all together */
      /* TODO find out if we have to deal with some Optica special */
      this.buildDefault();
    };
  };
  
  /**
    * deals with exceptions and return true if there were any found for the current location
    **/
  this.doBiggerException = function() {
    // exception for search
    if ( this.loc.match(/search/) ) {
      // if we display the search cgi output we want to have displayed the search breadcrumb
      var a = $(document.createElement('a')).writeAttribute({href:siteprops.loc.href,target:'contentframe'}).update(mapUrlItem('search'))
      this.addToCrumbs(a);
      return true;
    };
    return false;
  };
  
  this.addToCrumbs = function(elem) {
    // consolelog('adding a crumb.');
    this.bc_container.appendChild(elem);
  };
  
  this.addGT = function() {
    var gt = new Element('span').update('&nbsp;>&nbsp;')
    this.addToCrumbs(gt);
  };
  
  this.buildDefault = function() {
    var bcs = this.getPostRootCrumbs();
    var current_bcs = null;
    var url = '';
    var special_name = '';
    
    // consolelog("crumbs ab root: "+bcs);
    for (var i=0; i < bcs.length; i++) {
      url = '';
      current_bcs = bcs.slice(0,i+1);
      if ( i == 0 ) {
        /* root behavior */
        // consolelog('current bcs: '+current_bcs);
        /* there are surtain things we have to consider at the root item */
        if ( this.path.match(/firmengr/) ) {
          url = this.getURLForCrumbs(current_bcs)+'/home.htm'
        }
        else {
          if ( rz.isZRZ() ) {
            url = this.getURLForCrumbs(current_bcs)+'/zrz/home'
          }
          else if ( rz.getName() == 'apo' ) {
            url = this.getURLForCrumbs(current_bcs)+'/apotheken/home'
          }
          else if ( rz.getName() == 'aerzte' ) {
            url = this.getURLForCrumbs(current_bcs)+'/aerzte/home';
          }
          else if ( rz.getName() == 'optica' ) {
            url = this.getURLForCrumbs(current_bcs)+'/optica/home';
          };
        };
      }
      else {
        /* post root behavior */
        if ( i == 1 && ! this.path.match(/firmengr/) ) {
          /* means we skip the element at the index 1. But this is intensional. 
             Those elements are e.g. zrz, apotheken, aerzte, optica. And we don't need them. 
             You could think we would, but the first Breadcrumb is generated in the root behavior above.
             However, we do need them when we are in firmengr, that's why the if statement checks for that. */
          continue;
        };
        // consolelog('post root behavior.');
        if ( rz && rz.getName() == 'optica' && this.path.match(/(berufsgruppen)|(sanitaetshaeuser).*leistungen/) ) {
          /* There is something special about opticas Berufsgruppen. When there is a breadcrumb structure 
             like "<Berufsgruppe> > Leistungen [> <something>]" it should be displayed as "Leistungen für <Berufsgruppe> [> <something>]".
             That means we need to suppress one breadcrumb to be added for <Berufsgruppe> and change the label of the second one slightly. 
             For that we look ahead one crumb. If it's value is 'leistungen' we suppress the display of the current crumb by continueing the loop.
             That next run sets a special_name variable. The special_name variable is then used later as label for the crumb. */
          if ( bcs[i+1] == 'leistungen' ) {
            /* we look ahead. If the next item is 'leistungen' we suppress the current item to be show by clearing the url variable */
            continue;
          }
          else if ( bcs[i] == 'leistungen' ) {
            /* now we know we suppressed the output of the <berufsgruppe> item. So now we change the name of the current item */
            special_name = mapUrlItem(bcs[i])+' für '+mapUrlItem(bcs[i-1]);
          };
        };
        
        /* if there's a label for the breadcrumb we add a separator and set the url */
        if ( mapUrlItem(bcs[i]) || special_name ) {
          this.addGT();
          url = this.getURLForCrumbs(current_bcs);
        };
      };
      
      /* if the url was set above, we add a breadcrumb */
      if ( url ) {
        // consolelog('now we are adding the crumb "'+mapUrlItem(bcs[i])+'" for url "'+url+'"');
        this.addToCrumbs(new Element('a', {href:url,target:'contentframe'}).update(special_name?special_name:mapUrlItem(bcs[i])));
        /* resetting a special name */
        special_name = '';
      };
    };
  };
  
  /**
    * The breadcrumbs before the root element do not change for a RZ. So we can set it only once.
    **/
  this.getPreRootCrumbs = function() {
    if ( ! this.bc_pre_root ) {
      this.bc_pre_root = this.crumbs.slice(0,this.getRootIndex()); /* TODO This may be empty in my home env (pawel). Could that be a problem? - I think not!*/
      this.bc_pre_root_url = '/'+this.bc_pre_root.join('/'); // we also set the pre root url once, as it will never change for a RZ:
      // consolelog("bc pre root url set: "+this.bc_pre_root_url);
    };
    return this.bc_pre_root;
  };
  
  /**
    * The Root index is always the same for an RZ. So once set we will not calculate it again.
    **/
  this.getRootIndex = function() {
    /* find root index it not already done */
    if ( ! this.root_index ) {
      for (var i=0; i < this.crumbs.length; i++) {
        if ( this.root == this.crumbs[i] ) {
          this.root_index = i;
          break; // once found we can exit the loop
        };
      };
    };
    return this.root_index;
  };
  
  /**
    * The return value of this method changes depending on the current location.
    * It return all crumbs after root containing root.
    **/
  this.getPostRootCrumbs = function() {
    return this.crumbs.slice(this.getRootIndex());
  };
  
  /**
    * As the URL always contains also the parts before root, that parts will be appended,
    * except when we pass a false to this method as second argument.
    **/
  this.getURLForCrumbs = function(crumbs,with_before_root) {
    var with_before_root = with_before_root?with_before_root:true; // true is the default value
    var url = crumbs.join('/');
    if (with_before_root) {
      url = this.bc_pre_root_url+'/'+url;
    };
    return url.replace(/\/\//,'/');
  };
  
  return this.initialize();
}


/**
  * Pawel 2011-12-09: DEPRECATED!! NOT USED ANYMORE. NOW USING Breadcrumbs CLASS
  **/
function buildBreadcrumbs () {
  // here we will build the breadcrumbs out of the content
  // this function will be called at the onload event of the
  // iframe content
  
  // we have a hidden span tag, were we have the breadcrumbs items
  // we clear the breadcrumbs, as we will build them from scratch
  siteprops.breadcrumbs_element.update('')
  
  var pathname = siteprops.loc.pathname;
  pathname = pathname.replace(/^\//,''); // that way we have no empty item when splitting by slash
  var crumbs = pathname.split('/')
  
  // we go through the array until we find the root, then we start to write
  // the breadcrumbs into the document
  
  // specials for search
  if ( siteprops.loc.href.match(/search/) ) {
    // debugMessage('Loc: '+siteprops.loc.href)
    // if we display the search cgi output we want to have displayed the search breadcrumb
    var a = $(document.createElement('a')).writeAttribute({href:siteprops.loc.href,target:'contentframe'}).update(mapUrlItem('search'))
    siteprops.breadcrumbs_element.appendChild(a)
    return // we have nothing else to do in this case
  };
  
  
  var past_root = false // we need this to check for the root in the pathname
  for (var i=0; i < crumbs.length; i++) {
    if ( crumbs[i] == root ) {
      past_root = true
      var root_index = i
    }
    if ( crumbs[i] && past_root ) {
      var url = '';
      if ( i == root_index + 1 ) { // the first item after root is zrz, apotheken, ... (the RZ_Category) and we do not want to display that item
        continue;
      }
      // --------
      if ( i > root_index ) {
        // debugMessage('bla: '+crumbs[i])
        if ( mapUrlItem(crumbs[i]) ) { 
          // we suppresses the '>' to be written, when a url item
          // is not in the url_items hash.
          // var gt = $(document.createElement('span')).update(' &gt; ')
          var gt = new Element('span').update('&nbsp;>&nbsp;')
          siteprops.breadcrumbs_element.appendChild(gt)
        }
        url = '/'+crumbs.slice(0,i+1).join('/')
      }
      // some extra for firmengr
      else if ( i == root_index && pathname.match(/firmengr/) ) {
        url = '/'+crumbs.slice(0,i+1).join('/')+'/home.htm'
      }
      else {
        if ( rz.isZRZ() ) {
          url = '/'+crumbs.slice(0,i+1).join('/')+'/zrz/home'
        }
        else if ( rz.getName() == 'apo' ) {
          url = '/'+crumbs.slice(0,i+1).join('/')+'/apotheken/home'
        }
        else if ( rz.getName() == 'aerzte' ) {
          url = '/'+crumbs.slice(0,i+1).join('/')+'/aerzte/home';
        }
        else if ( rz.getName() == 'optica' ) {
          url = '/'+crumbs.slice(0,i+1).join('/')+'/optica/home';
        };
        
      }
      // we cannot use the new Element function of Prototype, as IE really has problems with Elements
      // created in the iframe and then inserted in the parent window
      // But the following also does the trick
      var a = $(document.createElement('a')).writeAttribute({href:url,target:'contentframe'}).update(mapUrlItem(crumbs[i]))

      siteprops.breadcrumbs_element.appendChild(a)
    }
  }

}

function buildMenuConstellation () {
  var n1 = new Date()
  // if we are in the firmengr directory, we don't need a Menuconstelation (not now 09-07-14)
  // so we simply skip this function
  if ( siteprops.loc.pathname.match(/firmengr/) ) {
    return
  };
  // debugMessage('active option --: '+siteprops.teaser_options.select('.active').join(', '))
  // we build a menu constellation for the current content
  // var wrapper = $(window.parent)
  // var main_menu = $(wrapper.$('top-menu-main-wrapper'))
  // var sub_menu = $(wrapper.$('top-menu-sub-wrapper'))
  // var teaser_options = $(wrapper.$('optionen'))
  // var loc = window.self.location.pathname
  var pathname = siteprops.loc.pathname;
  // console.log('is_zrz: '+rz.isZRZ()+' ('+rz.getName()+')');
  if ( rz && rz.isZRZ() ) {
    pathname = pathname.replace(/zrz\//,''); // that replace is a quick hack after stucking all the zahnaerzte RZs in the zrz directory. This should be solved better in the future
  }
  else if ( rz && rz.getName() == 'apo' ) {
    pathname = pathname.replace(/apotheken\//,''); // have to do that with apotheker and all other RZs
  }
  else if ( rz && rz.getName() == 'aerzte' ) {
    pathname = pathname.replace(/aerzte\//,''); // have to do that with apotheker and all other RZs
  }
  else if ( rz && rz.getName() == 'optica' ) {
    pathname = pathname.replace(/optica\//,''); // have to do that with apotheker and all other RZs
  };
  
  var crumbs = pathname.split('/') // that replace is a quick hack after stucking all the zahnaerzte RZs in the zrz directory. This should be solved better in the future

  // debugMessage('crumbs from loc: '+crumbs+'')
  // we only need the crumbs above root
  var crumbs_ab_root = new Array()
  for (var i=0; i < crumbs.length; i++) {
    if ( crumbs[i] == root ) {
      crumbs_ab_root = crumbs.slice(i+1)
      break
    }
  }
  // console.log('crumbs_ab_root: '+crumbs_ab_root);

  // debugMessage('crumbs: '+crumbs_ab_root.join(', '))
  for (var i=0; i < crumbs_ab_root.length; i++) {
    // debugMessage('i: '+i)

    if ( i == 0 ) {

      // we just have to hide everything except the main menu
      // and aktivate the right item
      // hideDropdowns()
      toggleSubMenuPanel(false)
      // Pawel (2011-09-26): Hiding ontly the the "traditional" constellation, otherwise the Effect in i==3 will be executed every time
      if ( crumbs_ab_root.length <= 3 ) {
        toggleSubMenu(false,'')
      };
      deactivateMainMenuItems()
      deactivateSubMenuItems()
      if ( crumbs_ab_root.length <= 2 ) {
        toggleTeaserOptions('')
      };


      activateItem(crumbs_ab_root[0])
      if ( $(crumbs_ab_root[0]) ) {
        $(crumbs_ab_root[0]).up().addClassName('active') //unsauber
      };


      if ( $(crumbs_ab_root[0]+'-sub') ) {
        toggleSubMenuPanel(true)
        toggleSubMenu(true,crumbs_ab_root[0]+'-sub')
      }
    }
    else if ( i == 1 ) {
      deactivateTeaserItems()
      deactivateDropdownItems()
      
      // Pawel (2011-09-26):
      // The following if block should only be executed when we have a "traditional" constellation
      // (meaning: the old menu structure before extending the menu logic for optica);
      if ( crumbs_ab_root.length <= 3 ) {
        // consolelog("toggling: "+crumbs_ab_root.slice(0,i+1).join('_')+'_optionen')
        toggleTeaserOptions(crumbs_ab_root.slice(0,i+1).join('_')+'_optionen')
      }
      
      if ( siteprops.loc.pathname.endsWith('/') ) {
        var teaser_item_id = crumbs_ab_root.slice(0,i+1).join('_')+'_'
        var dropdown_item_id = 'dropdown_'+crumbs_ab_root.slice(0,i+1).join('_')+'_'
        // alert('teaser_item_id: '+teaser_item_id)
      }
      else {
        var teaser_item_id = crumbs_ab_root.slice(0,i+1).join('_').replace(/\.htm/,'').replace(/\.asp/,'')
        var dropdown_item_id = 'dropdown_'+crumbs_ab_root.slice(0,i+1).join('_').replace(/\.htm/,'').replace(/\.asp/,'')
        // alert('teaser_item_id: '+teaser_item_id)
      }
      // activate submenuitem
      // alert('activating 2'+crumbs_ab_root.slice(0,i+1).join('_'))
      activateItem(crumbs_ab_root.slice(0,i+1).join('_'))
      // activate teaseritem
      // alert('activating 3'+teaser_item_id)
      // debugMessage('$(teaser_item_id).up().nodeName: (1)'+$(teaser_item_id).up().nodeName)
      teaser_item_object = $(teaser_item_id)
      if ( teaser_item_object ) {
        activateItem($(teaser_item_id).up())
      }
      activateItem(dropdown_item_id)

    }
    else if ( i == 2 ) {
      if ( $(crumbs_ab_root[0]) ) {
        $(crumbs_ab_root[0]).up().removeClassName('active') //unsauber
      };
      
      deactivateTeaserItems()
      var teaser_item_id = crumbs_ab_root.slice(0,i+1).join('_').replace(/\.htm/,'').replace(/\.asp/,'')

      // the following is a really ugly hack, but it works for now (ugly because very specific)
      if ( teaser_item_id.match('.*kontakt_ansprechpartner_patienten' ) ) {
        teaser_item_id = teaser_item_id.replace(/^(.*_ansprechpartner_patienten).*$/,'$1')
      }
      else if ( teaser_item_id.match('.*kontakt_ansprechpartner_kunden' ) ) {
        teaser_item_id = teaser_item_id.replace(/^(.*_ansprechpartner_)kunden.*$/,'$1zahnaerzte')
      }
      else if ( teaser_item_id.match('.*kontakt_ansprechpartner_interessenten' ) ) {
        teaser_item_id = teaser_item_id.replace(/^(.*_ansprechpartner_)interessenten.*$/,'$1zahnaerzte')
      }
      else {
        // debugMessage("it didn't match")
      }
      var dropdown_item_id = 'dropdown_'+teaser_item_id
      teaser_item_object = $(teaser_item_id)
      if ( teaser_item_object ) {
        activateItem(teaser_item_object.up())
      }
      if ( $(dropdown_item_id) ) {
        activateItem(dropdown_item_id)
      };
      // console.log("teaser_item_id (index==2): "+teaser_item_id);
    }
    else if ( i == 3 ) {
      // Pawel (2011-09-23): We use that case in the Optica menu
      // In that case, we have an additional sub menu (a sub-sub menu if you like) which replaces the actual sub menu.
      // It's very confusing!
      
      // Pawel (2011-10-10)
      // Some longer pathes in other RZs like Seminarrückblick in ZRZ could reach this level.
      // As for now we only need it in optica, we skip the loop with the following condition
      // to avoid unexpected behavior
      if ( rz.getName() != 'optica' ) {
        break; 
      };
      var ssub_menu_id = crumbs_ab_root.slice(0,3).join('_')+'-sub';
      var sub_menu = $(crumbs_ab_root[0]+'-sub');
      var ssub_menu = $(ssub_menu_id);
      
      
      
      /* We generate a submenu dynamically as they are all the same (in optica) at that level 
         If there is a DOM element for the ssub-menu, though we skip the dynamic generation. 
         This way we can have a customized ssub-menu if needed.
      */
      if ( !ssub_menu ) {
        /* preparing data for template evaluation */
        var data = {
          sub1: crumbs_ab_root[1], 
          sub2: crumbs_ab_root[2],
          sub3: mapUrlItem(crumbs_ab_root[2])
        }
        /* adding new UL to the DOM */
        siteprops.sub_menu.insert(siteprops.dyn_optica_ssub_template.evaluate(data));
        /* adding the base to the dropdown menu */
        // consolelog('new base id: '+'sub_'+crumbs_ab_root.slice(0,3).join('_')+'_leistungen');
        siteprops.dropdown_menu.addBase('sub_'+crumbs_ab_root.slice(0,3).join('_')+'_leistungen');
        
        /* setting ssub_menu to new element */
        ssub_menu = $(ssub_menu_id);
      };
      
      activateItem("sub_"+crumbs_ab_root.slice(0,i+1).join('_'));
      
      if ( sub_menu && ssub_menu ) {
        // console.log("sub_menu.id: "+sub_menu.id+"\nssub_menu.id: "+ssub_menu.id+'\nteaser_item_id: '+teaser_item_id);
        sub_menu.hide();
        if ( ! ssub_menu.visible() ) {
          // ssub_menu.show(); // without effect
          Effect.BlindDown(ssub_menu, {duration: 0.5}); // with effect 
        };
        /* hide options */
        siteprops.teaser_options.hide();  // using toggleTeaserOptions functions leads to problems, 
                                          // that's why we simply hide the teaser_options DIV directly
      };
    }
    else if ( i == 4 ) {
      // console.log("crumbs_ab_root["+i+"]: ("+crumbs_ab_root[i]+")");
      // console.log("id for teaser toggle: sub_"+crumbs_ab_root.slice(0,i).join('_')+'_optionen');
      // This time we copy the dropdown UL, so we do not have to write everything twice (in the teaser)
      var teaser_item_id = 'sub_'+crumbs_ab_root.slice(0,i+1).join('_').replace(/\.htm/,'').replace(/\.asp/,'')
      var dropdown_item_id = 'dropdown_'+teaser_item_id; // that's a dropdown item
      var dropdown = $('sub_'+crumbs_ab_root.slice(0,i).join('_')+'_dropdown'); // that's the dropdown
      var ul_content = '';
      var optionen = null;
      var optionen_id = '';
      
      if ( dropdown ) {
        // consolelog("---- dropdown.id: "+dropdown.id);
        var re = new RegExp(dropdown.id);
        optionen_id = dropdown.id.replace(/_dropdown$/,'_optionen'); // the id of the options in the teaser right deducted from the dropdown id
        if ( ! $(optionen_id) ) { // we only do all that, if we havn't created that element before, meaning it already exists
          // consolelog("++++++ Creating new element!");
          /* creating new UL Element */
          optionen = new Element('UL',{id: optionen_id, style:'display:none;'}); // creating UL Element
          /* adding additional LI to the new Element as well as the edited content of the dropdown */
          var link_name = $(dropdown.id.replace(/_dropdown$/,'')).innerHTML; //.truncate(30);
          
          // consolelog("link name: "+link_name);
          var first_li_tag = '<li class="main"><a id="'+dropdown.id.replace(/_dropdown$/,'_')+'" href="'+crumbs_ab_root.slice(0,i).join('/')+'/" target="contentframe">'+link_name+'</a></li>'
          /* rewrite all IDs */
          ul_content = dropdown.innerHTML;
          ul_content = ul_content.replace(/dropdown_([^\"]*)/g,'$1'); // removing the prefix for the A ids
          /* stucking everything together and adding it to the DOM */
          optionen.insert(first_li_tag).insert(ul_content);
          siteprops.teaser_options.insert(optionen);
          // consolelog("###### optionen:\n"+optionen.innerHTML+"\n######");
        };
        teaser_item_object = $(teaser_item_id)
        // consolelog("activating teaser item id: "+teaser_item_id);
        // consolelog("activating dropdown item id: "+dropdown_item_id);
        if ( teaser_item_object ) {
          activateItem(teaser_item_object.up())
        }
        if ( $(dropdown_item_id) ) {
          activateItem(dropdown_item_id)
        };
        /* display the options */
        toggleTeaserOptions(optionen_id);
      };
    }
  }
  var n2 = new Date();
  // consolelog("Zeit für Menüaufbau in ms: "+(n2-n1));
}

function toggleSubMenuPanel (show) {
  if ( show ) {
    siteprops.sub_menu.style.visibility = 'visible'
    return
  }
  siteprops.sub_menu.style.visibility = 'hidden'
}

function toggleSubMenu (show,id) {
  if ( show ) {
    $(id).show()
    // alert('bla: '+$(wrapper.$(id)).id)
    return
  }
  siteprops.sub_menu.select('ul').each(function(e){
    // debugMessage(e.id)
    e.hide()
  })
  return

}

/*
function hideDropdowns () {
  return
  siteprops.dropdowns.select('ul').each(function(e){
    e.hide()
  })
  return
}
*/

function toggleTeaserOptions (id) {
  // consolelog("toggleTeaserOptions id: "+id);
  var obj = $(id)?$(id):null;
  
  if ( obj ) {
    // consolelog('objs id is: '+obj.id)
    siteprops.teaser_options.show()
    if ( obj != siteprops.active_teaser_option ) {
      try {
        if ( siteprops.active_teaser_option ) {
          siteprops.active_teaser_option.hide()
        };
      }
      catch(e) {}

      Effect.BlindDown(obj,{duration:0.5}) // some effects
      // obj.show() // without effects
      // debugMessage('we just had that effect')
    }
    // the following set's the height of the teaser_options div to the height the obj will have
    // that way everything below the menu obj is showing will not scroll up and down, when clicking through the menu
    siteprops.teaser_options.style.height = obj.getHeight()+'px';
    // siteprops.active_teaser_option = obj;
  }
  else {
    // debugMessage('obj is not in the documents')
    siteprops.teaser_options.hide()
    try {
      if ( siteprops.active_teaser_option ) {
        siteprops.active_teaser_option.hide()
      };
      // consolelog('we hid the active_teaser_option: '+siteprops.active_teaser_option.id);
    }
    catch(e){
      // consolelog('there was nothing to hide')
    }
  }
  
  siteprops.active_teaser_option = obj
}

function deactivateMainMenuItems () {
  // var wrapper = $(window.parent)
  // var main_menu = $(wrapper.$('top-menu-main-wrapper'))
  siteprops.main_menu.select('.active').invoke('removeClassName','active')
}

function deactivateDropdownBackground() {
  // siteprops.dropdown_background.hide()
}

function deactivateSubMenuItems () {
  siteprops.sub_menu.select('a.active').invoke('removeClassName','active')
}

function deactivateTeaserItems () {
  // var wrapper = $(window.parent)
  // var teaser = $(wrapper.$('optionen'))
  siteprops.teaser_options.select('li.active').invoke('removeClassName','active')
}

function deactivateDropdownItems () {
  // var wrapper = $(window.parent)
  // var dropdowns = $(wrapper.$('dropdowns'))
  siteprops.dropdowns.select('a.active').invoke('removeClassName','active')
}

function activateItem (elem) {
  if ( Object.isString(elem) ) {
    elem = $(elem)
  }
  if ( elem ) {
    elem.addClassName('active')
  }
}

function wrapMe () {
  //alert('we are not wrapped. Implementation of automaticaly wrapping us will follow soon')
}

function buildStructures () {
  // we have to build structures like the breadcrumbs and
  // an appropriate menu constellation out of the content
  // consolelog('buildStructures was called.');

  // if we are not inside an iframe, we should be able to wrap
  // this window with the other stuff (menu, ..)
  // if ( window.top == window.self ) {
    // in this case we are not wrapped
    // wrapMe()
  // }
  if ( ! siteprops.breadcrumbs ) {
    siteprops.breadcrumbs = new Breadcrumbs(siteprops.breadcrumbs_element,root);
  }
  siteprops.breadcrumbs.update(siteprops.loc);
  // buildBreadcrumbs()
  buildMenuConstellation()
  // now we tell flexcroll to update the teaser scrollbars
  // debugMessage('updating flexcroll scrollbars')
  if(siteprops.teaser_right.scrollUpdate) {
    // we first check for the method availability then setting a timeout,
    // cause there are some problems when doing it without.
    setTimeout(function() {siteprops.teaser_right.scrollUpdate()}, 10);
  }
}

function mapUrlItem (item) {
  if ( url_items.keys().indexOf(item) >= 0 ) {
    return url_items.get(item)
  }
  // man könnte die Labels aus derm innerHTML der teaser Menüs herausnehmen,
  // braucht dann aber hier mehr informationen, statt nur item (glaub ich grad)
  return ''
}

function whoIsMandanten () {
  // to abstract the menu a bit, we call the Zahnärzte, Apotheker, ... zahnaerzte an has
  // to figure out which one is the right at the currrent page.
  // This figuring out happens in this function

  /* !!!!! This function is absolete !!! */
  return 'Zahnärzte'
}

function TeaserItem (id,list_of_regexpr,invert,show_in_rzs,only_when_logged_in) {
  /* *********************************************************************************
  Objects of that Class will be Teaser Objects which has to be visible only
  with the context of specific iframe contents
  Arguments:
  id:              is the id of the teaser item or the DOM object
  list_of_regexpr: is a Array of regexpressions. Does a URL of an iframe content match against one of that
                   regexpressions the object will be displayed (unless the third argument is true)
  invert:          if true, the regexpressions in list_of_regexpr specifies iframecontents where the teaser
                   object need not to be displayed
  show_in_rzs:     if the item with "id" should be shown/hidden only in a specific RZ, the names of the RZs
                   can be passed with this argument as array.
  only_when_logged_in:
                   If true checkVisibility() method will check for whether the visitor is logged in or not.
                   Default is false

  Attributes:
  this.item:        The DOM object of the teaser item
  this.regexprs:    The list of regexpressions


  Methods:
  this.checkVisibility(url):  deals with hiding and unhiding the item depending on the passed url


  ********************************************************************************* */

  // first we check if an object or an id as a string was passed
  this.item = Object.isString(id)?$(id):id; // this.item is the teaser item
  this.regexprs = list_of_regexpr
  this.invert = invert?invert:false; //default of invert is false
  this.show_in_rzs = show_in_rzs?show_in_rzs:null; // rz is by default null
  this.only_when_logged_in = only_when_logged_in?only_when_logged_in:false // default is false

  this.checkVisibility = function(url) {
    if ( ! this.item ) {
      return; // nothing to do if, there's no DOM Object
    };
    
    var show_item = false

    for (var pi = this.regexprs.length - 1; pi >= 0; pi--){
      if ( url.match(this.regexprs[pi]) ) {
        matched = true;
        break;
      }
      else {
        matched = false;
      }
    };
    
    // We want the following behavior between matched and invert:
    // matched    invert    wanted behavior
    //    0         0             0
    //    1         0             1
    //    0         1             1
    //    1         1             0
    // 
    // Our wanted behavior can be formalized as: (matched || invert) && !(matched && invert)
    // which is the same as (matched && !invert) || (!matched && invert)
    show_item = (matched && !invert) || (!matched && invert)
      
      /* deprecated since 2010-02-13 ->
      if ( url.match(this.regexprs[pi]) ) {
        if ( this.invert ) {
          show_item = false
        }
        else {
          show_item = true
        }
        break
      }
      else {
        if ( this.invert ) {
          show_item = true
        }
        else {
          show_item = false
        }
      }
    };  <- deprecated since 2010-02-13*/
    
    // filter on the rz information
    // if this.show_in_rzs is not null and the this.show_in_rzs contains the currently viewed RZ,
    // and further show_item is true, we will check, if we are currently in the RZ
    // in which item should be displayed
    // debugMessage('bla: '+window.top.rz.getName())
    if ( this.show_in_rzs != null && show_item ) {
      for (var i = this.show_in_rzs.length - 1; i >= 0; i--){
        // debugMessage('this.show_in_rzs[i]: '+this.show_in_rzs[i])
        if ( window.top.rz.getName() == this.show_in_rzs[i] ) {
          show_item = true;
          break;
        }
        else {
          show_item = false;
        }
      };
      
    };
    
    if ( (show_item && this.only_when_logged_in && login.loged_in) || (show_item && !this.only_when_logged_in) ) {
      // there are two possibilities when to show the item:
      // Basically we only want to display it when show_item is true.
      // The second constraint is, whether it should be only displayed when logged in. In that case we also check IF
      // we are logged in.
      // But if only_when_logged_in is false show_item is the only constraint
      if ( this.item ) {
        this.item.show();
      }
    }
    else {
      if ( this.item ) {
        this.item.hide()
      }
    }
  };

}

function SitesProperties () {
  // this is a constructor for an Object which will hold some often used dom objects
  this.iframe = $('iframe1')
  this.main_menu = $('top-menu-main-wrapper')
  this.sub_menu = $('top-menu-sub-wrapper')
  this.teaser_options = $('optionen')
  this.active_teaser_option = null // this.teaser_options.select('active')
  // debugMessage(this.active_teaser_option.join(', '))
  this.breadcrumbs_element = $('crumbs')
  this.breadcrumbs = null;
  this.dropdowns = $('dropdowns')
  this.dropdown_background = $('dropdown-menu-img-background')
  this.teaser_right = $('teaser-right')
  this.thumber_reload = true
  this.dropdown_menu = null;
  this.thumber_box = $('thumber-box-wrapper')
  this.thumber_iframe = $('thumber')
  // the pages_showing_thumber array items are regular expressions, so be carefull with dots "." and stuff.
  this.pages_showing_thumber = new Array('home\/?$','news','impressum','sitemap','leistungen_fuer\/?$','leistungen_fuer\/patienten\/?$','aerztedirekt','leistungen\/auszahlung','leistungen\/');
  this.iframe_wrapper = $('iframe-wrapper')
  this.teaser_right_wrapper = $('teaser-right-wrapper')
  this.teaser_right_hidden_pages = new Array('macchina') // array of pages that hide the teaser-right
  this.teaser_right_visible = true // default teaser-right appearence
  this.teaser_right_default_bg_value = this.teaser_right.getStyle('background-color');

  // teaser items with specific display pages
  this.teilzahlungsicon_box = new TeaserItem('teilzahlungsicon_box',new Array('patienten\/'))
  this.gebuehren_teilen_box = new TeaserItem('gebuehren_teilen_box',new Array('gebuehrenrechner\/$','zahnaerzte\/$'))
  this.komplettgebuehr_box = new TeaserItem('komplettgebuehr_box',new Array('gebuehrenrechner','zahnaerzte\/$'))
  this.gueldibaer_box = new TeaserItem('gueldibaer_box',new Array('patienten\/'))
 // this.die_16_gruende_box = new TeaserItem('die_16_gruende_box',new Array('vorteile\.htm'))
  this.sofortkontakt_box = new TeaserItem('sofortkontakt_box',new Array('kontakt\/','firmengeschichte\/'))
  this.empfehlung_box = new TeaserItem('empfehlung_box', new Array('empfehlung\/$'))
  this.empfehlung_box2 = new TeaserItem('empfehlung_box2', new Array('empfehlungsformular\.asp'))
  this.jobs_box = new TeaserItem('jobs_box', new Array('jobs'))
  this.firmengr_all_addresses_box = new TeaserItem('firmengr_all_addresses_box', new Array('firmengr\/home.htm','firmengr\/kontakt.asp'))
  this.seminare_rueckblick_box = new TeaserItem('seminare_rueckblick_box', new Array('seminare\/'))
  this.zrz_waehlen_box = new TeaserItem('zrz_waehlen_box', new Array('zrz_waehlen'))
  this.aktuelles_abz_patienten_box = new TeaserItem('aktuelles_abz_patienten_box', new Array('\/patienten\/$'), false, new Array('abz'))
  this.aktuelles_abz_zahnaerzte_box = new TeaserItem('aktuelles_abz_zahnaerzte_box', new Array('\/zahnaerzte\/$'), false, new Array('abz'), true);
  this.aktuelles_abz_box = new TeaserItem('aktuelles_abz_box', new Array('home\/$'), false, new Array('abz'),true);
  this.empfehlungsportal_box = new TeaserItem('empfehlungsportal_box', new Array('zahnaerzte\/','home\/'), false, new Array('abz'))
  this.factoring_box = new TeaserItem('factoring_box', new Array('\/zahnaerzte\/$'));
  this.unternehmerabend_box = new TeaserItem('unternehmerabend_box', new Array('zahnaerzte\/$'), false, new Array('dzr_n','dzr_s','hza','frh'))
  this.apodirekt_login_box = new TeaserItem('apodirekt-login-box', new Array('\/leistungen_fuer\/','\/home\/$'), false, new Array('apo'));
  this.aerztedirekt_login_box = new TeaserItem('aerztedirekt-login-box', new Array('\/leistungen\/','\/home\/$'), false, new Array('aerzte'));
  this.gogreen_zahnaerzte_box = new TeaserItem('gogreen_zahnaerzte_box',new Array('zahnaerzte\/'),false, new Array('abz'));
  this.gogreen_patienten_box = new TeaserItem('gogreen_patienten_box',new Array('patienten\/'),false, new Array('abz'));
  
  // Templates
  this.dyn_optica_ssub_template = new Template('\
    <ul id="berufsgruppen_#{sub1}_#{sub2}-sub" style="display:none;"> \
      <li><a id="sub_berufsgruppen_#{sub1}_#{sub2}_leistungen" \
             href="berufsgruppen/#{sub1}/#{sub2}/leistungen/" \
             target="contentframe">Leistungen für #{sub3}</a></li> \
      <li><a id="sub_berufsgruppen_#{sub1}_#{sub2}_formulare_bestellen" \
             href="berufsgruppen/#{sub1}/#{sub2}/formulare_bestellen/" \
             target="contentframe">Formulare bestellen</a></li> \
      <li><a id="sub_berufsgruppen_#{sub1}_#{sub2}_empfehlung" \
             href="berufsgruppen/#{sub1}/#{sub2}/empfehlung/" \
             target="contentframe">Empfehlung</a></li> \
    </ul>'
  );
  
  // we add some methods, too. 
  this.dealWithThumber = function() {
    if ( ! this.thumber_box ) {
      return; // if there's no thumber_box, we simply return 
    };
    // the following is to hide the news box when we are not in home or another page we wish to display the thumber
    // debugMessage('bla: '+this.iframe.contentWindow.location)
    var loc = this.iframe.contentWindow.location+''
    var show_thumber = false

    for (var pi = this.pages_showing_thumber.length - 1; pi >= 0; pi--){
      if ( loc.match(this.pages_showing_thumber[pi]) ) {
        show_thumber = true
        break
      }
      else {
        show_thumber = false
      }
    };

    if ( show_thumber ) {
      if ( this.thumber_reload ) {
        this.thumber_reload = false
        // debugMessage('thumber_reload is '+this.thumber_reload)
        this.thumber_iframe.contentWindow.location = this.thumber_iframe.contentWindow.location.href
      }
      // debugMessage('thumber_reload is '+this.thumber_reload)
      this.thumber_box.show()
    }
    else {
      this.thumber_box.hide()
      this.thumber_reload = true
    }

  }
  
  this.setDefaultTeaserRightBackground = function() {
    this.teaser_right.setStyle({background:this.teaser_right_default_bg_value})
  };

  this.dealWithTeaserItems = function() {
    // consolelog("location: "+this.iframe.contentWindow.location.href)
    var loc = this.iframe.contentWindow.location.href
    this.teilzahlungsicon_box.checkVisibility(loc)
    this.gebuehren_teilen_box.checkVisibility(loc)
    this.komplettgebuehr_box.checkVisibility(loc)
    this.gueldibaer_box.checkVisibility(loc)
  //  this.die_16_gruende_box.checkVisibility(loc)
    this.sofortkontakt_box.checkVisibility(loc)
    this.empfehlung_box.checkVisibility(loc)
    this.empfehlung_box2.checkVisibility(loc)
    this.jobs_box.checkVisibility(loc)
    this.firmengr_all_addresses_box.checkVisibility(loc)
    this.seminare_rueckblick_box.checkVisibility(loc)
    this.zrz_waehlen_box.checkVisibility(loc)
    this.aktuelles_abz_patienten_box.checkVisibility(loc)
    this.aktuelles_abz_zahnaerzte_box.checkVisibility(loc)
    this.aktuelles_abz_box.checkVisibility(loc)
    this.empfehlungsportal_box.checkVisibility(loc)
    this.factoring_box.checkVisibility(loc);
    this.unternehmerabend_box.checkVisibility(loc);
    this.apodirekt_login_box.checkVisibility(loc);
    this.aerztedirekt_login_box.checkVisibility(loc);
    this.gogreen_patienten_box.checkVisibility(loc);
    this.gogreen_zahnaerzte_box.checkVisibility(loc);
  };

  this.dealWithTeaserRightVisibility = function() {
    var loc = this.iframe.contentWindow.location.href
    var show = true // default behavior
    for (var i = this.teaser_right_hidden_pages.length - 1; i >= 0; i--) {
      if ( loc.match(this.teaser_right_hidden_pages[i])) {
        if ( this.teaser_right_visible ) {
          // the body tag of the content which should not have a teaser_right should be marked
          // with style="visibility:hidden;". The reason is, that the script needs some time
          // to hide the teaser_right and it's ugly to see the content of the iframe first in a
          // narrow view, then expanded to the right.
          // So we simply hide the content and show it after some time (now 400ms) when the teaser_right
          // is hidden.
          var frame_body = this.iframe.contentWindow.document.getElementsByTagName('BODY')[0]
          this.hideTeaserRight()
          setTimeout(function() {frame_body.style.visibility = 'visible'}, 400);
        }
        // if this.teaser_right_visible is false we simply return, as the teaser-right is not being displayed and we do not
        // need to hide it in this case, we are done
        return
      };
    };
    // if we didn't match above, we asume the default which is to display the teaser-right
    this.showTeaserRight()

  };

  this.showTeaserRight = function() {
    // the steps to show the teaser are:
    // 1.) set attribute colspan="1" in the tablecell td#iframe-wrapper
    // 2.) set width of iframe-wrapper to 656px
    // 3.) change style display:table-cell to the tablecell td#teaser-right-wrapper
    // 4.) add className "flexcroll" to div#teaser-right
    this.iframe_wrapper.setAttribute('colspan','1')
    this.iframe_wrapper.setStyle({width: "656px"})
    this.teaser_right_wrapper.show()
    this.teaser_right.addClassName('flexcroll')

    // lastly we set the objects variable to true, so we always know wheather the teaser-right is being displayed or not
    this.teaser_right_visible = true
  };

  this.hideTeaserRight = function() {
    // the steps to hide the teaser are
    // 1.) add attribute colspan="2" to the tablecell td#iframe-wrapper
    // 2.) set width of iframe-wrapper to auto
    // 3.) add style display:none to the tablecell td#teaser-right-wrapper
    // 4.) remove className "flexcroll" from div#teaser-right (because of IE)
    this.iframe_wrapper.setAttribute('colspan','2')
    this.iframe_wrapper.setStyle({width: "auto"})
    this.teaser_right_wrapper.hide()
    this.teaser_right.removeClassName('flexcroll')
    // lastly we set the objects variable to false, so we always know wheather the teaser-right is being displayed or not
    this.teaser_right_visible = false
  };

}

function Browser () {
  // Objects of this Class will identify the Browser on initialization and return the name with the method getName()
  var name = 'none'
  var version = ''
  var os = ''
  var lang = ''

  var initialize = function() {
    version = navigator.appVersion
    os = navigator.platform
    lang = navigator.language

    if (navigator.userAgent.toLowerCase().indexOf("opera") != -1) {
      name = 'opera'
    }
    else if (navigator.userAgent.toLowerCase().indexOf("msie") != -1) {
      name = 'ie'
    }
    else if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1) {
      name = 'ff'
    }
    else if (navigator.userAgent.toLowerCase().indexOf("chrome") != -1) {
      name = 'chrome'
    }
    else if (navigator.userAgent.toLowerCase().indexOf("safari") != -1 ) {
      name = 'safari'
    }
    else if (navigator.userAgent.toLowerCase().indexOf("mozilla") != -1) {
      name = 'moz'
    }
    else {
      name = navigator.appName
    }
  };

  initialize()

  this.getName = function() {
    return name
  };

  this.getVersion = function() {
    return version
  };

  this.getOSName = function() {
    return os
  };

  this.getLang = function() {
    return lang
  };
}

function URLSpecialLoads (iframe_obj) {
  // this Class takes care about loading specific pages passed in the url to to main frame into the content frame
  // e.g. dzr.de/drgn/rechenzentrum/zrz/?impressum should load the impressum into the iframe
  // we will have a hash which stores the key like "impressum" and the url which has to be load into the iframe
  // An Object has to be instanciated by passing the iframe_obj.
  // There are 2 Methods, one to add some keys and urls to the hash
  // and one which takes care of the loading
  this.initialize = function() {
    this.loc = window.top.location
    this.iframe = iframe_obj?iframe_obj:$('iframe1'); // Pawel (2011-05-11): added default value for this.iframe ($('iframe'))
    this.table = $H()
  };
  this.addKeyURLPair = function(key,value) {
    this.table.set(key,value)
  };
  this.loadIntoFrame = function(url) {
    try {
      this.iframe.setAttribute('src',url)
    }
    catch(e) {
      frames['contentframe'].location.href = url
    }
  };
  this.takeCareOfLoading = function() {
    var args = this.loc.search
    if ( args != '' ) { // if we have some arguments after splitting the location on the "?"
      // debugMessage('we have args')
      // consolelog('length of table: '+this.table.get('impressum'))
      this.table.each(function(pair) { // we iterate over the hash table
        // consolelog('iterating pair: '+pair.key)
        if ( args.match(pair.key) ) { //and if the args (after the ? in loc) matches against a key in the table
          this.loadIntoFrame(pair.value) // we load the url into the iframe
        };
      }.bind(this))
    };
  };
  this.initialize()
}

function RZName () {
  this.args = window.top.location.search
  this.dom = window.top.document.domain
  this.rz = ''
  this.is_zrz = false
  
  
  this.isZRZ = function() {
    return this.is_zrz;
  };
  
  this.getName = function() {
    if ( this.rz ) {
      return this.rz;
    };
    // here we get which rechenzentrum we are diplaying
    // debugMessage('args: '+this.args+'\ndom: '+this.dom);
    // if ( this.args.match(/\?dzr_n/) && this.dom.match(/d?zr(-online)?\.de/) ) {
    if ( this.args.match(/(\?|\&)dzr_n/) && this.dom.match(/((dzr)|(d?zr-online))\.((de)|(home))/) ) {
      // dzr is special because there are several domains for it but no disambiguation of dzr_n or dzr_s
      // via domain, but via arguments passed in the url
      this.rz = 'dzr_n'
      this.is_zrz = true
    }
    else if ( this.args.match(/(\?|\&)dzr_s/) || this.dom.match(/((dzr)|(d?zr-online))\.((de)|(home))/) ) {
      this.rz = 'dzr_s'
      this.is_zrz = true
    }
    else if ( this.args.match(/\?abz/) || this.dom.match(/abz-zr\.((de)|(home))/) ) {
      this.rz = 'abz'
      this.is_zrz = true
    }
    else if ( this.args.match(/\?hza/) || this.dom.match(/hza-online\.((de)|(home))/) ) {
      this.rz = 'hza'
      this.is_zrz = true
    }
    else if ( this.args.match(/\?frh/) || this.dom.match(/frh\.((de)|(home))/) ) {
      this.rz = 'frh'
      this.is_zrz = true
    }
    else if ( this.args.match(/firmengr/) || this.dom.match(/drgueldener\.((de)|(home))/) ) {
      this.rz = 'firmengr'
    }
    else if ( this.dom.match(/optica\.(de|home)/) ) {
      this.rz = 'optica'
    }
    else if ( this.dom.match(/bonafama/) ) {
      this.rz = 'bonafama'
    }
    else if ( this.dom.match(/apotheken/) ) {
      var loc = document.location.href;
      if ( loc.match(/\/apotheken\//) ) {
        this.rz = 'apo';
      }
      else if ( loc.match(/\/aerzte\//) ) {
        this.rz = 'aerzte';
      }
      else {
        // default is apo. This is needed i.e. for the splash screen
        this.rz = 'apo';
      }
      
    }
    else if ( this.dom.match(/privatabrechnung/) ) {
      this.rz = 'aerzte'
    }
    // debugMessage('rz: '+this.rz)
    return this.rz
  };
  
  this.getName(); // initializing
}

function Rechenzentrum () {
  // here we have a collection of DOM objecs which depend on the displayed RZ

  // this attributes will be set, depending on the RZ loaded
  this.name = ''
  this.long_name = ''
  this.long_name_dat = ''
  this.det_nom = ''  // Determiner Nominative (starting with lower character)
  this.det_dat = ''
  this.det_nom_cap = ''  // Determiner Nominative Capitalized (starting with upper character)
  this.det_dat_cap = ''
  this.det_gen = ''
  this.loc = window.top.location+''
  this.rz = ''
  this.acronym = ''
  this.telnr = ''
  this.faxnr = ''
  this.addr1 = ''  // erste Adresszeile
  this.addr2 = ''  // zweite Adresszeile
  this.addr3 = ''  // dritte Adresszeile
  this.addr4 = ''  // vierte Adresszeile
  this.is_zrz = false // all zrz share a lot of code together, other RZs maybe do not need. This gives us the posibility to check whether we are in a zrz or not
  /**
    The banner for the normal layout. That banner contains the logo inside the banner.
    For the wide layout this variable holds the logos div. The Banner is then stored in banner_wide variable.
  **/
  this.banner = null; 
  this.banner_wide = null; // banner for wide layout


  // this atributes mostly represent DOM objects which will be updated with the values from the
  // attributes defined above
  
  this.mainscreen = false // if we are in the main screen, this should be set to true (it's false when we are e.g. in the splash screen)
  this.firmengr = false // special case if we are on the firmengr page
  
  this.isZRZ = function() {
    return this.is_zrz;
  };

  this.getRechenzentrum = function() {
    var rz = new RZName() // we make an instance of RZName()
    this.is_zrz = rz.isZRZ();
    this.rz = rz.getName() // and then we call the Method getName() and write it to the same variable
    if ( !this.rz) {
      // consolelog('rz unknown: '+this.rz);
      if ( this.loc.match(/\.home/) ) {
        window.top.location = 'http://www.drgueldener.home'
      }
      else {
        window.top.location = 'http://www.drgueldener.de'
      }
    }
  };
  
  this.getName = function() {
    return this.rz;
  };

  this.setFromDomain = function() {
    // consolelog('Rechenzentrum->setFromDomain(): '+this.rz);
    // in this method we set some attributes of this object depending on the RZ
    
    if ( WIDE_LAYOUT ) {
      // setting the banner_wide for all ZRZs
      if ( this.is_zrz ) {
        this.banner_wide.setStyle({backgroundImage: "url(../../des_imgs/banner_wide_zrz.jpg)"});
      }
      // setting banner_wide for apo-aerzte
      else if ( this.rz == 'apo' || this.rz == 'aerzte' ) {
        this.banner_wide.setStyle({backgroundImage: "url(../../des_imgs/banner_wide_apo.jpg)"});
      }
      else if ( this.rz == 'optica' ) {
        this.banner_wide.setStyle({backgroundImage: "url(../../des_imgs/banner_wide_apo.jpg)"});
      }
      else if ( this.rz == 'firmengr' ) {
        this.banner_wide.setStyle({backgroundImage: "url(../des_imgs/banner_wide_zrz.jpg)"}); /* TODO change img src */
      };
    }
    
    if ( this.rz == 'dzr_s' ) {
      this.acronym = 'DZR'
      this.name = 'DZR Stuttgart'
      this.long_name = 'Deutsche Zahnärztliche Rechenzentrum'
      this.long_name_dat = 'Deutschen Zahnärztlichen Rechenzentrum'
      this.det_nom = 'das'
      this.det_nom_cap = 'Das'
      this.det_dat = 'dem'
      this.det_dat_cap = 'Dem'
      this.det_gen = 'des'
      if ( this.mainscreen ) {
        if ( ! WIDE_LAYOUT ) {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/dzr_banner.jpg)" });
        }
        else {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/logo_wide_dzr.png)" });
        };
        
      };
      this.telnr = '0711 61947-40'
      this.faxnr = '0711 61947-50'
      this.addr1 = 'DZR - Deutsches Zahnärztliches Rechenzentrum GmbH'
      this.addr2 = 'Marienstraße 10'
      this.addr3 = '70178 Stuttgart'
    }
    else if ( this.rz == 'dzr_n' ) {
      this.acronym = 'DZR'
      this.name = 'DZR Neuss'
      this.long_name = 'Deutsche Zahnärztliche Rechenzentrum'
      this.long_name_dat = 'Deutschen Zahnärztlichen Rechenzentrum'
      this.det_nom = 'das'
      this.det_nom_cap = 'Das'
      this.det_dat = 'dem'
      this.det_dat_cap = 'Dem'
      this.det_gen = 'des'
      if ( this.mainscreen ) {
        if ( ! WIDE_LAYOUT ) {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/dzr_banner.jpg)" });
        }
        else {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/logo_wide_dzr.png)" });
        };
        
      };
      this.telnr = '02131 5673-0'
      this.faxnr = '02131 5673-56'
      this.addr1 = 'DZR - Deutsches Zahnärztliches Rechenzentrum GmbH'
      this.addr2 = 'Hermann-Klammt-Straße 7'
      this.addr3 = '41460 Neuss'
    }
    else if ( this.rz == 'abz' ) {
      this.acronym = 'ABZ-ZR'
      this.name = 'ABZ-ZR'
      this.long_name = 'Zahnärztliche Rechenzentrum für Bayern'
      this.long_name_dat = 'Zahnärztlichen Rechenzentrum für Bayern'
      this.det_nom = 'das'
      this.det_nom_cap = 'Das'
      this.det_dat = 'dem'
      this.det_dat_cap = 'Dem'
      this.det_gen = 'des'
      if ( this.mainscreen ) {
        if ( ! WIDE_LAYOUT ) {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/abz_banner.jpg)" });
        }
        else {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/logo_wide_abz.jpg)",height:'80px' }); 
        };
        
      };
      this.telnr = '08142 6520-6'
      this.faxnr = '08142 6520-892'
      this.addr1 = 'ABZ - Zahnärztliches Rechenzentrum für Bayern GmbH'
      this.addr2 = 'Oppelner Straße 3'
      this.addr3 = '82194 Gröbenzell'
    }
    else if ( this.rz == 'hza' ) {
      this.acronym = 'HZA'
      this.name = 'HZA'
      this.long_name = 'Hanseatische Zahnärztliche Abrechnungs- und Service- Gesellschaft mbH'
      this.long_name_dat = 'Hanseatischen Zahnärztlichen Abrechnungs- und Service- Gesellschaft mbH'
      this.det_nom = 'die'
      this.det_nom_cap = 'Die'
      this.det_dat = 'der'
      this.det_dat_cap = 'Der'
      this.det_gen = 'der'
      if ( this.mainscreen ) {
        if ( ! WIDE_LAYOUT ) {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/hza_banner.jpg)" });
        }
        else {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/logo_wide_hza.jpg)" });
        };
        
      };
      this.telnr = '040 237802-0'
      this.faxnr = '040 237802-78'
      this.addr1 = this.acronym+' - '+this.long_name
      this.addr2 = 'Heidenkampsweg 51'
      this.addr3 = '20097 Hamburg'
    }
    else if ( this.rz == 'frh' ) {
      this.acronym = 'FRH'
      this.name = 'FRH'
      this.long_name = 'Freie Rechenzentrum Heilberufe'
      this.long_name_dat = 'Freien Rechenzentrum Heilberufe'
      this.det_nom = 'das'
      this.det_nom_cap = 'Das'
      this.det_dat = 'dem'
      this.det_dat_cap = 'Dem'
      this.det_gen = 'des'
      if ( this.mainscreen ) {
        if ( ! WIDE_LAYOUT ) {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/frh_banner.jpg)" });
        }
        else {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/logo_wide_frh.jpg)" }); 
        };
        
      };
      this.telnr = '0711 36511-200'
      this.faxnr = '0711 36511-201'
      this.addr1 = this.acronym+' - '+this.long_name
      this.addr2 = 'Marienstraße 12'
      this.addr3 = '70178 Stuttgart'
    }
    else if ( this.rz == 'firmengr' ) {
      this.name = 'Home'
      // alert(''+this.name)
      // there is now this.mainscreen set in firmengr, so we don't check for that.
      if ( ! WIDE_LAYOUT ) {
        this.banner.setStyle({backgroundImage: "url(../des_imgs/firmengr_banner.jpg)"}); 
      }
      else {
        // this.banner.setStyle({backgroundImage: "url(../des_imgs/logo_wide_firmengr.jpg)" }); /* TODO change img src */
        this.banner.remove();
      };
    }
    else if ( this.rz == 'apo' ) {
      this.acronym = 'Apotheken'
      this.name = 'Apotheken'
      this.long_name = 'Apotheken- und Ärzte Abrechnungszentrum Dr. Güldener GmbH'
      this.long_name_dat = 'Apotheken- und Ärzte Abrechnungszentrum Dr. Güldener GmbH'
      this.det_nom = 'die'
      this.det_nom_cap = 'Die'
      this.det_dat = 'den'
      this.det_dat_cap = 'den'
      this.det_gen = 'der'
      if ( this.mainscreen ) {
        if ( ! WIDE_LAYOUT ) {
          
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/apobanner_neu_abgedunkelt_2.png)" });
        }
        else {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/logo_wide_apo.jpg)",height:'74px' }); 
        };
        
      };
      this.telnr = '0711 61947-0'
      this.faxnr = '0711 61947-43'
      this.addr1 = 'Apotheken- und Ärzte- Abrechnungszentrum<br/>Dr. Güldener GmbH'
      this.addr2 = 'Marienstraße 10'
      this.addr3 = '70178 Stuttgart'
    }
    else if ( this.rz == 'aerzte' ) {
      this.acronym = 'Ärzte'
      this.name = 'Ärzte'
      this.long_name = 'Apotheken- und Ärzte Abrechnungszentrum Dr. Güldener GmbH'
      this.long_name_dat = 'Apotheken- und Ärzte Abrechnungszentrum Dr. Güldener GmbH'
      this.det_nom = 'die'
      this.det_nom_cap = 'Die'
      this.det_dat = 'den'
      this.det_dat_cap = 'den'
      this.det_gen = 'der'
      if ( this.mainscreen ) {
        if ( ! WIDE_LAYOUT ) {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/apobanner_neu_abgedunkelt_2.png)" });
        }
        else {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/logo_wide_apo.jpg)",height:'74px' }); 
        };
        
      };
      this.telnr = '0711 96000-210';
      this.faxnr = '0711 96000-272';
      this.addr1 = 'Apotheken- und Ärzte- Abrechnungszentrum<br/>Dr. Güldener GmbH';
      this.addr2 = 'Marienstraße 10';
      this.addr3 = '70178 Stuttgart';
    }
    else if ( this.rz == 'optica' ) {
      /* TODO Ergänzen */
      this.acronym = 'Optica'
      this.name = 'Optica'
      this.long_name = 'Optica blablabla'
      this.long_name_dat = 'Optica blablabla'
      this.det_nom = 'die'
      this.det_nom_cap = 'Die'
      this.det_dat = 'den'
      this.det_dat_cap = 'den'
      this.det_gen = 'der'
      if ( this.mainscreen ) {
        if ( ! WIDE_LAYOUT ) {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/optica_banner.jpg)" });
        }
        else {
          this.banner.setStyle({backgroundImage: "url(../../des_imgs/logo_wide_apo.jpg)",height:'74px' }); 
        };
        
      };
      this.telnr = '0711 61947-0'
      this.faxnr = '0711 61947-43'
      this.addr1 = 'Optica Abrechnungszentrum<br/>Dr. Güldener GmbH'
      this.addr2 = 'Marienstraße 10'
      this.addr3 = '70178 Stuttgart'
    }
    else {
      // debugMessage('we have no RZ set!!!')
      // if we are here, we should be in at drgueldener.de, so we could make a redirect here
      // to that page if somebody should try to access drgueldener.de/some/path
      if ( this.loc.match(/\.home/) ) {
        window.top.location = 'http://www.drgueldener.home'
      }
      else {
        window.top.location = 'http://www.drgueldener.de'
      }

    }
  };

  this.setDirectContactAddress = function() {
    if ( this.mainscreen ) {
      // items which shall be updated:
      $$('.rz_addr1')[0].update(this.addr1)
      $$('.rz_addr2')[0].update(this.addr2)
      $$('.rz_addr3')[0].update(this.addr3)
      $$('.rz_addr4')[0].update(this.addr4)
      $$('.rz_telnr')[0].update(this.telnr)
      $$('.rz_faxnr')[0].update(this.faxnr)
      // now the map src
      if ( $('sofortkontakt_map') ) {
        var map_src = '../../des_imgs/gebiete/'+this.rz+'_gebiet_karte.png'
        $('sofortkontakt_map').setAttribute('src',map_src)
      };
    };
    
  };

  // initialize
  this.finalizeInit = function() {
    if ( $('rechenzentrum') ) {
      // we only want to 
      this.main_menu_label = $('rechenzentrum')
      this.doc = $(window.top.document)
      this.banner = $('header-bild')
      this.banner_wide = $('banner-wide');
      this.impressum_link = $('impressum_link')
      this.mainscreen = true
    }
    else if ( $('firmengr') ) {
      this.banner = $('header-bild');
      this.banner_wide = $('banner-wide');
      this.doc = $(window.top.document)
      this.impressum_link = $('impressum_link')
      this.firmengr = true
    };
    this.setFromDomain();
    if ( this.mainscreen || this.firmengr ) {
      if ( this.banner ) {
        this.banner.show() // the banner should be hidden by default, so we call the
                           // show() method here as the backgrounds should now be set.
      };
    };
    this.setDirectContactAddress()
    url_items.set('rechenzentrum',this.name) // That's the label for the breadcrumbs
    // debugMessage(url_items.get('rechenzentrum'))

    if ( this.mainscreen  || this.firmengr ) {
      this.doc.title = this.name+': Dr. Güldener Firmengruppe'
      try {
        this.main_menu_label.update(this.name)
      }
      catch(e) {}
      // debugMessage(window.top.document.title)

      // setting the link to the impressum
      if ( this.rz != 'firmengr' ) {
        this.impressum_link.writeAttribute({href:'impressum_'+this.rz+'.htm'})
      }
      else {
        var link = 'javascript:alert("Hier wird nachher ein Fenster geöffnet.")'
        var link = '#'
        this.impressum_link.writeAttribute({href:'impressen.htm'})
        //this.impressum_link.writeAttribute({href:link})
        //this.impressum_link.observe('click',function(e) {
        //  e.stop()
        //  // we open the imprassa.htm page in a new window
        //  window.open('impressen.htm')
        //})
      }
    };
  };
  
  this.initialize = function() {
    this.getRechenzentrum();
    // consolelog('this.rz: '+this.rz);
  };
  
  this.initialize();
  
  
  
  
  



}

function dynChanges () {
  // the names of the classes which contents will be replaced
  // sub_XX_XXXX means substitute and then the variable name
  // It's just a convention not a must
  var acronyms = siteprops.iframe.getElementsByClassName2('span','sub_rz_acronym')
  var long_names = siteprops.iframe.getElementsByClassName2('span','sub_rz_long_name')
  var long_names_dat = siteprops.iframe.getElementsByClassName2('span','sub_rz_long_name_dat')
  var names = siteprops.iframe.getElementsByClassName2('span','sub_rz_name')
  var addresses2 = siteprops.iframe.getElementsByClassName2('span','sub_rz_addr2')
  var determiners_nom = siteprops.iframe.getElementsByClassName2('span','sub_rz_det_nom')
  var determiners_dat = siteprops.iframe.getElementsByClassName2('span','sub_rz_det_dat')
  var determiners_nom_cap = siteprops.iframe.getElementsByClassName2('span','sub_rz_det_nom_cap')
  var determiners_dat_cap = siteprops.iframe.getElementsByClassName2('span','sub_rz_det_dat_cap')
  var determiners_gen = siteprops.iframe.getElementsByClassName2('span','sub_rz_det_gen')


  // ....
  // now let's change that stuff
    // var log = new logging('logging')

  // after updating the elements we call the show() method on it, as that elements should be hidden by default,
  // because otherwise a possible default can be seen when loading with slow connections.
  acronyms.each(function(e) {
    // ie needs the element e extended with the prototype methods.
    // ff seems to do that automaticaly
    $(e).update(rz.acronym).show()
  })
  long_names.each(function(e) {
    // ie needs the element e extended with the prototype methods.
    // ff seems to do that automaticaly
    $(e).update(rz.long_name).show()
  })
  long_names_dat.each(function(e) {
    // ie needs the element e extended with the prototype methods.
    // ff seems to do that automaticaly
    $(e).update(rz.long_name_dat).show()
  })
  names.each(function(e) {
    // ie needs the element e extended with the prototype methods.
    // ff seems to do that automaticaly
    $(e).update(rz.name).show()
  })
  addresses2.each(function(e) {
    // ie needs the element e extended with the prototype methods.
    // ff seems to do that automaticaly
    $(e).update(rz.addr2).show()
  })

  // The Determiners will be set here
  determiners_nom.each(function(e) {
    // ie needs the element e extended with the prototype methods.
    // ff seems to do that automaticaly
    $(e).update(rz.det_nom).show()
  })
  determiners_dat.each(function(e) {
    // ie needs the element e extended with the prototype methods.
    // ff seems to do that automaticaly
    $(e).update(rz.det_dat).show()
  })
  determiners_nom_cap.each(function(e) {
    // ie needs the element e extended with the prototype methods.
    // ff seems to do that automaticaly
    $(e).update(rz.det_nom_cap).show()
  })
  determiners_dat_cap.each(function(e) {
    // ie needs the element e extended with the prototype methods.
    // ff seems to do that automaticaly
    $(e).update(rz.det_dat_cap).show()
  })
  determiners_gen.each(function(e) {
    // ie needs the element e extended with the prototype methods.
    // ff seems to do that automaticaly
    $(e).update(rz.det_gen).show()
  })

  // some changes has to be made only if logged in, so we will stuck it in this if condition,
  // so we need not to execute this code on the majority of the pages

  if ( login ) {
    if ( login.loged_in ) {
      var user_names = siteprops.iframe.getElementsByClassName2('span','sub_user_name')
      var client_nos = siteprops.iframe.getElementsByClassName2('span','sub_client_no')
      user_names.each(function(e) {
        $(e).update(login.user_name).show()
      })
      client_nos.each(function(e) {
        $(e).update(login.client_no).show()
      })
    };
  }

  // some changes are done not by searching for span tags. The Title of the Page is One of it
  // although this solution should be changed in the future this will do the trick for now
  if ( window.top.rz.name ) {
    var t = siteprops.iframe.contentWindow.document.title
    siteprops.iframe.contentWindow.document.title = t.replace(/DZR Stuttgart/,window.top.rz.name)
  };
}

function LoginObject () {
  this.initialize = function() {
    this.login_form = $('login-form')
    this.login_passwd_input = $('login-passwd')
    this.login_rzchoose = $('login-rzchoose')
    this.login_status = $('login-status')
    this.submit_button = $('login-submit')
    this.login_box = $('login-base_dropdown')
    this.login_box_background = $('login-dropdown-background')
    this.login_box_base = $('login-base')
    this.schleier = $('schleier')
    this.login_info_box = $('login-info')
    this.came_from = ''
    this.loged_in = false // are we loged in or not?
    this.secured_elements = $$('.secure') // all elements marked with the secure class
    this.user_name = '' // here we will store the name of the user
    this.user_name_shorted = '' // sometimes the username is to long to display, so here we store the shorter version
    this.client_no = ''
    this.user_name_max_length = 30 // if the user_name is longer than that value we will shorten it
    this.tout_backup = login_dropdown.tout
    this.main_body = $(document.getElementsByTagName('html')[0]) // we need the body element, too, BUT as IE7 Has some Problems with using the Body Element we will take the html Element instead. The Problem was, that, using BODY the setting body.style = 'auto' moved the hole page to the right (around 10px, that's the width of the scroll bars). It seems that in IE7 the scroll bars are set for the HTML Element.

    // we will submit the form when the user presses the array img
    this.submit_button.observe('click',this.logMeIn.bind(this))
    // we want to login with the "Return" when we typed in the password, so we will observe the passwd field for a keypress event
    this.login_passwd_input.observe('keyup',this.submitLoginFormOnReturnPress.bindAsEventListener(this))
    //consolelog('initialized')
    // the login_timeout variable holds the timeout object which checks periodicaly if the user is still
    // logged in at the server, that is, if the servers session is still valid
    this.login_timeout = null
    // login timeout in seconds
    this.login_tout = 600
    this.timeout_logout = false // this will be setted to true if the logout is forced due to a timeout
  };

  this.submitLoginFormOnReturnPress = function(e) {
    if ( e.keyCode == '13' ) {
      // consolelog('we hit the enter key')
      this.logMeIn()
      return
    };
    // consolelog('we hit the keyCode: '+e.keyCode)
  };

  this.logMeIn = function () {
    // debugMessage('we are here: logMeIn() Method, First line ')
    // var uname = $('uname')
    // var passwd = $('password')
    //consolelog('inside logMeIn')
    var params = '' // some additional parameters if needed
    if ( ! this.login_rzchoose ) {
      // this one is needed, if we have no user input about the RZ we're logging in to,
      // which is the usual case except if the user is logging in from the firmengr page
      // where there is no RZ information present.
      params = '&login-rzchoose='+window.top.rz.rz
    };
    var form_data = this.login_form.serialize()
    var ajax_request = new Ajax.Request('../../login.asp',{
      method: 'post',
      parameters: form_data+'&ajax=1&posted=yes'+params,
      onSuccess: this._logMeIn_OnSuccess.bind(this)
    })
  }

  this.logMeOut = function (e) {
    e.stop()
    //consolelog('logging out')
    var ajax_request = new Ajax.Request('../../logout.asp',{
      method: 'post',
      onSuccess: this._logMeOut_OnSuccess.bind(this)
    })
  }

  this.changeStuff = function (transport) {
    // debugMessage('we are here: changeStuff() Method, First line ')
    // here we change some stuff after login
    // var data = transport.responseText.split('|')
    // var text = 'Sie sind eingelogt als: '+data[0]+' '+data[1]+'. <a href="javascript:logMeOut();">ausloggen</a>'
    // var text = 'Sie sind eingeloggt als '+transport.responseText+'. <br/><a href="#" id="logout-button">ausloggen</a>'

    // if we are at this point, we know that we are logged in and we can start set the timeout for the check if we are still
    // logged in now.
    this.login_timeout = this.timeoutAction.bind(this).delay(this.login_tout)

    this.user_name = transport.responseText.split('||')[0]
    this.client_no = transport.responseText.split('||')[1]

    // we check if the user_name is not too long
    if ( this.user_name.length > this.user_name_max_length ) {
      this.user_name_shorted = this.user_name.substring(0,this.user_name_max_length)+' ...' // we shorten the user_name
    }
    else {
      this.user_name_shorted = this.user_name // otherwise user_name_shorted is the same as user_name
    }
    var text2 = 'Sie sind eingeloggt als '+this.user_name_shorted //+' '+Url.encode(this.user_name)

    if ( this.came_from != '' ) {
      siteprops.iframe.contentWindow.location = this.came_from
    };
    // reloading anprechpartner.htm which will then redirect to the kunden ansprechpartner page
    if ( siteprops.iframe.contentWindow.location.href.match(/interessenten_ansprechpartner/) ) {
      // debugMessage('redirecting')
      setTimeout(function() {siteprops.iframe.contentWindow.location.href = 'kontakt/ansprechpartner/';}, 10);
    };
    this.came_from = '' // we reset this variable
    // we do not want to show a dropdown when loged in, so we set the objects blocking variable to true
    login_dropdown.block_dropdowns = true
    // and we hide the dropdown manually
    login_dropdown.dropUp()
    Effect.Fade(this.schleier, {duration:1.0,from:0.5,to:0}) // hiding schleier the fancy way, with an effect
    // this.schleier.hide() // hiding schleier without an effect
    this.login_box_base.update('Ausloggen')
    this.login_box_base.removeClassName('login-loged-out')
    this.login_box_base.addClassName('login-loged-in')
    // return // just for development
    this.login_form.hide()
    //consolelog('changeStuff: we are here.')
    // this.login_status.setStyle({background:'#4f4'}).update(text)
    // $('logout-button').observe('click',this.logMeOut.bind(this))
    Event.stopObserving(this.login_box_base,'click')
    this.login_box_base.observe('click',this.logMeOut.bind(this))
    //consolelog('changeStuff: we are now here.')
    this.login_info_box.update(text2).writeAttribute("title", this.user_name)
    //consolelog('removing secure class markers')
    this.secured_elements.each(function(e) {
      //consolelog('remove secure class name from '+e.id)
      e.removeClassName('secure')
    })
    this.login_status.update('Sie sind eingeloggt.').show()
    // alert('Sie haben sich erfolgreich eingeloggt.')
    siteprops.dealWithTeaserItems();
  }

  this.unchangeStuff = function () {
    // if somebody logs out he/she comes here, and we reset the login_timeout
    window.clearTimeout(this.login_timeout)
    // return // just for development
    // reloading kontakt/ansprechpartner/index.htm which will then redirect to the interessenten ansprechpartner page
    if ( siteprops.iframe.contentWindow.location.href.match(/kunden_ansprechpartner/) ) {
      // debugMessage('redirecting')
      setTimeout(function() {siteprops.iframe.contentWindow.location.href = 'kontakt/ansprechpartner/';}, 10);
    }
    // If we are displaying some content beneath the service dir, we redirect to zrz/zahnaerzte.htm
    if ( siteprops.iframe.contentWindow.location.href.match(/\/service/) ) {
      // debugMessage('we want to redirect you.')
      setTimeout(function() {siteprops.iframe.contentWindow.location.href = 'zahnaerzte/';}, 100)
    }
    var text = 'Sie sind nicht eingeloggt.'
    this.login_box_base.update('Log-In')
    this.login_box_base.removeClassName('login-loged-in')
    this.login_box_base.addClassName('login-loged-out')
    this.login_form.show()
    this.login_info_box.update('')
    this.login_status.setStyle({background:'none'}).update(text).hide()
    login_dropdown.tout = this.tout_backup
    //consolelog('unchangeStuff: we are here.')
    // we unset the Event Listener for the unlock button/link/whatever
    // Event.stopObserving($('logout-button'),click)
    try {
      //console.log('unsetting the Event Listener')
      Event.stopObserving(this.login_box_base,'click')
    }
    catch(e) {}
    // $('logout-button').stopObserve('click',this.logMeOut.bind(this))
    // $('login_box_base').stopObserve('click',this.logMeOut.bind(this))
    //console.log('unchangeStuff: we are now here.')

    this.secured_elements.each(function(e) {
      e.addClassName('secure')
    })
    login_dropdown.block_dropdowns = false
    if ( this.timeout_logout ) {
      alert('Sie wurden aus Sicherheitsgründen automatisch ausgeloggt.')
      this.timeout_logout = false // we reset it now
    };
    siteprops.dealWithTeaserItems();
  }

  this.timeoutAction = function() {
    // debugMessage('timeout Accured.')
    // we set this to true, and reset it if we are not really logged out in the amILogedIn() Method
    this.timeout_logout = true
    // if we waited for this.login_tout seconds we call the amILogedIn() Method, as we still could be logged in.
    // doing so, we call the server, which by the way will refresh the session and we should stay logged in.
    this.amILogedIn()
  };

  this.resetTimeout = function() {
    // first we clear the timeout
    window.clearTimeout(this.login_timeout)
    // then we set a new one
    this.login_timeout = this.timeoutAction.bind(this).delay(this.login_tout)
  };

  this.amILogedIn = function () {
    var ajax_request = new Ajax.Request('../../am_i_loged_in.asp',{
      method: 'post',
      parameters: 'rz='+window.top.rz.rz,
      onSuccess: this._amILogedIn_OnSuccess.bind(this)
    })
  }

  this.showLoginBox = function() {
    // this method will be called when somebody who is not loged in requests a protected page
    // we will use the DropdownMenu Methods and Attributes to show the Login Form
    login_dropdown.dropdown = this.login_box
    login_dropdown.base = this.login_box_base
    login_dropdown.dropDown()
    // We'll use a small Effect to make a little more fancy. The "to" Option should be the same as that in the CSS
    // for the schleier Object
    Effect.Appear(this.schleier, {duration:1.5,from: 0.0,to: 0.5 })
    // this.schleier.show() // showing the schleier Object without an effect.
    // we set the overflow property to hidden, because schleier schows with 100% x 100% which is the viewport area,
    // but sometimes maybe we can scroll and then there is no schleier at the front.
    this.main_body.setStyle({overflow:'hidden'})
    this.schleier.observe('click',this.cancelLogin.bind(this))
    login_dropdown.tout = 120
  };

  this.cancelLogin = function() {
    // for canceling the login procedure we need to do the following steps
    Effect.Fade(this.schleier, {duration:1.0,from:0.5,to:0}) // hiding schleier the fancy way, with an effect
    // this.schleier.hide() // hiding schleier without an effect
    // setting body overflow property back to auto
    this.main_body.setStyle({overflow: "auto"})
    // we will make the tout time very short, so that the login dropdown disapears very quickly
    login_dropdown.tout = 0.1
    // we need a dropup object to drop up, and the login_box it that object.
    login_dropdown.dropup = this.login_box
    login_dropdown.dropUp()
    // if the previous page the user visited was not the same as the one in the came_from variable,
    // we will send him back in the history, otherwise we will send him to the "zahnaerzte" page, as in that case
    // he was already loged in.
    // SUPPLEMENTAL: this is not working, so we will send the user directly to the "zahnaerzte" page, at least for now
    if ( siteprops.iframe.contentWindow.location.href.match(this.came_from) ) {
      // just in case you read it for the third time (Pawel), This if statement is absolutely unnecessary. I just leave it
      // here, so that I remember, that I tried that approach already.
      // So this all would also work with only the else path of this statement. (Writen by Pawel)
      // if the come_from value matches against the current iframe content url we will send the user to the "home" page
      siteprops.iframe.contentWindow.location.href = 'zahnaerzte/'
    }
    else {
      // history.back()
      siteprops.iframe.contentWindow.location.href = 'zahnaerzte/'
    }
    // now we set the tout to the default value
    login_dropdown.tout = this.tout_backup

  };

  this.dealWithLoginBase = function(loc) {
    if ( loc.href.match(/\/patienten\//) && !this.loged_in ) {
      this.login_box_base.hide();
    }
    else {
      this.login_box_base.show();
    }
  };

  this.cancelLoginWithoutRedirect = function() {
    // for canceling the login procedure we need to do the following steps
    Effect.Fade(this.schleier, {duration:1.0,from:0.5,to:0}) // hiding schleier the fancy way, with an effect
    // this.schleier.hide() // hiding schleier without an effect
    // setting body overflow property back to auto
    this.main_body.setStyle({overflow: "auto"})
    // we will make the tout time very short, so that the login dropdown disapears very quickly
    login_dropdown.tout = 0.1
    // we need a dropup object to drop up, and the login_box it that object.
    login_dropdown.dropup = this.login_box
    login_dropdown.dropUp()
    login_dropdown.tout = this.tout_backup
  };

  this._amILogedIn_OnSuccess = function(transport) {
    if ( transport.responseText != 'False' && true ) { // the "&& true" ist for debbuging purpose only
      // we don't check for "True" as if it's true we'll get a |-seperated list of data
      // alert('yeah, we are true')
      this.loged_in = true
      if ( ! this.timeout_logout ) { // if we are logged in and this check happens only when we were logged in before,
                                     // we do only have to run changeStuff() Method if this is a real new page load
        this.changeStuff(transport)
      }
      else {
        this.timeout_logout = false // so we were logged in and hence we reset this to false
      }

    }
    else {
      // alert('damn, we are false')
      this.loged_in = false
      this.unchangeStuff()
    }
  }

  this._logMeOut_OnSuccess = function(transport) {
    if ( transport.responseText == 'True' ) {
      // alert('yeah, we are true')
      this.loged_in = false
      this.unchangeStuff()
    }
    else {
      // alert('damn, we are false')
      this.loged_in = true
      this.changeStuff(transport)
    }
  }


  this._logMeIn_OnSuccess = function (transport) {
    // debugMessage('we are here: _logMeIn_OnSuccess() Method, First line ')
    //console.log('transport: '+transport.responseText)
    // var data = transport.responseText.split('|')
    if ( transport.responseText != 'False' ) {
      // we don't check for "True" as if it's true we'll get a |-seperated list of data
      this.loged_in = true
      // setting body overflow property back to auto
      this.main_body.setStyle({overflow: "auto"})
      // debugMessage('we are here: _logMeIn_OnSuccess() Method, right after some style settings ')
      // when we loged in, we don't need the event listener on the schleier object, as it will be hidden
      //console.log('will we reset the event listener for schleier object?')
      try {
        // because we not always log in with a schleier object, we just try out if we can do it, otherwise, we
        // simply do nothing
        //console.log('unsetting event listener for schleier object')
        Event.stopObserving(this.schleier,'click')
      }
      catch(e) {
        //console.log("we didn't unset the event listener for schleier object")
      }
      this.changeStuff(transport)

    }
    else {
      this.loged_in = false
      this.login_status.update('Ihr Log-In war nicht erfolgreich.<br/>Bitte versuchen Sie es noch einmal.').setStyle({color:'red'}).show()
      // after adding content to the dropdown, we need to do some resizing. The positioning method does that for us
      login_dropdown.positioning()
    }
  }

  this.initialize()

}

function getRoot () {
  // The Root Directory we need for the breadcrumbs depends on the rz-type (zahnärzte,apotheker,...,firmengruppe)
  // this function will find the specific root for each of the location dependent rz-types
  var loc = document.location.pathname
  if ( loc.match(/firmengr/) ) {
    return 'firmengr'
  }
  else {
    return 'rechenzentrum'
  };
}

function LinkSetterDoP (id,productive_url,develop_url) {
  // INstances of this object will change the href attribute value depending on the Development or Productive (DoP)
  // environment.

  this.initialize = function() {
    this.obj = Object.isString(id)?$(id):id;
    this.productive_url = productive_url
    this.develop_url = develop_url
    this.setHrefAttribute(this.getEnvironment())
  };

  this.getEnvironment = function() {
    var d = document.domain
    if ( d.match(/develop/) ) {
      return 'develop'
    }
    return 'productive'
  };

  this.setHrefAttribute = function(env) {
    if ( env == 'productive' ) {
      this.obj.setAttribute('href',productive_url)
    }
    else {
      this.obj.setAttribute('href',develop_url)
    }
  };

  this.initialize()
}

function FormInputObject (obj,str) {
  /* *****************************
  Objects of that class will be input boxes, that has str written in it. Wenn the input field
  gets the focus the default str will disapear, so the user does not have to delete manually.
  If on a blur event the default str will be inserted again if nothing was typed into the input field.
  ***************************** */

  // Attributes
  this.obj = null
  this.str = ''
  this.cleared = false
  this.is_passwd_input = false
  this.fake_input = null // if we have to deal with a password field we have to add a fake input type text
                         // field, cause IE does not support changing the type parameter

  // Methods
  this.initialize = function() {
    // debugMessage('initialize')
    this.obj = Object.isString(obj)?$(obj):obj;
    if ( str ) {
      this.str = str
      this.obj.value = str
    }
    else {
      this.str = $F(this.obj)
    }
    // this.str = str!=''?str:$F(this.obj)
    this.obj.onfocus = this.focusAction.bind(this)
    this.obj.onblur = this.blurAction.bind(this)
    // this.obj.observe('blur',this.blurAction.bind(this))
  };

  this.focusAction = function() {
    // console.log('cleared: '+this.cleared)
    if ( this.cleared ) {
      // console.log('selecting __'+this.obj.id)
      this.obj.select()
      return
    };
    this.obj.clear()
    if ( this.is_passwd_input ) {
      this.fake_input.hide()
      this.obj.show()
    };
    this.cleared = true
  };

  this.blurAction = function() {
    if ( ! this.obj.present() ) {
      // if nothing was typed into the field we just put the default inside
      this.obj.value = this.str
      if ( this.is_passwd_input ) {
        this.obj.hide()
        this.fake_input.show().activate()
      };
      // debugMessage('cleared to false')
      this.cleared = false
    };
  };

  this.setToPasswdField = function() {
    // this.is_passwd_input = false // the idea with changing the attribute "type" does not work in IE, so we disable it here
    return
    this.is_passwd_input = true
    this.fake_input = new Element("input", {type: "text", value: this.str})
    this.obj.hide()
    this.obj.insert({after: this.fake_input})
    this.fake_input.onfocus = this.focusAction.bind(this)
    this.fake_input.onblur = this.blurAction.bind(this)
    // this.initialize()
    // return this
  };

  this.initialize()

}



var Url = {
  /**
  *
  *  URL encode / decode
  *  http://www.webtoolkit.info/
  *
  **/

	// public method for url encoding
	encode : function (string) {
		return escape(this._utf8_encode(string));
	},

	// public method for url decoding
	decode : function (string) {
		return this._utf8_decode(unescape(string));
	},

	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}

		return string;
	}

}

// BEGIN prototype erweiterungen:

// we define a new getElementsByClassName method on the iframe Element,
// we need that for dynamically changing the content from the window.top element
Element.addMethods('iframe',{
  doc: function(element) {
    element = $(element);
    if (element.contentWindow)
      return element.contentWindow.document;
    else if (element.contentDocument)
      return element.contentDocument;
    else
      return null;
  },
  getElementsByClassName2: function(element,tagname,cname) {
    element = $(element)
    // var frame_document = element.document()
    var frame_elements = new Array()
    var tags = element.doc().getElementsByTagName(tagname)
    for (var i = tags.length - 1; i >= 0; i--){
      if ( tags[i].className.indexOf(cname) != -1 ) {
        frame_elements.push(tags[i])
      }
    }
    // frame_elements.each(function(e) {alert(e.tagName)})
    return frame_elements
    // if ( frame_elements.length > 0 ) {
    //       return frame_elements
    //     }
    //     else {
    //       return null
    //     }
  }
})

// END prototype erweiterungen

// ------------------------------------------------------------
// function imported from Ian. Was in formulare.htm
function popUp(doc,w,h,xpos,ypos,extras){

  // extras is called either with nothing or with a single-quoted string containing one or more of:
  // scrollbars,resizable,menubar,status etc.
  // eg: parent.popUp('doc.htm',740,500,10,10,'scrollbars,resizable')


  if(document.getElementById) {
  	xpos+=5;
  	ypos+=80;
  	if(window.strip){strip.close()}
  	strip=window.open("","swig","width="+w+",height="+h+","+extras+"")
  }


  else if (document.layers){
  	xpos+=10;
  	ypos+=270;
  	if(window.strip){strip.close()}
  	else{
  		strip=window.open("","swig","width="+w+",height="+h+"");

  	//alert("From popup: xpos,ypos: "+xpos+", "+ypos+"\nThe width is "+w+" and height is "+h)
  	}
  }

  if(window.strip){
  	strip.moveTo(xpos,ypos);
  	strip.location.href=doc;
  }

}
// ------------------------------------------------------------

// ------------------------------------------------------------
function getRZFromPLZ(plz) {
  if ( isNumber(plz) ) {
    var RZ

    var plzLiteral = plz.toString();

    if ( plzLiteral.substring(0,1) == "0" ) { RZ = 'frh' }
    else if ( plzLiteral.substring(0,1) == "1") { RZ = 'frh' }

    else if (
           plz > 23920 && plz < 24000
        || plz > 29400 && plz < 29417
        || plz > 36400 && plz < 36470
        || plz > 37300 && plz < 37596
        || plz > 38480 && plz < 38490
        || plz > 38800 && plz < 39650
        || plz > 96500 && plz < 96530
        || plz > 98500 && plz < 99999
    ) {
    	RZ = 'frh';
    	}

    //see fax form CG 15 08 08
    //between, n‰mlich
    //23921	23999
    //29401	29416
    //36401	36469
    //37301	37595
    //38481	38489
    //38801	39649
    //96501	96529	Th¸ringen
    //98501	99998	Th¸ringen

    else if ( plz > 19999 && plz < 30000 ) {RZ = 'hza'}
    else if ( plz > 63879 && plz < 63940) {RZ = 'abz'}
    else if ( plz > 63699 && plz < 63880) {RZ = 'abz'}
    else if ( plz > 79999 && plz < 86999) {RZ = 'abz'}
    else if ( plz > 88099 && plz < 88180) {RZ = 'abz'}
    else if ( plz > 89299 && plz < 89370) {RZ = 'abz'}
    else if ( plz > 89399 && plz < 89450) {RZ = 'abz'}
    else if ( plz > 89999 && plz < 96500) {RZ = 'abz'}
    else if ( plz > 96529 && plz < 97860) {RZ = 'abz'}
    else if ( plz > 97900 && plz < 97910) {RZ = 'abz'}

    else if ( plz > 29999 && plz < 34000) {RZ = 'dzr_n'}
    else if ( plz > 36999 && plz < 36401) {RZ = 'dzr_n'}
    else if ( plz > 36470 && plz < 43000) {RZ = 'dzr_n'}
    else if ( plz > 43999 && plz < 54000) {RZ = 'dzr_n'}
    else if ( plz > 56999 && plz < 60000) {RZ = 'dzr_n'}

    else if ( plz > 33999 && plz < 37000) {RZ = 'dzr_s'}
    else if ( plz > 53999 && plz < 57000) {RZ = 'dzr_s'}
    else if ( plz > 69999 && plz < 80000) {RZ = 'dzr_s'}

    return RZ
  }
}

function getRZsURL (rz) {
  // this function returns the url to a rz passed as a string like dzr_s or abz, ...
  var url = ''
  if ( rz == 'dzr_s' ) {
    url = 'http://dzr.de/drgn/rechenzentrum/zrz/?dzr_s'
  }
  else if ( rz == 'dzr_n' ) {
    url = 'http://dzr.de/drgn/rechenzentrum/zrz/?dzr_n'
  }
  else if ( rz == 'abz' ) {
    url = 'http://abz-zr.de/drgn/rechenzentrum/zrz/'
  }
  else if ( rz == 'frh' ) {
    url = 'http://frh.de/drgn/rechenzentrum/zrz/'
  }
  else if ( rz = 'hza' ) {
    url = 'http://hza-online.de/drgn/rechenzentrum/zrz/'
  }
  else {
    debugMessage('Keine URL für das RZ "'+rz+'" gefunden.')
  }
  if ( window.document.domain.match(/develop/) ) {
    url = url.replace(/(http:\/\/)(.*)$/,'$1develop.$2')
  };
  return url
}

/**
 * TODO write documentation
 + short: takes id of div element
 + element has to have a trigger element with class name dropdown-trigger
 + element has to have a content element with class name dropdown-content
 + content will be shown when trigger was clicked
 + div element will be added which acts as close button. Class name of it will be dropdown-close
 */
function DropdownContent (id,show_on_init,t) {
  this.id = id;
  this.effect_time = t?t:0.2;
  this.dropdown_wrapper = null;
  this.content_item = null;
  this.link_item = null;
  this.close_item = null;
  this.show_on_init = show_on_init?show_on_init:false; // if show_on_init is true, the content will be shown by default
  
  this.initialize = function() {
    // get dropdown wrapper
    this.dropdown_wrapper = $(this.id);
    // get the link tag
    this.link_item = $$('#'+this.id+' .dropdown-trigger')[0];
    // get the content tag
    this.content_item = $$('#'+this.id+' .dropdown-content')[0];
    // generate the close "button"
    this.close_item = new Element('div', {'class':'dropdown-close'});
    // add close button to the DOM
    this.content_item.insert({top:this.close_item});
    
    if ( ! (this.close_item && this.link_item) ) {
      return null; // return null when we can't find the items. This way we avoid error messages
    };
    // register click event listener on the link
    this.link_item.observe('click',this.showContent.bind(this));
    // register click event listener on the close "button"
    this.close_item.observe('click',this.hideContent.bind(this));
    if ( this.show_on_init ) {
      this.showContent(true,true);
    };
  };
  
  
  /**
   *  This method shows the content of dropdown-content
   *  Arguments: 
   *    noanimate:  if true the showing will be animated
   *    noscroll:   if true the we won't scroll to the contents top
   **/
  this.showContent = function(noanimate,noscroll) {
    var noanimate = noanimate?noanimate:false;
    var noscroll = noscroll?noscroll:false;
    this.link_item.hide();
    this.dropdown_wrapper.removeClassName('dropdown-closed');
    this.dropdown_wrapper.addClassName('dropdown-opened');
    if ( noanimate ) {
      this.content_item.show();
    }
    else {
      Effect.SlideDown(this.content_item, {duration:this.effect_time});
    };
    if ( ! noscroll ) {
      this.scrollToContent.bind(this).delay(this.effect_time);
    };
  };
  
  this.hideContent = function() {
    Effect.SlideUp(this.content_item, {duration:this.effect_time});
    this.showTrigger.bind(this).delay(this.effect_time);
  };
  
  this.showTrigger = function() {
    this.dropdown_wrapper.removeClassName('dropdown-opened');
    this.dropdown_wrapper.addClassName('dropdown-closed');
    this.link_item.show();
  };
  
  this.scrollToContent = function() {
    this.dropdown_wrapper.scrollTo();
  };
  
  this.initialize();
  
}


function isNumber(data) {
  if ( data.match(/\d\d\d\d\d/) ) {
    return true
  }
  return false
}
// ------------------------------------------------------------

/**
 * pawel (2010-07-30):
 * Güldener complains about Zahlungsziehlverlängerungsanträge without an RZ. Ian had a look at the logfiles
 * and it seems, that some users serv that pages using the drgueldener.de domain. But this domain is only 
 * accessible in the splashscreen or the firmengr/ page. That's why we check for that domain, in the 
 * the RZ specific main index.htm page we'll call this function, too make sure that the user is not
 * using that unspecified domain.
 **/
 
/** deprecated (2011-07-18): it wasn't that **/ 
// function checkIfValidRZDomain () {
//   if ( document.domain.match(/drgueldener\.((de)|(home))/) ) {
//     document.location = 'http://drgueldener.de/drgn/';
//   };
// }


// function logHeights () {
//   console.log('RESIZE EVENT!'+
//               '\ninitial_teaser_right_height: '+initial_teaser_right_height+
//               '\ninitial_viewport_height: '+initial_viewport_height+
//               '\nheight_difference: '+height_difference+
//               '\n\nwindow height: '+window.innerHeight+
//               '\nviewport height: '+document.viewport.getHeight()+
//               '\nhtml tag height: '+$(document.getElementsByTagName('HTML')[0]).getHeight()+
//               '\nbody tag height: '+$(document.getElementsByTagName('BODY')[0]).getHeight()+
//               '\nall-wrapper height: '+$('all-wrapper').getHeight()+
//               '\niframe-and-teaser-wrapper height: '+$('iframe-and-teaser-wrapper').getHeight()+
//               '\nteaser-right height: '+$('teaser-right').getHeight());
// }

function onResizeAdjustments () {
  // the following changes the height of the teaser-right dynamicaly, as it was the reason, why
  // the window got global scrollbars when making it smaller.
  // It only happend in browsers != ie.
  if ( browser.getName() != 'ie' ) {
    var height_difference = document.viewport.getHeight() - $('teaser-right').getHeight();
    Event.observe(window, 'resize', function(e) {
      siteprops.teaser_right.style.height = document.viewport.getHeight()-height_difference+'px';
      // logHeights();
    })
  };
}


function checkIfPageShouldBeJailed () {
  /* When somebody tries to access a content page, which should be inside the 
     iframe 'contentframe' we redirect, but we only can now for sure, whether 
     we should jail the page when we've loaded, as it checks for the iframe id and name */
  
  Event.observe(window,'load',function() {
    var jailed = (window.self != window.top);
    var iframe = $('iframe1');
    if ( (!jailed && iframe && iframe.name == 'contentframe') || (!jailed && $('splashscreen')) ) {
      // if the window has a iframe1 id and the name of that iframe has the name 'contentframe' 
      // we are in the main frame and hence we don't need to jail ourself. 
      // So when returning "true" we triger a no-jailing status.
      // The other thing is, when there is an element with id "splashscreen". We should not jail that page eather.
      jailed = true;
    };
    if ( !jailed ) {
      jailPage();
    };
  })
  
}

function loadSpecificContentInfoIframe () {
  /* check if argument was passed */
  var arg, url, loader, url_encoded = null;
  if ( window.self != window.top ) {
    return; // the content of the iframe should not trigger anything here
  };
  var q = window.location.search;
  if ( q ) {
    q = q.replace(/^\?(.*)$/,'$1').split(/\&/);
    for (var i = q.length - 1; i >= 0; i--){
      var kv_pair = q[i].split(/=/);
      if ( kv_pair[0] === 'c' ) {
        url = Url.decode(kv_pair[1]);
        url_encoded = kv_pair[1]; // we need that later
        break;
      };
    };
    /* check if argument has a valid value */
    if ( url ) {
      var current_url = window.top.location.href
      if ( url.slice(0,15) != current_url.slice(0,15)) {
        // if the first some characters of the url in the argument and the current url are not equal,
        // somebody tries to load something into the iframe which does not belong there. In that case
        // we simply stop doing something. Alternatively we could redirect to somewhere. 
        return;
      };
      
      
      /* load url from argument into iframe */
      // We can only load something into the iframe, when DOM is loaded, so we add a Event Listener
      Event.observe(window,'load',function() {
        // We use the URLSpecialLoads Class as it hase a loadIntoFrame Method already
        loader = new URLSpecialLoads();
        loader.loadIntoFrame(url);
        /* TODO If the user accessed a content of dzr directly, there is no way to tell, whether he
           ment dzr_s or dzr_n, so we display a small window where he can choose the RZ */
        var rz = new RZName(); // this get's the object
        rz = rz.rz // we only need the rz name here so overriding the variable
        if ( rz.match(/dzr_s|dzr_n/) && !document.location.search.match(/dzr_selected/) ) {
          promtUserForRZChoice(url_encoded);
        };
      });
    };
  };
}

function promtUserForRZChoice (url) {
  // URL should be encoded
  // this function will/should be called when the dom is already loaded!
  // console.log('prompting user to choose between dzr_s or dzr_n.\nURL was: '+url);
  /* TODO add hidden div with content */
  var prompt_div = new Element('div', {'id':'rz_choice_prompt'}).setStyle({'display': "none"});
  var prompt_p = new Element('p').update("Sie sind momentan auf den Webseiten des DZR-Stuttgart.<br/> Möchten Sie zu DZR-Neuss wechseln?<br/>");
  // console.log('document.location: '+document.location.href+'&dzr_n');
  var prompt_a1 = new Element('a', {'href': document.location.href.replace(/\?/,'?dzr_n&')+'&dzr_selected'}).update('Ja');
  var prompt_a2 = new Element('a').update('Nein');
  
  /*  add listeners to buttons */
  // prompt_a1 will behave as a A-tag
  // console.log('putting it all together.')
  prompt_a2.observe('click',destroyRZChoicePrompt);
  /*  display div */
  prompt_p.insert(prompt_a1).insert(prompt_a2);
  prompt_div.insert(prompt_p);
  $$('body')[0].insert(prompt_div,{'position':'top'});
  /*  center position */
  positionizeRZChoicePromt(prompt_div);
  // console.log('blinding down');
  Effect.Appear(prompt_div);
  /*  hiding prompt after some time */
  destroyRZChoicePrompt.delay(10);
}

function positionizeRZChoicePromt (e) {
  // to simplyfy things we don't retrieve the width dynamicaly, since we know the div is 500px wide
  var e_width = 500;
  var display_center = document.body.clientWidth/2;
  e.setStyle({left:display_center-(e_width/2)+'px'});
}

function destroyRZChoicePrompt () {
  var prompt_div = $('rz_choice_prompt');
  Effect.Fade(prompt_div);
  prompt_div.remove.delay(5); // if there is such a function
}

function jailPage () {
  // consolelog('einsperren!!');
  var url = document.location.href;
  /* get url to redirect to */
  var url_to_redirect_to;
  if ( root == 'rechenzentrum' ) {
    url_to_redirect_to = url.replace(/^(http.*\/rechenzentrum\/[^\/]+\/).*$/,'$1');
  }
  else { // should be firmengr
    url_to_redirect_to = url.replace(/^(http.*\/firmengr\/).*$/,'$1');
  }
  
  /* urlencode the url for usage as parameter */
  var url_encoded = Url.encode(url);
  
  /* set the string for redirection */
  var target_url_with_parameter = url_to_redirect_to+'?c='+url_encoded;
  
  /* redirect */
  document.location = target_url_with_parameter;
}

/** 
    This functions checks the dimensions of the screen and 
    decides whether to serv a layout for notbooks or stay 
    with the regular one 
**/
function desideWichLayoutToUse () {
  // consolelog("checking screen size\n"+screen.availWidth+'x'+screen.availHeight);
  var loc = document.location.href
  var should_be_url = loc // setting it to the same value just in case
  var redirect = false;
  // consolelog("current URL: "+loc);
  if (screen.availWidth > 1150 && screen.availHeight <= 800 ) {
    // consolelog("we should serv the notebook layout");
    // when we use the main page with index.htm
    if ( loc.match(/\/index\.htm/) ) {
      should_be_url = loc.replace(/\/index\.htm/,"/index_wide.htm");
    }
    // when accessing the main page via /rechenzentrum/[zrz|apotheken|...]/
    else if ( loc.match(/\/rechenzentrum\/[^\/]+\/(\?.*)?$/) ) {
      should_be_url = loc.replace(/\/(\?.*)?$/,"/index_wide.htm$1");
    }
    // when accessing firmengr. page
    else if ( loc.match(/\/firmengr\/(\?.*)?$/) ) {
      should_be_url = loc.replace(/\/(\?.*)?$/,"/index_wide.htm$1");
    };
  }
  else {
    if ( loc.match(/\/index_wide\.htm/) ) {
      should_be_url = loc.replace(/\/index_wide\.htm/,"/index.htm");
    };
  };
  // we set the WIDE_LAYOUT variable debendent on which layout is loaded.
  if ( loc.match(/\/index_wide\.htm/) ) {
    WIDE_LAYOUT = true;
  }
  else {
    WIDE_LAYOUT = false;
  };
  // consolelog("should be URL: "+should_be_url);
  // consolelog("WIDE_LAYOUT: "+WIDE_LAYOUT);
  if ( loc != should_be_url ) {
    // consolelog("we redirect");
    // debugMessage('redirect to '+should_be_url);
    if ( document.location.search.match(/no_wide/) ) {
      return; // don't redirect if there a no_wide argument in the url
    };
    redirect = true;
  };
  
  if ( redirect ) { // || document.location.search.match(/force_wide/) ) {//  TODO: leads to a loop. Will take care of that later
    setTimeout(function() {window.top.location = should_be_url}, 50); // this timeout resolves some problems with IE
  };
}

// a map of the url items and their Names to show the client in breadcrumbs
url_items = $H({
              rechenzentrum:        'DZR Stuttgart',
              leistungen:           'Leistungen',
              zahnaerzte:           'Zahnärzte',
              patienten:            'Patienten',
           //   'vorteile.htm':      'Vorteile',
              seminare:             'Seminare',
              service:              'Zentrum Z',
              partner:              'Partner',
              "leitfaden.asp":            'Leitfaden',
              gutachterliste:       'Gutachterliste',
              empfehlung:             'Empfehlung',
              'empfehlungsportal.htm': "Empfehlungsportal",
              kontakt:              'Kontakt',
              'login_request.asp': "Login",
              'infomaterial.asp':   "Infomaterial",
              'abrechnung.htm':              'Abrechnung',
              'abrechnung':              'Abrechnung',
              'ausfallhaftung.htm':          'Ausfallhaftung',
              'sofortauszahlung.htm':           'Sofortauszahlung',
              'verwaltungsentlastung.htm':   'Verwaltungsentlastung',
              'verwaltungsentlastung':   'Verwaltungsentlastung',
              'erstattungsservice.htm':      'Erstattungsservice',
              'erstattungsservice': "Erstattungsservice", 
              'bonitaetsanfragen.htm':       'Bonitätsanfragen',
              'praxisunterstuetzung.htm':    'Praxisunterstützung',
              'abrechnungsforum.htm':        'Abrechnungsforum',
              'abrechnungsforum.asp':        'Abrechnungsforum',
              'zentrum_z.htm':               'Zentrum Z',
              'teilzahlung.htm': "Teilzahlung",
              'basisseminar-privatliquidation.htm': "Basisseminar Privatliquidation",
              'inhaltsverzeichnis.htm': "Inhaltsverzeichnis",
              'rechnung-korrekt-erstellt.htm': "Rechnung korrekt erstellt",
              'abrechnungsexperten_goz_vvg.htm': "Die Abrechnungsexperten kommen!", 
              'zahnaerzte-unternehmerabend.htm': "Zahnärzte-Unternehmerabend",
              'zahnaerzte-unternehmerabend_08.htm': "Zahnärzte Unternehmerabend 2008",
              'praxiserfolg_steigern.htm': "Praxiserfolg steigern",
              'zukunft_gestalten.htm': "die Zukunft gestalten",
              'seminare_rueckblick': "Rückblick",
              'aktuelle-aenderungen.htm': "Zahnärztliche Abrechnung: Aktuelle Änderungen ",
              firmengeschichte: "Firmengeschichte",
              infos_anfordern: "Infos Anfordern",
              'auf_einen_blick.htm': "Auf einen Blick",
              gebuehrenrechner: "Gebührenrechner",
              'kammern.htm': "Kammern",
              'gutachter.htm': "Gutachter",
              'online_abrechnung.htm': "Online-Abrechnung",
              'disketten_abrechnung.htm': "Disketten-Abrechnung",
              'computer_abrechnung.htm' : "Papier-Abrechnung",
              'partnerschaftliche_abrechnung.htm': "Partnerschaftliche Abrechnung",
              allgemeine_fragen: "Allgemeine Fragen",
              teilzahlung: "Teilzahlung",
              teilzahlungsrechner: "Teilzahlungsrechner",
              erstattungshilfe: "Erstattungshilfe",
              'teilzahlungsrechner.htm': "Teilzahlungsrechner",
              'empfehlungsformular.htm': "Empfehlungsformular",
              news: "News",
              "begruendungsmanager.asp": "Begründungsmanager",
              "formulare.asp": "Formulare",
              zahlungszielverlaengerung: "Zahlungszielverlängerung",
             // presse: "Presse",
              infomaterial: "Infomaterial",
              'gebuehrenrechner_macchina.htm': "Rechner",
              'patienten_ansprechpartner_dzr_s.htm': "Ansprechpartner für Patienten",
              'patienten_ansprechpartner_dzr_n.htm': "Ansprechpartner für Patienten",
              'patienten_ansprechpartner_abz.htm': "Ansprechpartner für Patienten",
              'patienten_ansprechpartner_frh.htm': "Ansprechpartner für Patienten",
              'patienten_ansprechpartner_hza.htm': "Ansprechpartner für Patienten",
              'kunden_ansprechpartner_dzr_s.asp': "Ansprechpartner für Kunden",
              'kunden_ansprechpartner_dzr_n.asp': "Ansprechpartner für Kunden",
              'kunden_ansprechpartner_abz.asp': "Ansprechpartner für Kunden",
              'kunden_ansprechpartner_frh.asp': "Ansprechpartner für Kunden",
              'kunden_ansprechpartner_hza.asp': "Ansprechpartner für Kunden",
              'interessenten_ansprechpartner_dzr_s.htm': "Ansprechpartner für Interessenten",
              'interessenten_ansprechpartner_dzr_n.htm': "Ansprechpartner für Interessenten",
              'interessenten_ansprechpartner_abz.htm': "Ansprechpartner für Interessenten",
              'interessenten_ansprechpartner_frh.htm': "Ansprechpartner für Interessenten",
              'interessenten_ansprechpartner_hza.htm': "Ansprechpartner für Interessenten",
              'routenplaner': "Routenplaner/Anfahrt",
              'feedback': "Fragen und Antworten",
               firmengr: "Dr. Güldener Firmengruppe",
              'jobs': "Stellenangebote",
              'stellenangebot1.htm': "Stellenangebot",
              'stellenangebot2.htm': "Stellenangebot",
              'stellenangebot3.htm': "Stellenangebot",
              'sitemap.htm': "Sitemap",
              'impressum_dzr_s.htm': "Impressum",
              'impressum_dzr_n.htm': "Impressum",
              'impressum_abz.htm': "Impressum",
              'impressum_hza.htm': "Impressum",
              'impressum_frh.htm': "Impressum",
              'impressen.htm': "Impressen",
              'impressum_apo.htm': "Impressum",
              'impressum_aerzte.htm': "Impressum",
              'search': "Suche",
              'neu_registrieren.asp': "Neu Registrieren",
              'passwort_vergessen.asp': "Passwort Vergessen",
              'kontakt.asp': "Kontakt",
              'leistungen_fuer': "Leistungen für",
              'apotheken': "Apotheken",
              'rezeptabrechnung.htm': "Rezeptabrechnung",
              'rezeptsicherheit.htm': "Rezeptsicherheit",
              'kh-apotheken': "KH-Apotheken",
              'rezeptauswertung.htm': "Rezeptauswertung",
              'auszahlung.htm': "Auszahlung",
              'auszahlung': "Auszahlung",
              'zuzahlungs_inkasso.htm': "Zuzahlungs-Inkasso",
              'hersteller_inkasso.htm': "Hersteller-Inkasso",
              'verblisterung.htm': "Verblisterung",
              'apo32_rezeptarchiv.htm': "Apo32/Rezeptarchiv",
              'infomaterial.htm': "Infomaterial",
              'ekv.htm': "eKV",
              'apooffice.htm': "ApoOffice",
              'apodirekt.htm': "apodirekt",
              'aerztedirekt': "ärztedirekt",
              'apodirekt_cash.htm': "apodirekt Cash",
              'infomaterial_formulare.htm': "Infomaterial/Formulare",
              'zuzahlungen.htm': "Zuzahlungen",
              'privatrezept.htm': "Privatrezept",
              'allgemeine_fragen.htm': "Allgemeine Fragen",
              'patienten_ansprechpartner_apo.htm': "Ansprechpartner für Patienten",
              'interessenten_ansprechpartner_apo.htm': "Ansprechpartner für Interessenten",
              'patienten_ansprechpartner_aerzte.htm': "Ansprechpartner für Patienten",
              'interessenten_ansprechpartner_aerzte.htm': "Ansprechpartner für Interessenten",
              'kunden_ansprechpartner_apo.asp': "Ansprechpartner für Kunden",
              'fragen_zur_einverstaendniserklaerung.htm': "Fragen zur Einverständniserklärung",
              'abrechnungfuer': "Abrechnung für",
              'sanitaetshaeuser': "Sanitätshäuser", 
              'heilmittelleistungserbringer': "Heilmittelleistungserbringer", 
              'hilfsmittellieferanten': "Hilfsmittellieferanten", 
              'ambulante_pflegedienste': "Ambulante Pflegedienste", 
              'hebammen': "Hebammen", 
              'medizintechniker': "Medizintechniker",
              'shdirektdemo': "SHdirekt Demo", 
              'komplettangebot': "Komplettangebot", 
              'info_anfordern': "Info anfordern", 
              'formulare_bestellen': "Formulare bestellen",
              'ergotherapeuten':"Ergotherapeuten",
              'fruehfoerderung':"Frühförderung",
              'krankengymnasten':"Krankengymnasten",
              'kurbetriebe':"Kurbetriebe",
              'logopaeden':"Logopäden",
              'masseure':"Masseure",
              'medizinische-badebetriebe':"Medizinische Badebetriebe",
              'physiotherapeuten':"Physiotherapeuten",
              'podologen':"Podologen",
              'rehazentren':"Rehazentren",
              'sprachheilpaedagogen':"Sprachheilpädagogen",
              'augenoptiker':"Augenoptiker",
              'hoerakustiker':"Hörakustiker",
              'orthopaedieschuhtechniker':"Orthopädieschuhtechniker",
              'orthopaedietechniker':"Orthopädietechniker",
              'patienten_ansprechpartner_optica.htm': "Ansprechpartner für Patienten",
              'interessenten_ansprechpartner_optica.htm': "Ansprechpartner für Interessenten",
              'impressum_optica.htm': "Impressum",
              'berufsgruppen': "Berufsgruppen",
              'formulare_bestellen': "Formulare bestellen",
              'empfehlung': "Empfehlung",
              'neue_goz.htm': "Die neue GOZ",
              'neue_goz_abz.htm': "Die neue GOZ",
              'gogreen': "GoGreen",
              'privatliquidation.htm':'Privatliquidation',
              'saniconcept.htm': "SaniConcept®",
              'goz_2012.htm': "GOZ 2012"
            })

var root = getRoot()
var login = null // we define this variable globaly
var debug = true /* TODO don't forget to change that to false in production! */
var WIDE_LAYOUT = false // tells us, which layout is active

checkIfPageShouldBeJailed(); // we check if we have to jail the page. This is the case when we access content directly and not the usual way.

loadSpecificContentInfoIframe(); // if there is an url passed, this function will load that url into the iframe

