//
// $Id: siteware.js 344 2008-03-19 22:19:54Z  $
//
// COMMUNITOR SiteWare 2.0 Site Server
// Copyright by COMMUNITOR Internetservice GmbH, 2001-2008
//

Element.addMethods({
  getMaxZIndex: function (element) {
    var descendants = $(element).descendants();
    var z,m=0;
    for (var i=0,l=descendants.length;i<l;++i) {
      z = parseInt(descendants[i].getStyle('z-index'));
      if (z && m < z) m = z;
    }
    return m;
  }
});

Object.extend(String.prototype, {
  applyBaseHref: function(baseHref) {
    var source = this, match, proto, fileName, domainPath, domain;
    // if string has proto or no base href was given then just return a copy of string
    if (!baseHref || (source.indexOf('://') > -1))
      return source.substr(0);
    // analyzing base href
    // strip proto part
    match = baseHref.match(/([^:]+:\/\/)(.*)/);
    if (match) {
      proto = match[1];
      baseHref = match[2];
    }
    // strip file name
    if ((match = baseHref.lastIndexOf('/')) > -1) {
      domainPath = baseHref.substr(0,match+1);
      fileName = baseHref.substr(match+1);
    } else {
      if (proto) {
        domainPath = baseHref + '/';
        fileName = '';
      } else {
        domainPath = '';
        fileName = baseHref ;
      }
    }
    // strip domain
    if (proto) {
      // apply base href to string
      if (source.indexOf('/') == 0) {
        match = domainPath.indexOf('/');
        return proto + domainPath.substr(0, match) + source;
      }
      return proto + domainPath + source;
    }
    
    if (source.indexOf('/') == 0)
      return source.substr(0);
      
    return domainPath + source;
  }
});

Effect.Zoom = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      zoomFrom:    0.0,
      zoomTo:      100.0,
      opacityFrom: 100.0,
      opacityTo:   100.0,
      direction:   'top-left',
      restoreAfterFinish: null,
      transformTo: null
    }, arguments[1] || { });
    this.start(options);
  },
  setNodeDimensions: function(node,dimensions,zoomFactor) {
    if (!zoomFactor) zoomFactor = 1;
    var nodeStyle = {};
    
    if (!isNaN(dimensions.width) && (dimensions.width != null))
      nodeStyle["width"] = (dimensions.width * zoomFactor).round() + 'px';
    
    if (!isNaN(dimensions.height) && (dimensions.height != null))
      nodeStyle["height"] = (dimensions.height * zoomFactor).round() + 'px';
    
    if (!isNaN(dimensions.top) && (dimensions.top != null))
      nodeStyle["top"] = (dimensions.top * zoomFactor).round() + 'px';
    else if (!isNaN(dimensions.bottom) && (dimensions.bottom != null))
      nodeStyle["bottom"] = (dimensions.bottom * zoomFactor).round() + 'px';
    
    if (!isNaN(dimensions.left) && (dimensions.left != null))
      nodeStyle["left"] = (dimensions.left * zoomFactor).round() + 'px';
    else if (!isNaN(dimensions.right) && (dimensions.right != null))
      nodeStyle["right"] = (dimensions.right * zoomFactor).round() + 'px';
    
    node.setStyle(nodeStyle);
  },
  setBoxDimensions: function(dimensions,zoomFactor,movements,node) {
    if (!zoomFactor) zoomFactor = 1;
    if (!node) node = this.element;
    var correction = Object.extend({
      left: 0,
      top:  0
    }, movements || { });
    var left = dimensions.left + correction.left;
    var top  = dimensions.top  + correction.top;
    switch (this.options.direction) {
      case 'top-left':
        break;
      case 'top-right':
        left += (1-zoomFactor) * dimensions.width;
        break;
      case 'bottom-left':
        top += (1-zoomFactor) * dimensions.height;
        break;
      case 'bottom-right':
        left += (1-zoomFactor) * dimensions.width;
        top  += (1-zoomFactor) * dimensions.height;
        break;
      case 'center':
        left += (1-zoomFactor)/2 * dimensions.width;
        top  += (1-zoomFactor)/2 * dimensions.height;
        break;
    }
    node.setStyle({
      left:   (left).round() + 'px',
      top:    (top).round() + 'px',
      width:  (dimensions.width * zoomFactor).round() + 'px',
      height: (dimensions.height * zoomFactor).round() + 'px'
    });
  },
  setup: function() {
    this.deltaZoom = (this.options.zoomTo - this.options.zoomFrom)/100.0;
    var node = this.element, zoomCorrection=1;
    // if no target box is given, derive it from actual position and dimensions
    if (this.options.transformTo == null) {
      this.options.transformTo = {
        top:    parseInt(node.getStyle('top')),
        left:   parseInt(node.getStyle('left')),
        width:  parseInt(node.getStyle('width')),
        height: parseInt(node.getStyle('height'))
      };
      // correct position according to expansion direction
      // calculations are based on width of containing box
      zoomCorrection = 100.0/this.options.zoomFrom;
      if (zoomCorrection != 1) {
        switch (this.options.direction) {
          case 'top-left':
            break;
          case 'top-right':
            this.options.transformTo.left = this.options.transformTo.left + (1-zoomCorrection) * this.options.transformTo.width;
            break;
          case 'bottom-left':
            this.options.transformTo.top = this.options.transformTo.top + (1-zoomCorrection) * this.options.transformTo.height;
            break;
          case 'bottom-right':
            this.options.transformTo.left = this.options.transformTo.left + (1-zoomCorrection) * this.options.transformTo.width;
            this.options.transformTo.top  = this.options.transformTo.top  + (1-zoomCorrection) * this.options.transformTo.height;
            break;
          case 'center':
            this.options.transformTo.left = this.options.transformTo.left + (1-zoomCorrection)/2 * this.options.transformTo.width;
            this.options.transformTo.top  = this.options.transformTo.top  + (1-zoomCorrection)/2 * this.options.transformTo.height;
            break;
        }
        this.options.transformTo.width  = this.options.transformTo.width  * zoomCorrection;
        this.options.transformTo.height = this.options.transformTo.height * zoomCorrection;
      }
    } else {
      this.options.transformTo = {
        top:    parseInt(this.options.transformTo.top),
        left:   parseInt(this.options.transformTo.left),
        width:  parseInt(this.options.transformTo.width),
        height: parseInt(this.options.transformTo.height)
      };
    }
    
    // from now on we have a reference size for further calculations - based on width of container box
    // so we can calculate the original dimensions of all items
    node.zoomOriginalPosition = {
      top:    parseInt(node.getStyle('top')),
      left:   parseInt(node.getStyle('left')),
      width:  parseInt(node.getStyle('width')),
      height: parseInt(node.getStyle('height'))
    };
    
    zoomCorrection = this.options.transformTo.width/node.zoomOriginalPosition.width;
    if (zoomCorrection != 1) {
      switch (this.options.direction) {
        case 'top-left':
          break;
        case 'top-right':
          node.zoomOriginalPosition.left = node.zoomOriginalPosition.left + (1-zoomCorrection) * node.zoomOriginalPosition.width;
          break;
        case 'bottom-left':
          node.zoomOriginalPosition.top = node.zoomOriginalPosition.top + (1-zoomCorrection) * node.zoomOriginalPosition.height;
          break;
        case 'bottom-right':
          node.zoomOriginalPosition.left = node.zoomOriginalPosition.left + (1-zoomCorrection) * node.zoomOriginalPosition.width;
          node.zoomOriginalPosition.top  = node.zoomOriginalPosition.top  + (1-zoomCorrection) * node.zoomOriginalPosition.height;
          break;
        case 'center':
          node.zoomOriginalPosition.left = node.zoomOriginalPosition.left + (1-zoomCorrection)/2 * node.zoomOriginalPosition.width;
          node.zoomOriginalPosition.top  = node.zoomOriginalPosition.top  + (1-zoomCorrection)/2 * node.zoomOriginalPosition.height;
          break;
      }
      node.zoomOriginalPosition.width  = node.zoomOriginalPosition.width  * zoomCorrection;
      node.zoomOriginalPosition.height = node.zoomOriginalPosition.height * zoomCorrection;
    }
    
    // calculate movement of bounding box with top-left as reference point
    this.deltaX = this.options.transformTo.left - node.zoomOriginalPosition.left;
    this.deltaY = this.options.transformTo.top  - node.zoomOriginalPosition.top;
    // calculate change of opacity along the way
    this.deltaOpacity = (this.options.opacityTo - this.options.opacityFrom)/100.0;
    this.protectOpacityInIE = Prototype.Browser.IE && this.deltaOpacity != 0 ? true : false;
    
    // calculate reference dimensions of descendants
    // clear array of any obsolete nodes that will not get resized
    this.descendants = this.element.descendants().findAll(function(node) {
      if (!node.nodeName) return false;
      switch (node.nodeName) {
        case 'DIV':
        case 'IMG':
        case 'TEXTAREA':
        case 'SELECT':
          return true;
        case 'INPUT':
          if ((node.type == 'checkbox') || (node.type == 'radio'))
            return false;
          else
            return true;
        default:
          return false;
      }
    });
    var t,l,w,h;
    for (var i=0,l=this.descendants.length;i<l;++i) {
      node = this.descendants[i];
      if (node.nodeName == 'DIV') node.absolutize();
      // getWidth() and style.width did not resolve on images with display:none when they are in an none-displayed box...
      // if style is not set, getStyle would default it to 0 so we use direct access methods instead
      node.zoomOriginalPosition = {
        top: null, left: null, bottom: null, right: null,
        width:  parseInt(node.getStyle('width')) * zoomCorrection,
        height: parseInt(node.getStyle('height')) * zoomCorrection
      };
      if (node.style.left == "" && node.style.right != "")
        node.zoomOriginalPosition.right = parseInt(node.getStyle('right')) * zoomCorrection;
      else
        node.zoomOriginalPosition.left = parseInt(node.getStyle('left')) * zoomCorrection;
      if (node.style.top == "" && node.style.bottom != "")
        node.zoomOriginalPosition.bottom = parseInt(node.getStyle('bottom')) * zoomCorrection;
      else
        node.zoomOriginalPosition.top = parseInt(node.getStyle('top')) * zoomCorrection;
      this.setNodeDimensions(node,node.zoomOriginalPosition,(this.options.zoomFrom/100.0));
      if (this.protectOpacityInIE) {
        if (node.getStyle('background-image').indexOf('.png') > 0) {
          node.opacitySavedBackgroundImage = node.getStyle('background-image');
          node.setStyle({backgroundImage : ''});
        }
        if (node.nodeName == 'IMG' && node.src.indexOf('.png') > 0) {
          node.opacitySavedImage = node.src;
          node.setStyle({visibility: 'hidden'});
        }
      }
    }
    this.setBoxDimensions(this.element.zoomOriginalPosition,(this.options.zoomFrom/100.0));
    this.element.setOpacity(this.options.opacityFrom/100.0).show();
  },
  update: function(position) {
    var node,zoomFactor = this.options.zoomFrom/100.0 + this.deltaZoom * position;
    for (var i=0,l=this.descendants.length;i<l;++i) {
      node = this.descendants[i];
      this.setNodeDimensions(node,node.zoomOriginalPosition,zoomFactor);
    }
    var movement = {
      left: (this.deltaX * position),
      top:  (this.deltaY * position)
    };
    this.setBoxDimensions(this.element.zoomOriginalPosition,zoomFactor,movement);
    this.element.setOpacity(this.options.opacityFrom/100.0 + this.deltaOpacity * position)
  },
  finish: function() {
    var node;
    if (this.protectOpacityInIE) {
      for (var i=0,l=this.descendants.length;i<l;++i) {
        node = this.descendants[i];
        if (node.opacitySavedBackgroundImage)
          node.setStyle({backgroundImage: node.opacitySavedBackgroundImage});
        if (node.opacitySavedImage)
          node.setStyle({visibility: 'visible'});
      }
    }
    if (this.options.restoreAfterFinish) {
      this.element.hide().setOpacity(1);
      for (var i=0,l=this.descendants.length;i<l;++i) {
        node = this.descendants[i];
        this.setNodeDimensions(node,this.descendants[i].zoomOriginalPosition);
      }
      this.element.setStyle(this.options.restoreAfterFinish);
    }
  }
});


/*************************************/
/*  Popup Klasse SWpopupCollection   */
/*************************************/
var SWpopupCollection = Class.create();
Object.extend(SWpopupCollection.prototype, {
  initialize: function(container) {
    this.all = [];
    this.allByName = {};
    this.allForms = {};
    this.container = $(container);
    this.options = Object.extend({
      selector: ['a[rel]','area[rel]','input[type="image"]']
    }, arguments[1] || { });
    // selector is rel
    var links = this.container.select(this.options.selector);
    var data,rel,pos=0,dataIndex,popup;
    for (var i=0,l=links.length;i<l;++i) {
      rel = links[i].readAttribute('rel')
      if (!rel) continue;
      rel = rel.replace('http://','http_//').split(':');
      dataIndex = -1;
      if ((rel[0] == 'SWpopup') || (rel[0] == 'SWadminPopup')) {
        dataIndex = 1;
      } else if ((rel[2] == 'SWpopup') || (rel[2] == 'SWadminPopup')) {
        dataIndex = 3;
      }
      if (dataIndex > -1) {
        //rel="SWpopup:imgID,Container_Connector_Url,HighRes_FileName_url,HighRes_Size_w,HighRes_Size_h"
        //rel="SWrollover:idButRequest,but_anfrageformular1.gif:SWpopup:idButRequest,<%= PageElement(DirectRequestButton,Link) %>?partial=true<%= CGIsessionp1 %>,#html#,500,600"
        data = rel[dataIndex].split(',');
        // array with image-popup-triggers to scroll between
        if (data[2] != '#html#') {
          this.all.push(data[0]);
          // create image popup
          popup = new SWpopup(data[0],data[1].replace('http_//','http://'),data[2].replace('http_//','http://'),data[3],data[4],this,pos,(rel[dataIndex-1] == 'SWadminPopup'));
        } else {
          // create form popup if not already created
          if (this.allForms[data[1]]) {
            popup = this.allForms[data[1]];
          } else {
            popup = new SWpopup(data[0],data[1].replace('http_//','http://'),data[2],data[3],data[4],this,pos,(rel[dataIndex-1] == 'SWadminPopup'));
            this.allForms[data[1]] = popup;
          }
        }
        this.allByName[data[0]] = popup;
        links[i].observe('click', (function(e) {this.show();e.stop();}).bindAsEventListener(popup));
        ++pos;
      }
    }
  },
  show: function(id) {
    if (this.allByName[id]) {
      if (!this.allByName[id].loaded) {
        this.show.bind(this).delay(1,id);
        return;
      }
      return this.allByName[id].show();
    } else
      this._notfound(id);
  },
  hide: function(id) {
    if (this.allByName[id]) {
      if (!this.allByName[id].loaded) {
        this.hide.bind(this).delay(1,id);
        return;
      }
      return this.allByName[id].hide();
    } else
      this._notfound(id);
  },
  showPrevious: function(id) {
    if (this.allByName[id])
      return this.allByName[id].showPrevious();
    else
      this._notfound(id);
  },
  showNext: function(id) {
    if (this.allByName[id])
      return this.allByName[id].showNext();
    else
      this._notfound(id);
  },
  _notfound: function(id) {
    alert('id '+id+' has no related popup!');
  },
  visible: null
});


/*************************************/
/*  Popup Klasse SWpopup             */
/*************************************/
var SWpopup = Class.create();
Object.extend(SWpopup.prototype, {
  initialize: function(img,containerUrl,url,width,height,collection,pos,admin) {
    // remember my position in order of appearance on page
    this.collection = collection;
    this.index = pos;
    this.id = img;
    this.thumb = $(img);
    this.div = null;
    this.loaded = false;
    this.contentUrl = url;
    this.contentWidth = width;
    this.contentHeight = height;
    this.storedPosition = {
      left:   '0px',
      top:    '0px',
      width:  '0px',
      height: '0px'
    }
    // load content of popup
    if (containerUrl.indexOf('./') == 0)
      containerUrl = containerUrl.applyBaseHref(window.location.href);
    else
      containerUrl = containerUrl.applyBaseHref(this.thumb.src);
    // compatibility: we use & instead of ; to be able to connect to non-siteware servers
    var params = 'partial=true&admin='+admin;
    if (containerUrl.indexOf('?') > -1) {
      containerUrl = containerUrl.split('?');
      params += '&'+containerUrl[1].split(';').join('&');
      containerUrl = containerUrl[0];
    }
    containerUrl += '?' + params;
    new Ajax.Request(containerUrl, {
      asynchronous: true,
      method: 'get',
      evalScripts: true,
      onSuccess: this.load.bind(this),
      onFailure:SWErrorHandler
    });
  },
  load: function(t) {
    // create containing div and position it bottom-left above clicked image
    this.div = new Element("div");
    var offsets = this.thumb.positionedOffset();
    this.storedPosition.left = offsets[0] + 'px';
    this.storedPosition.top = offsets[1] + this.thumb.getHeight() + 'px';
    if (parseInt(this.storedPosition.top) < 0) this.storedPosition.top = '0px';
    var body = $(document.getElementsByTagName("body")[0]);
    this.div.setStyle({
      position:   'absolute',
      zIndex:     (body.getMaxZIndex()+100),
      visibility: 'hidden',
      opacity:    0.99999
    }).setStyle(this.storedPosition);
    // process XML response
    var xmlDoc = t.responseXML.documentElement;
    var target, tagName;
    var nodes=xmlDoc.childNodes;
    for (var i=0;i<nodes.length;i++) {
      if (nodes[i].nodeName) {
        tagName = nodes[i].nodeName.split(":");
        if (tagName[0] == "siteware") {
          try {
            this.div.update(nodes[i].firstChild.nodeValue.replace(/\]\]->/g, "]]"+">")).cleanWhitespace();
          } catch (e) {
            alert("Update failed with message: "+e);
          }
        }
      }
    }
    body.insert(this.div);
    // mark as loaded
    this.loaded = true;
    this.formatSize();
    // configure rollover images only if we have a html-container
    if (this.contentUrl == '#html#')
      new SWrollover(this.div);
  },
  formatSize: function() {
    // adjust dimensions - prepare
    var div = this.div;
    var left = div.select('.shTopLeft')[0];
    var container = div.select('.shTop')[0];
    var right = div.select('.shTopRight')[0];
    var offsets = left.positionedOffset();
    var setPosition = function(element,r,c,zIndex) {
      if (!zIndex) zIndex = 1;
      element.setStyle({
        position: 'absolute',
        left:     cLeft[c] + 'px',
        top:      rTop[r]  + 'px',
        width:    (cLeft[c+1]-cLeft[c]) + 'px',
        height:   (rTop[r+1]-rTop[r])   + 'px',
        zIndex:   zIndex
      });
    }
    // initialize positions with offset
    var cLeft = [offsets[0],offsets[0],offsets[0],offsets[0]], rTop = [offsets[1],offsets[1],offsets[1],offsets[1]];
    // add width of first col and height of first row
    // with correction for overlapping (depends on content element)
    // place image
    var img = div.select('.shImage')[0];
    var imgOffset = {};
    ['left','top','right','bottom','padding','margin'].each(function(p) {
      var val = parseInt(img.getStyle(p));
      imgOffset[p] = isNaN(val) ? 0 : val;
    });
    var dim = left.getDimensions();
    for (var i=1;i<4;++i) {
      cLeft[i] += dim.width;
      rTop[i]  += dim.height;
    }
    // add width and height of content - offsets are negative when overlapping, so adding is ok
    // add padding and margin as well
    // parseInt is needed for this to be interpreted as calculation
    for (var i=2;i<4;++i) cLeft[i] += (parseInt(this.contentWidth)  + imgOffset.left + imgOffset.right  + 2*imgOffset.padding + 2*imgOffset.margin);
    for (var i=2;i<4;++i) rTop[i]  += (parseInt(this.contentHeight) + imgOffset.top  + imgOffset.bottom + 2*imgOffset.padding + 2*imgOffset.margin);
    // top row
    setPosition(left,0,0);
    setPosition(container,0,1);
    // add width of last col
    cLeft[3] += right.getWidth();
    setPosition(right,0,2);
    // content row
    left = div.select('.shLeft')[0];
    container = div.select('.shContent')[0];
    right = div.select('.shRight')[0];
    setPosition(left,1,0);
    setPosition(container,1,1,(div.getMaxZIndex()+1));
    setPosition(right,1,2);
    // bottom row
    left = div.select('.shBottomLeft')[0];
    container = div.select('.shBottom')[0];
    right = div.select('.shBottomRight')[0];
    // add height of last row
    rTop[3] += left.getHeight();
    setPosition(left,2,0);
    setPosition(container,2,1);
    setPosition(right,2,2);
    // configure image only if we have an image
    if (this.contentUrl != '#html#') {
      if (this.contentUrl.indexOf('./') == 0)
        img.src = this.contentUrl.applyBaseHref(window.location.href);
      else
        img.src = this.contentUrl.applyBaseHref(this.thumb.src);
    }
    // set dimensions of image or content container
    // workaround through IE's box model that includes padding with a box's width
    var padding = Prototype.Browser.IE ? 2*imgOffset.padding : 0
    img.setStyle({
      position: 'absolute',
      width:    (parseInt(this.contentWidth)  + padding) + 'px',
      height:   (parseInt(this.contentHeight) + padding) + 'px',
      bottom:   '',
      right:    ''
    });
    this.storedPosition.top = (parseInt(this.storedPosition.top)-rTop[3] > 0?parseInt(this.storedPosition.top)-rTop[3]:0) + 'px';
    this.storedPosition.width  = cLeft[3] + 'px',
    this.storedPosition.height = rTop[3]  + 'px',
    div.hide().setStyle(this.storedPosition).setStyle({visibility: 'visible'});
    
    // configure Buttons
    var id = this.id;
    div.select('.btnClose').invoke('observe','click', this.hide.bind(this));
    div.select('.btnNext').invoke('observe','click', this.showNext.bind(this));
    div.select('.btnPrev').invoke('observe','click', this.showPrevious.bind(this));
  },
  show: function() {
    var oldPopup = this.collection.visible;
    if (!oldPopup) {
      this.zoomIn();
    } else if (oldPopup != this) {
      oldPopup.blendOut();
      this.blendIn();
    }
    this.collection.visible = this;
    return this;
  },
  hide: function() {
    var oldPopup = this.collection.visible;
    if (oldPopup && oldPopup == this) {
      this.zoomOut();
      this.collection.visible = null;
    }
    return this;
  },
  getPrevious: function() {
    var img = null;
    if (this.index == 0) {
      img = this.collection.all.last();
    } else {
      img = this.collection.all[this.index -1];
    }
    return this.collection.allByName[img];
  },
  getNext: function() {
    var img = null;
    if (this.id == this.collection.all.last()) {
      img = this.collection.all.first();
    } else {
      img = this.collection.all[this.index +1];
    }
    return this.collection.allByName[img];
  },
  showPrevious: function() {
    var popup = this.getPrevious();
    if (popup) popup.show();
    return popup;
  },
  showNext:  function() {
    var popup = this.getNext();
    if (popup) popup.show();
    return popup;
  },
  zoomIn: function() {
    // move image box to actual center of screen and correct scroll-position with offset
    var dimensions = document.viewport.getDimensions();
    var offsets = document.viewport.getScrollOffsets();
    // start animation: zoom in from thumb size to full size, move to center and blend in
    // movement is calculated from fully expanded position, eg. top-left corner and is relative to actual position
    var left = dimensions.width/2  + offsets.left - parseInt(this.storedPosition.width)/2;
    var top  = dimensions.height/2 + offsets.top  - parseInt(this.storedPosition.height)/2;
    var transformTo = {
      left:   (left < 0 ? 0 : left)  + 'px',
      top:    (top < 0 ? 0 : top) + 'px',
      width:  this.storedPosition.width,
      height: this.storedPosition.height
    };
    new Effect.Zoom(this.div,{
      zoomFrom:    (this.thumb.getWidth() / this.contentWidth * 100),
      zoomTo:      100.0,
      duration:    1.0,
      opacityFrom: 20.0,
      transformTo: transformTo,
      direction:   'bottom-left'
    });
  },
  zoomOut: function() {
    // start animation
    new Effect.Zoom(this.div,{
      zoomFrom:  100.0,
      zoomTo:    (this.thumb.getWidth() / this.contentWidth * 100),
      opacityTo: 20.0,
      duration:  1.0,
      transformTo: this.storedPosition,
      restoreAfterFinish: this.storedPosition,
      direction: 'bottom-left'
    });
  },
  blendIn: function() {
    // move image box to center of screen and correct scroll-position with offset
    var dimensions = document.viewport.getDimensions();
    var offsets = document.viewport.getScrollOffsets();
    var left = dimensions.width/2  + offsets.left - parseInt(this.storedPosition.width)/2;
    var top  = dimensions.height/2 + offsets.top  - parseInt(this.storedPosition.height)/2;
    var transformTo = {
      left:   (left < 0 ? 0 : left)  + 'px',
      top:    (top < 0 ? 0 : top) + 'px',
      width:  this.storedPosition.width,
      height: this.storedPosition.height
    };
    // start animation: only blend in
    this.div.setStyle(transformTo);
    new Effect.Zoom(this.div,{
      zoomFrom:    100.0,
      zoomTo:      100.0,
      duration:    1.0,
      opacityFrom: 20.0
    });
  },
  blendOut: function() {
    // start animation: only blend out
    new Effect.Zoom(this.div,{
      zoomFrom:  100.0,
      zoomTo:    100.0,
      opacityTo: 0.0,
      duration:  1.0,
      restoreAfterFinish: this.storedPosition
    });
  }
});


/*************************************/
/*  Mouse-Rollover-Klasse SWrollover */
/*************************************/
var SWrollover = Class.create();
Object.extend(SWrollover.prototype, {
  // container containing roll over links
  initialize: function(container) {
    this.container = $(container);
    this.options = Object.extend({
      selector: ['a[rel]','area[rel]','input[type="image"]']
    }, arguments[1] || { });
    // selector is rel
    var links = this.container.select(this.options.selector);
    var rel;
    for (var i=0,l=links.length;i<l;++i) {
      rel = links[i].readAttribute('rel');
      if (!rel) continue;
      rel = rel.split(':');
      if (rel[0] == 'SWrollover') {
        this.setupRollover(links[i],rel[1].split(','));
      } else if (rel[2] == 'SWrollover') {
        this.setupRollover(links[i],rel[3].split(','));
      }
    }
  },
  setupRollover: function(link,data) {
    // first is rollover, second is selected
    image = $(data[0]);
    if (!image)
      return;
    link.rolloverRepository = {
      state: null,
      element: image,
      src: image.src,
      over: null,
      click: null
    };
    link.rolloverRepository.getImage = (function() {
      return this.src
    }).bind(link.rolloverRepository);
    link.rolloverRepository.setImage = (function(src) {
      this.src = src.applyBaseHref(this.src);
      // preload rollover image
      (new Image()).src = this.src;
      if (!this.state)
        this.element.src = this.src;
    }).bind(link.rolloverRepository);
    link.rolloverRepository.getOverImage = (function() {
      return this.over
    }).bind(link.rolloverRepository);
    link.rolloverRepository.setOverImage = (function(src) {
      this.over = src.applyBaseHref(this.src);
      // preload rollover image
      (new Image()).src = this.over;
      if (this.state == 'over')
        this.element.src = this.over;
    }).bind(link.rolloverRepository);
    link.rolloverRepository.getClickImage = (function() {
      return this.click
    }).bind(link.rolloverRepository);
    link.rolloverRepository.setClickImage = (function(src) {
      item.click = src.applyBaseHref(item.src);
      // preload rollover image
      (new Image()).src = item.click;
      if (item.state == 'clicked')
        item.element.src = item.click;
    }).bind(link.rolloverRepository);
    // backlink from image
    if (!image.rolloverHandlers)
      image.rolloverHandlers = new Array();
    image.rolloverHandlers[image.rolloverHandlers.length] = link.rolloverRepository;
    if (data[1] && data[1] != "") {
      this.setupOverHandler(link);
      link.rolloverRepository.setOverImage(data[1]);
    }
    if (data[2] && data[2] != "") {
      this.setupClickHandler(link);
      link.rolloverRepository.setClickImage(data[2]);
    }
  },
  getImage:      function(item)     {return item.getImage();},
  setImage:      function(item,src) {return item.setImage(src);},
  getOverImage:  function(item)     {return item.getOverImage();},
  setOverImage:  function(item,src) {return item.setOverImage(src);},
  getClickImage: function(item)     {return item.getClickImage();},
  setClickImage: function(item,src) {return item.setClickImage(src);},
  setupOverHandler: function(link) {
    link.observe('mouseover', this.overImage);
    link.observe('mouseout', this.restoreImage);
  },
  setupClickHandler: function(link) {
    link.observe('click', this.clickImage);
    link.observe('mouseout', this.restoreImage);
  },
  overImage: function(e) {
    var item = this.rolloverRepository;
    if (!item || item.state == 'over')
      return;
    item.element.src = item.over;
    item.state = 'over';
  },
  clickImage: function(e) {
    var item = this.rolloverRepository;
    if (!item || item.state == 'clicked')
      return;
    item.element.src = item.click;
    item.state = 'clicked';
  },
  restoreImage: function(e) {
    var item = this.rolloverRepository;
    if (!item || !item.state)
      return;
    item.element.src = item.src;
    item.state = null;
  }
});

/*************************************/
/*  Ajax-Klassen                     */
/*************************************/
var SWGetObjectHandler = function(t) {
  var xmlDoc = t.responseXML.documentElement;
  var target, tagName;
  var nodes=xmlDoc.childNodes;
  for (var i=0,l=nodes.length;i<l;++i) {
    if (nodes[i].nodeName) {
      tagName = nodes[i].nodeName.split(":");
      if (tagName[0] == "siteware") {
        try {
          if (tagName[1] == "objectID") {
            $("idObjectID").value = nodes[i].firstChild.nodeValue;
          } else {
            target = $(nodes[i].getAttribute("for"));
            if (target) {
              target.update(nodes[i].firstChild.nodeValue.replace(/\]\]->/g, "]]"+">"));
              SWwindowInit(target);
            }
          }
        } catch (e) {
          alert("Update failed with message: "+e);
        }
      }
    }
  }
  return;
}
var SWErrorHandler = function(t) {
    alert('Error ' + t.status + ' -- ' + t.statusText);
}

Ajax.Responders.register({
  onCreate: function(f) {
    if (f.options.btn)
      f.options.btn.invoke('setStyle',{visibility:'visible'});
    else if (Ajax.activeRequestCount > 0)
      $("idAjaxStatus").setStyle({visibility:'visible'});
  },
  onComplete: function(f) {
    if (f.options.btn)
      f.options.btn.invoke('setStyle',{visibility:'hidden'});
    else if (Ajax.activeRequestCount == 0)
      $("idAjaxStatus").setStyle({visibility:'hidden'});
  }
});
/*************************************/
/*  Highlight-Klassen                */
/*************************************/
var SWre = {
  on:    /-(armed|off)\.(gif|jpg|png)$/,
  off:   /-(armed|on)\.(gif|jpg|png)$/,
  armed: /-(off|on)\.(gif|jpg|png)$/
}
var SWblur = function(){if(this.blur)this.blur();}
var SWhighlight = function() {
  if (!SWclickedItem || this != SWclickedItem) {
    this.addClassName('rowHover');
    if (arguments[1] && arguments[1].length > 0)
      arguments[1].each(SWhighlightBtn);
    if (arguments[2] && arguments[2].length > 0)
      arguments[2].invoke('setStyle',{visibility:'visible'});
  }
}
var SWunHighlight = function() {
  if (!SWclickedItem || this != SWclickedItem) {
    this.removeClassName('rowHover');
    if (arguments[1] && arguments[1].length > 0)
      arguments[1].each(SWunHighlightBtn);
    if (arguments[2] && arguments[2].length > 0)
      arguments[2].invoke('setStyle',{visibility:'hidden'});
  }
}
var SWhighlightBtn = function(el) {
  if (el.src) el.src = el.src.replace(SWre.on,'-on.$2');
}
var SWunHighlightBtn = function(el) {
  if (el.src) el.src = el.src.replace(SWre.off,'-off.$2');
}
var SWarmBtn = function(el) {
  if (el.src) el.src = el.src.replace(SWre.armed,'-armed.$2');
}
var SWclick = function(msg) {
  if (SWclickedItem && this != SWclickedItem) {
    SWclickedItem.removeClassName('rowActive');
    if (SWclickedBtnHl && SWclickedBtnHl.length > 0)
      SWclickedBtnHl.each(SWunHighlightBtn);
    if (SWclickedBtnVs && SWclickedBtnVs.length > 0)
      SWclickedBtnVs.invoke('setStyle',{visibility:'hidden'});
  }
  if (!SWclickedItem || this != SWclickedItem || msg == 'clicked') {
    SWclickedItem = this;
    //{item: this, btn1: arguments[1], btn2: arguments[2]};
    this.addClassName('rowActive').removeClassName('rowHover');
    if (arguments[1] && arguments[1].length > 0) {
      SWclickedBtnHl = arguments[1];
      SWclickedBtnHl.each(SWarmBtn);
    }
    if (arguments[2] && arguments[2].length > 0) {
      SWclickedBtnVs = arguments[2];
      SWclickedBtnVs.invoke('setStyle',{visibility:'visible'});
    }
  }
}
var SWregisterHighlightHandler = function(el) {
  if (el.SWoverHandler)
    Event.stopObserving(el,'mouseover',el.SWoverHandler);
  if (el.SWoutHandler)
    Event.stopObserving(el,'mouseout',el.SWoutHandler);
  el.SWoverHandler = SWhighlight.bindAsEventListener(el,el.select('[class~="SW_BTN_HL"]'),el.select('[class~="SW_BTN_HD"]'));
  el.SWoutHandler = SWunHighlight.bindAsEventListener(el,el.select('[class~="SW_BTN_HL"]'),el.select('[class~="SW_BTN_HD"]'));
  Event.observe(el,'mouseover',el.SWoverHandler);
  Event.observe(el,'mouseout',el.SWoutHandler);
}
var SWregisterClickHandler = function(el) {
  if (el.SWclickHandler)
    Event.stopObserving(el,'click',el.SWclickHandler);
  el.SWclickHandler = SWclick.bindAsEventListener(el,el.select('[class~="SW_BTN_HL"]'),el.select('[class~="SW_BTN_HD"]'));
  Event.observe(el,'click',el.SWclickHandler);
}
var SWmakeFocusHidable = function(el) {
  if (el.tagName.toLowerCase() == "area")
    el.observe('click',SWblur.bindAsEventListener(el));
  else
    el.observe('focus',SWblur.bindAsEventListener(el));
}
var SWwindowInit = function(target) {
  target = $(target);
  // initialize highlightables and clickables
  if (target.hasClassName('SW_CL')) {
    SWregisterClickHandler(target);
    // tell children that they just have been clicked...
    target.SWclickHandler('clicked');
  } else {
    target.select('[class~="SW_CL"]').each(SWregisterClickHandler);
  }
  if (target.hasClassName('SW_HL'))
    SWregisterHighlightHandler(target);
  else
    target.select('[class~="SW_HL"]').each(SWregisterHighlightHandler);
  // initialize rollover images
  new SWrollover(target);
  // initialize popup windows
  new SWpopupCollection(target);
  // remove focus boxes from links
  target.select(['a','input[type="image"]','area']).each(SWmakeFocusHidable);
}
var SWclickedItem  = null;
var SWclickedBtnHl = null;
var SWclickedBtnVs = null;

var __windowInit = function() {
  SWwindowInit(document.getElementsByTagName("body")[0]);
}

if (window.attachEvent) {
  window.attachEvent("onload", __windowInit);
} else {
  window.addEventListener("load", __windowInit, true);
}

if(top!=self)top.location.href=self.location.href;
