/* Sputnik-specific JS */

var max_length_username = 20;

var maps_myxInfoWindow_beakOffset = 48;
var maps_myxInfoWindow_commOffset = -9;
var maps_myxInfoWindow_genOffset = 10;

var maps_myxIcon_image = new Array();
maps_myxIcon_image['normal']      = "/img_sputnik/maps/marker.png";

var maps_myxIcon_shadow = new Array();
maps_myxIcon_shadow['normal']     = "/img_sputnik/maps/marker_shadow.png";

var maps_myxIcon_iconSize = [41, 48];
var maps_myxIcon_shadowSize = [41, 48];
var maps_myxIcon_iconAnchor = [18, 47];


/*  Bubblebox2, version 0.1
 *  (c) 2009 Martin Andert
 *
 *--------------------------------------------------------------------------*/

var Bubblebox = {
  Version: '0.1',
  RequiredPrototypeVersion: '1.6.0.3',
  checkDependencies: function() {
    function convertVersionString(versionString) {
      var v = versionString.replace(/_.*|\./g, '');
      v = parseInt(v + '0'.times(4 - v.length), 10);
      return versionString.indexOf('_') > -1 ? v - 1 : v;
    }

    if ((typeof Prototype == 'undefined') || (typeof Element == 'undefined') || (typeof Element.Methods == 'undefined') || 
        (convertVersionString(Prototype.Version) < convertVersionString(Bubblebox.RequiredPrototypeVersion))) {
      throw("bubblebox2.js requires the Prototype JavaScript framework >= " + Bubblebox.RequiredPrototypeVersion);
    }

    if (typeof Element.Storage == 'undefined') {
      throw("bubblebox2.js requires including element_storage.js, a Prototype JavaScript framework extension");
    }
    
    return true;
  }
};

Bubblebox.checkDependencies();

Bubblebox.Item = Class.create({
  initialize: function(element, text, options) {
    this.element = element = $(element);
    this.text = text;
    
    this.options = Object.clone(Bubblebox.Item.DefaultOptions);
    Object.extend(this.options, options || {});
    
    if (this.element.title) {
      this.element.title = '';
    }
    
    try {
      this.element.select('[alt]').each(function(descendant) {
        descendant.alt = '';
      });
    } catch (e) {}
    
    this.registerListeners();
  },
  registerListeners: function() {
    this._listeners = {};
    var listener;
    $H(Bubblebox.Item.Listeners).each(function(pair) {
      listener = this[pair.value].bind(this);
      this._listeners[pair.key] = listener;
      this.element.observe(pair.key, listener);
    }.bind(this));
  },
  onMouseEnter: function(e) {    
    this._cancelled = false;
    
    this.positionX = e.pointerX();
    this.positionY = e.pointerY();
    
    this._mouseMoveListener = this.onMouseMove.bind(this);
    this.element.observe('mousemove', this._mouseMoveListener);
    
    Bubblebox.setText(this.text);
    
    this._timeout = window.setTimeout(function() {
      if (!(this._cancelled)) {
        Bubblebox.moveTo(this.positionX, this.positionY);
        Bubblebox.show(this.options.opaque);
      }
    }.bind(this), this.options.delay);
  },
  onMouseLeave: function(e) {
    this.hide();
  },
  onClick: function(e) {
    this.hide();
  },
  onMouseMove: function(e) {    
    this.positionX = e.pointerX();
    this.positionY = e.pointerY();
    
    Bubblebox.moveTo(this.positionX, this.positionY);
  },
  hide: function() {
    Bubblebox.hide();
    
    if (!(this._cancelled)) {
      this.element.stopObserving('mousemove', this._mouseMoveListener);
      window.clearTimeout(this._timeout);
      this._cancelled = true;
    }
  }
});

Object.extend(Bubblebox.Item, {
  DefaultOptions: {
    delay: 1500,
    opaque: false
  }
});

if (Prototype.Browser.IE) {
  Object.extend(Bubblebox.Item, {
    Listeners: {
      'mouseenter': 'onMouseEnter',
      'mouseleave': 'onMouseLeave',
      'click': 'onClick'
    }
  });
}
else {
  Object.extend(Bubblebox.Item, {
    Listeners: {
      'mouse:enter': 'onMouseEnter',
      'mouse:leave': 'onMouseLeave',
      'click': 'onClick'
    }
  });
}

Object.extend(Bubblebox, {
  RecognizedTags: ['a', 'img', 'li', 'div', 'span', 'button'],
  RecognizedHolderClasses: ['.bubblebox-holder'],
  OffsetX: 8,
  OffsetY: 20,
  MaxWidth: 300,
  HtmlTemplate: 
    '<div id="bubblebox_frame">' +
      '<div class="top">' +
        '<div id="bubblebox_stem_t" class="stem-lt">&nbsp;</div>' +
      '</div>' +
      '<div id="bubblebox_content" class="content">' +
        '<span id="bubblebox_text">&nbsp;</span>' +
      '</div>' +
      '<div class="bottom">' +
        '<div id="bubblebox_stem_b">&nbsp;</div>' +
      '</div>' +
    '</div>',
  items: [],
  init: function() {
    if (document.body) {
      Bubblebox.container = Bubblebox._createContainer();
      document.body.appendChild(Bubblebox.container);
      
      $('bubblebox_content').addClassName(Prototype.Browser.IE ? 'overflow_ie' : 'overflow_non_ie');
      
      return Bubblebox.enable(document.body);
    }
    
    return false;
  },
  _createContainer: function() {
    var div = document.createElement('div');
    div.id = 'bubblebox';
    div.style.display = 'none';
    div.innerHTML = Bubblebox.HtmlTemplate;
    
    return div;
  },
  enable: function(parent) {
    if (Prototype.Browser.IE || !(parent = $(parent))) { return false; }
    
    Bubblebox._enableRecognizedTags(parent);
    Bubblebox._enableImplicitHolders(parent);
    
    return true;
  },
  _enableRecognizedTags: function(parent) {    
    parent.select(Bubblebox.RecognizedTags).each(function(element) {      
      if (!element.retrieve('bubblebox:enabled', false) && element.title) {
        Bubblebox._registerItem(element, element.title, {});
      }
    });
  },
  _enableImplicitHolders: function(parent) {
    parent.select(Bubblebox.RecognizedHolderClasses).each(function(holder) {
      var element = holder.previous();
      
      if (element && !element.retrieve('bubblebox:enabled', false)) {
        var options = {};
        
        if (holder.hasClassName('bubblebox-opaque')) {
          options.opaque = true;
        }
        
        if (holder.hasClassName('bubblebox-nodelay')) {
          options.delay = 0;
        }
        
        Bubblebox._registerItem(element, holder.innerHTML, options);
      }
    });
  },
  _registerItem: function(element, text, options) {
    Bubblebox.items.push(new Bubblebox.Item(element, text, options));
    element.store('bubblebox:enabled', true);
  },
  setText: function(text) {
    $('bubblebox_text').innerHTML = text;
    Bubblebox._resize();
  },
  moveTo: function(mouseX, mouseY) {
    var viewportDimensions = document.viewport.getDimensions();
    var viewportScrollOffsets = document.viewport.getScrollOffsets();
    
    Bubblebox._viewport = { 
      left: viewportScrollOffsets.left,
      top: viewportScrollOffsets.top,
      width: viewportDimensions.width,
      height: viewportDimensions.height };
    
    Bubblebox.container.style.left = Bubblebox._calculateXPosition(mouseX) + 'px';
    Bubblebox.container.style.top = Bubblebox._calculateYPosition(mouseY) + 'px';
    Bubblebox._adjustStem();
  },
  show: function(opaque) {
    if (opaque) {
      Bubblebox.container.removeClassName('semitransparent');
    }
    else {
      Bubblebox.container.addClassName('semitransparent');
    }
    
    Bubblebox.container.show();
  },
  hide: function() {
    Bubblebox.container.hide();
  },
  _adjustStem: function() {
    if (Bubblebox._stemOrientation.top) {
      $('bubblebox_stem_b').removeClassName('stem-lb').removeClassName('stem-rb');
      
      if (Bubblebox._stemOrientation.left) {
        $('bubblebox_stem_t').removeClassName('stem-rt').addClassName('stem-lt');
      }
      else {
        $('bubblebox_stem_t').removeClassName('stem-lt').addClassName('stem-rt');
      }
    }
    else {
      $('bubblebox_stem_t').removeClassName('stem-lt').removeClassName('stem-rt');
      
      if (Bubblebox._stemOrientation.left) {
        $('bubblebox_stem_b').removeClassName('stem-rb').addClassName('stem-lb');
      }
      else {
        $('bubblebox_stem_b').removeClassName('stem-lb').addClassName('stem-rb');
      }
    }
  },
  _stemOrientation: { left: true, top: true },
  _calculateXPosition: function(mouseX) {
    var bubbleboxRight = mouseX + Bubblebox.OffsetX + Bubblebox._currentSize.width;
    var windowRight = Bubblebox._viewport.left + Bubblebox._viewport.width;
    var result;
    
    if (windowRight >= bubbleboxRight) {
      Bubblebox._stemOrientation.left = true;
      result = mouseX + Bubblebox.OffsetX;
    }
    else {
      Bubblebox._stemOrientation.left = false;
      result = mouseX - Bubblebox.OffsetX - Bubblebox._currentSize.width;
    }
    
    return Math.max(0, result);
  },
  _calculateYPosition: function(mouseY) {
    var bubbleboxBottom = mouseY + Bubblebox.OffsetY + Bubblebox._currentSize.height;
    var windowBottom = Bubblebox._viewport.top + Bubblebox._viewport.height;
    var result;
    
    if (windowBottom >= bubbleboxBottom) {
      Bubblebox._stemOrientation.top = true;
      result = mouseY + Bubblebox.OffsetY;
    }
    else {
      Bubblebox._stemOrientation.top = false;
      result = mouseY - Bubblebox.OffsetY / 4 - Bubblebox._currentSize.height;
    }
    
    return Math.max(0, result);
  },
  _getTextWidth: function() {
    var els = Bubblebox.container.style;
    var originalVisibility = els.visibility;
    var originalDisplay = els.display;
    
    els.visibility = 'hidden';
    els.display = 'block';
    
    var width = $('bubblebox_text').getWidth();
    
    els.display = originalDisplay;
    els.visibility = originalVisibility;
    
    return width;
  },
  _resize: function() {
    $('bubblebox_frame').style.width = '100%';
    
    var padding = 30;
    var maxWidth = Bubblebox.MaxWidth + padding;
    var requiredWidth = Bubblebox._getTextWidth() + padding;
    
    if (requiredWidth <= maxWidth) {
      $('bubblebox_frame').style.width = requiredWidth + 'px';
    }
    else {
      $('bubblebox_frame').style.width = maxWidth + 'px';
      requiredWidth = Bubblebox._getTextWidth() + padding;
      $('bubblebox_frame').style.width = requiredWidth + 'px';
    }
    
    Bubblebox._currentSize = Bubblebox.container.getDimensions();
  }
});

document.observe('dom:loaded', function() {
  function respondToMouseOver(event) {
    var target = event.element();
    
    if (event.relatedTarget && !event.relatedTarget.descendantOf(target))
      target.fire("mouse:enter");
  }
  
  function respondToMouseOut(event) {
    var target = event.element();
    
    if (event.relatedTarget && !event.relatedTarget.descendantOf(target))
      target.fire("mouse:leave");
  }

  /*
   *  Fires "mouse:enter" and "mouse:leave" events in non-IE browsers 
   *  as a substitute for the "mouseenter" and "mouseleave" events.
   */
  if (!Prototype.Browser.IE) {
    document.observe("mouseover", respondToMouseOver);
    document.observe("mouseout",  respondToMouseOut);
  }
  
  if (!Prototype.Browser.IE) {
    Bubblebox.init.delay(1);
  }
});



/*  CheckboxToggleizer, version 0.1
 *  (c) 2009 Martin Andert
 *
 *  Synopsis: Within a group of checkboxes, this javascript unobstrusively 
 *  handles the checked state of a controlling checkbox (one that toggles 
 *  all other checkboxes on or off). Only some predefined stylesheet class 
 *  names must be set in the HTML code to enable this feature.
 *
 *  HTML example (showing the needed CSS classes):
 *
 *    <div class="ct_container">
 *      <input type="checkbox" name="chk_all" class="ct_toggler" /> all
 *      <input type="checkbox" name="chk_act" class="ct_item" /> active
 *      <input type="checkbox" name="chk_del" class="ct_item" /> deleted
 *    </div>
 *
 *--------------------------------------------------------------------------*/

var CheckboxToggleizer = Class.create({
  initialize: function(container) {
    this.container = $(container);
    
    this.toggler = this.container.select('input[type=checkbox].ct_toggler').first();
    this.items = this.container.select('input[type=checkbox].ct_item');
    
    if (Object.isUndefined(this.toggler) || this.items.length == 0) {
      return;
    }
    
    this.updateTogglerState();
    
    var togglerClickHandler = this.onTogglerClick.bind(this);
    var itemClickHandler = this.onItemClick.bind(this);
    
    this.toggler.observe('click', togglerClickHandler);
    this.items.invoke('observe', 'click', itemClickHandler);
  },
  onTogglerClick: function() {
    var state = this.toggler.checked;
    
    this.items.each(function(item) {
      item.checked = state;
    });
  },
  onItemClick: function() {
    this.updateTogglerState();
  },
  updateTogglerState: function() {
    this.toggler.checked = this.items.all(function(item) {
      return item.checked;
    });    
  }
});

Object.extend(CheckboxToggleizer, {
  instances: [],
  scan: function() {
    $$('.ct_container').each(function(container) {
      CheckboxToggleizer.instances.push(new CheckboxToggleizer(container));
    });
  }
});

document.observe('dom:loaded', CheckboxToggleizer.scan);



var authenticityToken = '';

/*
 * AJAX spinner (aka 'loading_image')
 */
var scX=1000;
var msX=0;
var msY=0;

Event.observe(window, 'load', function() {
        if (self.innerWidth){
                scX = self.innerWidth;
        }
        else if (document.documentElement && document.documentElement.clientWidth){
                scX = document.documentElement.clientWidth;
        }
        else if (document.body){
                scX = document.body.clientWidth;
        }
        Event.observe(document.body, 'mousedown', function(event) {
                getPos(event);
        });
});


function showSpinner(){
        if($('spinner')){
                moveSpinner();
                document.onmousemove = function (e) {
                        getPos(e);
                        moveSpinner();
                };
        }
}

function moveSpinner(){
        if(msX+$('spinner').getWidth()>=scX-20){
                $('spinner').style.left="-1000px";
        }
        else{
                $('spinner').style.left=msX+"px";
        }
        $('spinner').style.top=msY+"px";
}

function hideSpinner(){
        if (Ajax.activeRequestCount < 1 && $('spinner')) {
                $('spinner').style.left="-1000px";
                document.onmousemove = null;
        }
}

function getPos(e){
        if (!e) var e = window.event;
        msX=Event.pointerX(e)+12;
        msY=Event.pointerY(e)+12;
}


Ajax.Responders.register({
  onCreate: function(requester) {
    if (!this.isStatusBoxUpdaterRequest(requester)) {
      showSpinner();
    }
  },

  onComplete: function(requester) {
    if (!this.isStatusBoxUpdaterRequest(requester)) {
      hideSpinner();
    }
  },

  isStatusBoxUpdaterRequest: function(r) {
    return /\/(uploads\?|update_(statusbox_info|motion_detector)$)/.test(r.url);
  }
});

function closeHighslide(element) {
  hs.close($(element));
}

function delayedAlert(message, delay) {
  window.setTimeout("alert('" + message + "')", delay);
}



/*
 * Clientseitige Funktionalität für die Suche-Webseite
 */
var elements = ['users', 'audios', 'videos', 'pictures', 'texts', 'groups'];

function checkBoxes(box) {
  if (box == $('mode_all')) {
    elements.each(function(element) {
      if ($('mode_' + element))
        $('mode_' + element).checked = box.checked;
    });
  }
  else if (box.checked) {
    $('mode_all').checked = elements.all(function(element) {
      if ($('mode_' + element))
        return $('mode_' + element).checked;
      else
        return true;
    });
  }
  else
    $('mode_all').checked = false;
}

function validateForm() {
  query = $F('q').strip();

  if (query.length < 2) {
    alert(error_query_minlength);
    $('q').focus();
    return false;
  }

  $('q').value = query;

  $('e').value = elements.select(function(element) {
    return $('mode_' + element).checked;
  }).join(',');

  return true;
}



/*
 * Clientseitige Funktionalität für die FAQ-Webseite
 */
function toggleFaqAnswer(id, prefix) {
  var q_tag = $(prefix + 'faq_' + id + '_question');
  var a_tag = $(prefix + 'faq_' + id + '_answer');

  if (a_tag.visible()) {
    Effect.toggle(a_tag, 'slide', { duration: 0.25, afterFinish: function() {
      q_tag.removeClassName('up');
    }});

    //q_tag.removeClassName('up');
    //a_tag.hide();
  }
  else {
    Effect.toggle(a_tag, 'slide', { duration: 0.25, afterFinish: function() {
      q_tag.addClassName('up');
    }});

    //q_tag.addClassName('up');
    //a_tag.show();

    new Ajax.Request('/faq/increment_visits/' + id, { method: 'get' });
  }
}


/*
 * Clientseitige Funktionalität für die Adressen A-Z-Webseite
 */
function toggleAddressAnswer(id, prefix) {
  var q_tag = $(prefix + 'address_' + id + '_question');
  var a_tag = $(prefix + 'address_' + id + '_answer');

  if (a_tag.visible()) {
    Effect.toggle(a_tag, 'slide', { duration: 0.25, afterFinish: function() {
      q_tag.removeClassName('up');
    }});

    //q_tag.removeClassName('up');
    //a_tag.hide();
  }
  else {
    Effect.toggle(a_tag, 'slide', { duration: 0.25, afterFinish: function() {
      q_tag.addClassName('up');
    }});

    //q_tag.addClassName('up');
    //a_tag.show();

    new Ajax.Request('/address/increment_visits/' + id, { method: 'get' });
  }
}




/*
 * Clientseitige Funktionalität für Kommentare
 */
function incrementCommentsCount(pid, cname, cid) {
  current = parseInt($(pid + '_comments_count_' + cname + '_' + cid).innerHTML);
  $(pid + '_comments_count_' + cname + '_' + cid).innerHTML = (current + 1);
}

function decrementCommentsCount(pid, cname, cid) {
  current = parseInt($(pid + '_comments_count_' + cname + '_' + cid).innerHTML);
  $(pid + '_comments_count_' + cname + '_' + cid).innerHTML = (current - 1);
}



/*
 * Clientseitige Funktionalität für Tags/Taggings
 */
function addToTaggingsCount(pid, tname, tid, i) {
  current = parseInt($(pid + '_taggings_count_' + tname + '_' + tid).innerHTML);
  $(pid + '_taggings_count_' + tname + '_' + tid).innerHTML = (current + i);
}

function incrementTaggingsCount(pid, tname, tid) {
  current = parseInt($(pid + '_taggings_count_' + tname + '_' + tid).innerHTML);
  $(pid + '_taggings_count_' + tname + '_' + tid).innerHTML = (current + 1);
}

function decrementTaggingsCount(pid, tname, tid) {
  current = parseInt($(pid + '_taggings_count_' + tname + '_' + tid).innerHTML);
  $(pid + '_taggings_count_' + tname + '_' + tid).innerHTML = (current - 1);
}






/*
 * Contentanzeige im Flashplayer/Highslide
 */
function incrementContentHits(id, c, a) {
  new Ajax.Request('/content/increment_hits/' + id + '?c=' + c + '&a=' + a, { asynchronous: true, evalScripts: true, method: 'put', parameters: 'authenticity_token=' + encodeURIComponent(authenticityToken) });
}

function openPicture(element, id, captionId) {
  var result = hs.expand(element, { captionId: captionId,
                                    wrapperClassName: 'highslide-control-wrapper',
                                    slideshowGroup: 'picture' });
  incrementContentHits(id, 'picture', 'highslide');
  return result;
}

function openText(element, id) {
  var result = hs.htmlExpand(element, { elementClassName: 'highslide_text_content',
                                        contentId: 'highslideBlogContainer',
                                        objectType: 'ajax', cacheAjax: false });
  incrementContentHits(id, 'blogs', 'single');
  return result;
}

function openArticle(element, id) {
  var result = hs.htmlExpand(element, { elementClassName: 'highslide_text_content',
                                        contentId: 'highslideBlogContainer',
                                        objectType: 'ajax', cacheAjax: false });
  incrementContentHits(id, 'blogs', 'single_valid');
  return result;
}

function openAudio(element, id) {
  window.open('/flashplayer/show?w=213&h=166&dsh=120&layout=1&t=a&ids=' + id,
              'myx_audio_stream',
              'height=164,width=213');

  incrementContentHits(id, 'flashplayer', 'audio');
  return false;
}

function openVideo(element, id) {
  window.open('/flashplayer/show?w=480&h=404&dsh=360&layout=1&sfsb=1&ids=' + id,
              'myx_video_stream',
              'height=404,width=480');

  incrementContentHits(id, 'flashplayer', 'video');
  return false;
}

function openPlaylist(element, ids) {
  var h = 140 + Math.min(ids.length, 20) * 23;

  window.open('/flashplayer/show?w=213&h=' + h + '&dsh=120&layout=1&t=a&ids=' + ids.join('_'),
              'myx_audio_stream',
              'height=' + h + ',width=213');

  for (var i = 0, len = ids.length; i < len; ++i) {
    incrementContentHits(ids[i], 'flashplayer', 'audio');
  }

  return false;
}

function openAudioPlaylist(element, ids, playlistId) {
  var h = 140 + Math.min(ids.length, 20) * 23;

  window.open('/flashplayer/show?w=213&h=' + h + '&dsh=120&layout=1&t=a&ids=' + ids.join('_'),
              'myx_audio_stream',
              'height=' + h + ',width=213');

  for (var i = 0, len = ids.length; i < len; ++i) {
    incrementContentHits(ids[i], 'flashplayer', 'audio');
  }

  incrementContentHits(playlistId, 'flashplayer', 'audio_playlist');

  return false;
}

function openVideoPlaylist(element, ids, playlistId) {
  window.open('/flashplayer/show?w=480&h=404&dsh=360&layout=1&sfsb=1&ids=' + ids.join('_'),
              'myx_video_stream',
              'height=404,width=480');

  for (var i = 0, len = ids.length; i < len; ++i) {
    incrementContentHits(ids[i], 'flashplayer', 'video');
  }

  incrementContentHits(playlistId, 'flashplayer', 'video_playlist');

  return false;
}


/**
 * Funktion zum Erzeugen eines Select-Feldes
 *  - Element wird in Div geschrieben, dessen ID uebergeben wird
 *  - args:
 *    - previous_div_name:    String:   ID/Name des divs, in dessen Ende die select-boxen eingefuegt werden sollen
 *    - el_name:              String:   ID/Name der zu erzeugenden Select-Box
 *    - genre_string:         String:   vollst. Inhalts-Baum fuer Select-Boxen
 *    - depth:                Integer:  aktuelle Abstiegstiefe
 *    - div_inline:           Integer:  divs mit style="diplay:inline" erzeugen (1:ja, 0:nein)
 *    - empty_option_text:    String:   Text fuer leere Option
 *    - preselect:            String:   Pfad zur Vorauswahl bzw. ausgewaehlter Wert, dessen Unterselect-boxen erzeugt werden sollen
 *    - as_text:              Boolean:  zu erzeugende Elemente nicht direkt rendern, sondern als Text liefern
 *    - is_new:               Boolean:  true: erzeuge diese Select-Box neu; false: erzeuge Child-Select-box neu
 *    - print_label:          Boolean:  true: zeige Label fuer Subgenres an; false: lass das bleiben
 *    - spacer:               String:   Alternativer Zwischenraumtext (Default: '')
 */
function create_genre_select(previous_div_name, el_name, genre_string, depth, div_inline, empty_option_text, preselect, as_text, is_new, print_label, spacer){

  depth = parseInt(depth);            // aktuelle Genre-Pfad-Tiefe
  div_inline = parseInt(div_inline);
  empty_option_text = (typeof(empty_option_text) != 'undefined') ? empty_option_text : '';    // default-Wert fuer leeres Option-Feld
  preselect = (typeof(preselect) != 'undefined') ? preselect : '';    // default-Wert fuer Vorauswahl
  as_text = (typeof(as_text) != 'undefined') ? as_text : false;       // default-Wert fuer as_text
  is_new = (typeof(is_new) != 'undefined') ? is_new : true;           // default-Wert fuer is_new
  print_label = (typeof(print_label) != 'undefined') ? print_label : true;           // default-Wert fuer print_label
  spacer = (typeof(spacer) != 'undefined') ? spacer : '';
  var level_hash = $H({});
  var genres = genre_string.split(':');
  for (var i = 0; i < genres.length; i++){
    var genre = genres[i];
    var right = genre.length - 1;
    if(genre.indexOf('~') >= 0  && genre.indexOf('*') >= 0){
      right = (genre.indexOf('~') < genre.indexOf('*')) ? genre.indexOf('~') : genre.indexOf('*');
    }else if(genre.indexOf('~') >= 0){
      right = genre.indexOf('~');
    }else if(genre.indexOf('*') >= 0){
      right = genre.indexOf('*');
    }

    var levelname = genre.replace(/[~\*].*$/,"");
    if(level_hash.keys().indexOf(levelname) == -1){
      // neu anlegen mit Platz fuer id
      level_hash.set(levelname, new Array(1));
    }
    if(genre.substring(right).match(/^\*\d+$/)){
      // Map-Wert eintragen
      level_hash.get(levelname)[0] = genre.substring(right + 1);
    }else{
      level_hash.get(levelname).push(genre.substring(right + 1));
    }
  }

  var sel_box_name = el_name + "_" + depth.toString();
  var child_div_name = new String("div_" + sel_box_name);
  var option_tags = '';             // Optionseintraege
  var select_empty_option = true;   // waehle per Default die leere Option
  var levels = level_hash.keys();   // Array von Strings der Levelnamen dieses Levels

  // Vorauswahl bestimmen
  var selected_val = '';      // Name des ersten Levels des vorausgewaehlten Eintrags
  var select_next = '';       // Restlicher Pfad unter selected_val
  if(preselect.length > 0 ){
    // hole Namen des vordersten Levels des vorausgewaehlten Pfades
    right = preselect.length - 1;
    if(preselect.indexOf('~') >= 0  && preselect.indexOf('*') >= 0){
      right = (preselect.indexOf('~') < preselect.indexOf('*')) ? preselect.indexOf('~') : preselect.indexOf('*');
    }else if(preselect.indexOf('~') >= 0){
      right = preselect.indexOf('~');
    }else if(preselect.indexOf('*') >= 0){
      right = preselect.indexOf('*');
    }
    selected_val = preselect.substring(0, right);
    // bestimme den Rest des vorausgewaehlten Pfades

    if(right < (preselect.length - 1) ){
      select_next = preselect.substring(right + 1);
    }
  }

  var genre_string_next = '';     // generiere Genrebaum fuer naechsten Level
  var path_of_next_level = '';
  // wenn auf tieferer Ebene und ein vorausgewaehltes Element existiert, dann nur Optionsfelder fuer dessen direkte Kinder erzeugen
  for(var i = 0; i < levels.length; i++){
    var next_level = '';
    levelname = levels[i];
    option_tags += "<option value='" + levelname + "*" + level_hash.get(levelname)[0] + "'";
    if(level_hash.get(levelname).length > 1){
      // naechste Ebene vorbereiten
      next_level = level_hash.get(levelname).slice(1).join(':');
      genre_string_next += (genre_string_next.length > 0) ? ':' : '';
      genre_string_next += next_level;
      // nur hier ist der Pfad fuer den naechsten Level bekannt, wenn schon eine Vorauswahl besteht
      if(select_empty_option && (levelname == selected_val)){
        path_of_next_level = next_level;
      }
    }
    if(select_empty_option && (levelname == selected_val)){
      // auszuwaehlendes Element gefunden
      select_empty_option = false;
      option_tags += " selected='selected' ";
    }
    option_tags += ">" + levelname + "</option>\n";
  }
  option_tags += "</select>\n";

  var empty_option = '';if(select_empty_option){
    empty_option = "<option value='' selected='selected' >" + empty_option_text + "</option>\n";
  }else{
    empty_option = "<option value=''>" + empty_option_text + "</option>\n";
  }
  // Codeaufruf fuer naechsten Level
  var recursive_call = 'onchange="create_genre_select(\'' + child_div_name + '\', \'' + el_name + '\', \'' + genre_string + '\', ' + (depth).toString() + ', ' + div_inline + ' , \'' + empty_option_text + '\', this.value, false, false, ' + print_label + ', \'' + spacer + '\');"';
  var div_style = (div_inline == 1) ? " style='display:inline' " : "";
  // setze html-String fuer select-box zusammen
  var sel_box = "";
  // wenn gewuenscht und Tiefe groesser 0, dann Label fuer Subgenres setzen
  if(print_label && depth > 0){
    sel_box += '<label for="genre_' + depth.toString() + '">' + (spacer.length > 0 ? spacer : ("Subgenre " + depth.toString() + " wählen:")) + '</label>'
  }
  sel_box += "<select id='" + sel_box_name + "' name='" + sel_box_name + "'" + recursive_call + ">\n" + empty_option + option_tags + "</select>\n";
  var child_div = new String("<div id='" + child_div_name + "' class='multi' name='" + child_div_name + "' " + div_style + ">");
  // bei gefundenem preselect-Wert und weiterem Pfad naechsten Level erzeugen
  if(!select_empty_option && path_of_next_level.length > 0){
    // rekursiver Abstieg mit Stringerzeugung statt direktem Rendern
    child_div += create_genre_select(child_div_name, el_name, path_of_next_level, (depth+1).toString(), div_inline, empty_option_text, select_next, true, true, print_label, spacer);
  }
  child_div += "</div>";

  // Schreiben der select-box mit child-div in das Fromular
  if(is_new){
    if(as_text){
      // weitere rekursiv erzeugte Select-Boxen als Text zurueckliefern
      as_text = sel_box + child_div;
      return as_text;
    }else{
      // diese Select-Box ersetzen bzw. ueberschreiben
      new Insertion.Bottom(previous_div_name, sel_box + child_div);
    }
  }else{
    // nur Child-Select-Boxen ersetzen
    $("div_" + sel_box_name).replace(child_div);
  }
}



/*
 * Clientseitige Funktionalität zum Drucken eines Blogartikels aus dem Highslide
 */
function printBlogArticle(element) {
  var tag_id = $(element).up().next().down().down().getAttribute('id');
  var page = "/blogs/print/" + tag_id.match(/\d+$/);

  window.open(page, 'print_blog', 'height=400,width=700,scrollbars,resizable,toolbar');
}



/*
 * Clientseitige Funktionalität für die Highslides
 */
function isCommentFormValid(element, stdtext) {
  text = $F(element).strip();

  if (text.length == 0)  {
    alert(error_form_text_empty);
    $(element).focus();
    return false;
  }
  if (stdtext.length > 0) {
    if (text.indexOf(stdtext) >- 1) {
      alert(error_form_text_empty);
      $(element).focus();
      return false;
    }
  }

  $(element).value = text;

  return true;
}

function isTaggingFormValid(element) {
  text = $F(element).strip();

  if (text.length == 0) {
    alert(error_form_tags_empty);
    $(element).focus();
    return false;
  }

  $(element).value = text

  return true;
}

function isMessageFormValid(elementReceipient, elementSubject, elementBody) {
  receipient = $F(elementReceipient).strip();

  if (receipient.length == 0) {
    alert(error_form_receipient_empty);
    $(elementReceipient).focus();
    return false;
  }

  subject = $F(elementSubject).strip();

  if (subject.length == 0) {
    alert(error_form_subject_empty);
    $(elementSubject).focus();
    return false;
  }

  body = $F(elementBody).strip();

  if (body.length == 0) {
    alert(error_form_body_empty);
    $(elementBody).focus();
    return false;
  }

  $(elementReceipient).value = receipient;
  $(elementSubject).value = subject;
  $(elementBody).value = body;

  return true;
}


// cosmo: shows the controlbar in picture highslides
hs.registerOverlay({ thumbnailId: null, overlayId: 'controlbar', position: 'top right', hideOnMouseOut: true});
hs.registerOverlay({ thumbnailId: null, overlayId: 'controlbar2', position: 'middle left', width:'100%', hideOnMouseOut: true });
hs.graphicsDir = '/javascripts/highslide/graphics/';

hs.cacheAjax = false;
hs.preserveContent = false;
hs.lang = {
  loadingText:     'Bitte warten...',
  loadingTitle:    'Klick zum Abbrechen',
  focusTitle:      'Hier klicken, um das Bild in den Vordergrund zu bringen',
  fullExpandTitle: 'Hier klicken, um das Bild in Originalgröße zu sehen',
  fullExpandText:  'Vollbild',
  previousText:    'Voriges',
  previousTitle:   'Voriges (Pfeiltaste links)',
  nextText:        'Nächstes',
  nextTitle:       'Nächstes (Pfeiltaste rechts)',
  moveTitle:       'Verschieben',
  moveText:        'Verschieben',
  closeText:       'Schließen',
  closeTitle:      'Schließen (Esc)',
  resizeTitle:     'Größe wiederherstellen',
  playText:        'Abspielen',
  playTitle:       'Slideshow abspielen (Leertaste)',
  pauseText:       'Pause',
  pauseTitle:      'Pausiere Slideshow (Leertaste)',
  number:          'Bild %1 von %2',
  restoreTitle:    'Klicken um das Bild zu schließen. Maustaste gedrückt halten und ziehen, um das Bild zu verschieben. Pfeiltasten benutzen, um vor- oder zurückzublättern.'
};


var hsHts = new Array();

toggleHighslideAdditionals = function(ob, div_id, div_location, depth) {
  if (Element.next(div_location, 'div.' + div_id)) {
    var hb = Element.next(div_location, 'div.' + div_id);
    var cht = ob.up(depth + 4).previous('table').down('tr').next('tr').down('td').next('td').getHeight();
    var tds = ob.up(depth + 4).previous('table').down('tr').next('tr').immediateDescendants();
    if (hb.style.display == "none") {
      var ht = hb.getHeight() + 10;
      hsHts[ob.up(depth + 1).getAttribute('id')] = ht;
      var tht = (cht + ht) + "px";
      tds.each(function(s, i) {
        s.style.height = tht;
      });
      ob.up(depth + 3).style.height = (ob.up(depth + 3).getHeight() + ht) + "px";
      ob.up(depth).style.height = (ob.up(depth).getHeight() + ht) + "px";
      hb.style.display = "block";
    } else {
      hb.style.display = "none";
      var ht = hsHts[ob.up(depth + 1).getAttribute('id')];
      var tht = (cht - ht) + "px";
      tds.each(function(s, i) {
        s.style.height = tht;
      });
      ob.up(depth + 3).style.height = (ob.up(depth + 3).getHeight() - ht) + "px";
      ob.up(depth).style.height = (ob.up(depth).getHeight() - ht) + "px";
    }
  }
}


function displayNegativeRaterHighslide(ownerElement) {
  if (!$(ownerElement + '_rate_negative')) {
    var a = new Element('a', { 'id': ownerElement + '_rate_negative',  href: '/content/rate_negative_msg' });
    Element.insert($(ownerElement), a);
  }

  hs.htmlExpand($(ownerElement + '_rate_negative'), { elementClassName: 'highslide_html highslide_warning', contentId: 'highslideContainer', objectType: 'ajax', cacheAjax: false });
}

function getNewCheckcode(source) {
  $('checkcode_img_'+source).src = '/registration/captcha/' + (new Date()).getTime();
  return false;
}


// Zeichen in Textarea begrenzen
function validateTextLength(pid, commentable_type, commentable_id, rightContent, textLegthLimit){
    var form_id = pid + "_comments_create_" + commentable_type + "_" + commentable_id;
    var textarea_id = form_id + "_value";
    var textToValidate = $(rightContent + pid + "_comments_create_" + commentable_type + "_" + commentable_id + "_value").value;

    if (textToValidate.length >= textLegthLimit){
      alert('Die Eingabe hat eine Länge von ' + textLegthLimit + ' Zeichen erreicht!');
      $(rightContent + pid + "_comments_create_" + commentable_type + "_" + commentable_id + "_value").value = textToValidate.substring(0,299)
      return false;
    }
  }


function checkShoutBoxDefault(field,stdText){
  if(($(field).value).indexOf(stdText)>-1){
     $(field).value='';
  }
}

function expandLayer(theId) {
  //new Ajax.Updater('', '/help/increment_number_of_asks/1', {asynchronous:true, evalScripts:true});
  var myDropDownId = theId + "Detail";
  var myToggleClasses = ['','up'];
  Effect.toggle(myDropDownId, 'slide',
          { duration: 0.25,
            afterFinish: function() {
              toggleClassNames(theId,
              [myToggleClasses[0], myToggleClasses[1]], myDropDownId);
            } //afterFinish
          }
        ); //Effect.toggle
}

function toggleClassNames(theClassId, theClassArray, theDropDownId) {
  var myLink = $(theClassId);
  var myClassNumber = Element.visible($(theDropDownId)) ? 1 : 0;
  myLink.className = theClassArray[myClassNumber];
}


Relationships = {
};

Relationships.toggleAdditionals = function(option, target_id) {
  if (option == 'fr_a') {
    $('relationship_text_and_subscription_holder_' + target_id).show();
  }
  else {
    $('relationship_text_and_subscription_holder_' + target_id).hide();
  }

  if (option == 'ig_a') {
    $('relationship_note_holder_' + target_id).show();
  }
  else {
    $('relationship_note_holder_' + target_id).hide();
  }
};


Relationships.displayContentSubscriptionHighslide = function(target) {
  $('subscription_link').href = target
  hs.htmlExpand($('subscription_link'), { elementClassName: 'highslide_user highslide_abo', contentId: 'highslideContainer', objectType: 'ajax', cacheAjax: false })
}

Relationships.pmReplyAndContentSubscriptionHighslide = function(target) {
  $('pm_reply_and_content_subscription_link').href = target
  hs.htmlExpand($('pm_reply_and_content_subscription_link'), { elementClassName: 'highslide_user highslide_abo', contentId: 'highslideContainer', objectType: 'ajax', cacheAjax: false })
}


function fisheye(el, zoom, f) {
  var fct;

  f ? fct = f : fct = 400;

  if (!el.origW) {
    var orig_dims = Element.getDimensions(el);
    el.origW = orig_dims.width;
    el.origH = orig_dims.height;
  }

  if (zoom) {
    el.imgEffect = new Effect.Scale(el, fct, { duration: 0.3 });
  }
  else {
    if (el.imgEffect) {
      el.imgEffect.cancel();
    }

    el.currW = Element.getWidth(el);
    new Effect.Scale(el, el.origW / el.currW * 100, { duration: 0.2 });
  }
}

function delete_motion_detector_message(id) {
  new Ajax.Request("/profile/delete_motion_detector_message", {
    method: 'post',
    parameters: { id: id, authenticity_token: encodeURIComponent(authenticityToken) }
  });
}

var marked_motion_detector_messages_as_seen = false;
var marked_motion_detector_messages_as_seen_request_sending = false;

function mark_motion_detector_messages_as_seen() {
  if ((marked_motion_detector_messages_as_seen == false) && (marked_motion_detector_messages_as_seen_request_sending == false) ) {
    marked_motion_detector_messages_as_seen_request_sending = true;
    $('motion_detector_new_symbol').className = "";

    new Ajax.Request("/profile/mark_motion_detector_messages_as_seen", {
      method: 'post',
      parameters: { authenticity_token: encodeURIComponent(authenticityToken) },
      onSuccess: function(transport) {
        marked_motion_detector_messages_as_seen = true;
      },
      onComplete: function(transport) {
        marked_motion_detector_messages_as_seen_request_sending = false;
      }
    });
  }
}

function observeTextareaWithMaxLengthValidation(textarea) {
  textarea = $(textarea);
  
  if (!textarea.hasClassName('observing_max_length') && $w(textarea.className).find(function(className) { return /^max_length_([1-9]\d*)$/.test(className); })) {
    textarea.addClassName('observing_max_length');
    
    var maxLength = parseInt(RegExp.$1);
    var disposalMessage = 'Es stehen ' + maxLength + ' Zeichen zur Verfügung.';
    var reachedMaxMessage = 'Die Eingabe hat die maximal gültige Länge von ' + maxLength + ' Zeichen überschritten.';

    if (!textarea.present()) {
      textarea.value = disposalMessage;
      textarea.store('disposalValue', disposalMessage);

      textarea.observe('focus', function() {
        if (textarea.value.strip() == disposalMessage) {
          textarea.clear();
        }
      });

      textarea.observe('blur', function() {
        if (!textarea.present()) {
          textarea.value = disposalMessage;
        }
      });

      $(textarea.form).observe('submit', function() {
        if (textarea.value.strip() == disposalMessage) {
          textarea.clear();
        }
      });
    }

    if (Prototype.Browser.IE || Prototype.Browser.WebKit) {
      textarea.observe('paste', function() {
        if (textarea.value.length > maxLength) {
          alert(reachedMaxMessage);
          textarea.value = textarea.value.substring(0, maxLength);
          return false;
        }
      });
      
      textarea.observe('keyup', function() {
        if (textarea.value.length > maxLength) {
          alert(reachedMaxMessage);
          textarea.value = textarea.value.substring(0, maxLength);
          return false;
        }
      });
    } 
    else {
      textarea.observe('input', function() {
        if (textarea.value.length > maxLength) {
          alert(reachedMaxMessage);
          textarea.value = textarea.value.substring(0, maxLength);
          return false;
        }
      });
    }
  }
}

function observeTextareasWithMaxLengthValidation() {
  $$('textarea.validate_max_length').each(function(textarea) {
    observeTextareaWithMaxLengthValidation(textarea);
  });
}

document.observe('dom:loaded', function() {
  observeTextareasWithMaxLengthValidation();
});


function toggleFormTabs(ftab,ob){
        if(Element.up(ob,'ul')){
                Element.select(Element.up(ob,'ul'),'li').each(function(l){
                        Element.removeClassName(l,'live_form_tab');
                });
                Element.up(ob,'li').addClassName('live_form_tab');

        }
        var fWrap = Element.up(ob,'form')?Element.up(ob,'form'):$('wrapper_main_content');
        Element.select(fWrap,('div.tab_form')).each(function(r){
                Element.addClassName($(r),'hidden_form_tab');
        });
        Element.removeClassName(ftab,'hidden_form_tab');
}

function campaign_check_visibility(campaigns, content_type) {
  var campaign_array = campaigns.split(',');
  for (var i=0; i < campaign_array.length; i++) {
    var campaign = campaign_array[i].strip();
    if (!$(campaign + '_add_' + content_type)) {
      continue;
    }

    assigned_to_gallery = (content_type == 'picture') ? ($(content_type + '_assign_to_gallery').value != '') : false;
    visible_for_all = !($(content_type + '_only_visible_to_friends').checked || $(content_type + '_only_visible_to_members').checked || assigned_to_gallery);

    $(campaign + '_add_' + content_type).disabled = !visible_for_all;

    if ($(campaign + '_add_' + content_type).checked) {
      $(campaign + '_add_' + content_type).checked = visible_for_all;
    }
  }
}

function previewSetup(form, path) {
  if ($('preview_hsl'))
    closeHighslide('preview_hsl');
  if (window.tinymce)
    tinyMCE.triggerSave();
  new Ajax.Request(path, {
    asynchronous: true, evalScripts: true, parameters: Form.serialize(form)
  });
};

function previewShow(content_preview, element_id, element_class_name, content_id) {
  hs.htmlExpand($(element_id), {
                elementClassName: element_class_name,
                contentId:        content_id,
                maincontentText:  content_preview
  })
};


/* MacStyleDock.js - a function for creating a Mac-OSX-style 'dock'
 *
 * The author of this program, Safalra (Stephen Morley), irrevocably releases
 * all rights to this program, with the intention of it becoming part of the
 * public domain. Because this program is released into the public domain, it
 * comes with no warranty either expressed or implied, to the extent permitted
 * by law.
 *
 * For more public domain JavaScript code by the same author, visit:
 * http://www.safalra.com/programming/javascript/
 */


/* Creates a MacStyleDock. A MacStyleDock is a row of images that expand as the
 * mouse pointer moves over them. The images are created as children of the
 * specified node with the specified minimum and maximum sizes. Two other
 * parameters specify the images to be used and the 'range' of expansion. The
 * parameters are:
 *
 * node         - the node at which to create the Mac-style 'dock'
 * imageDetails - an array each of whose elements are object with three
 *                properties:
 *                - name      - the basename of the image
 *                - sizes     - an array of pizel sizes available
 *                - extension - the image extension
 *                - onclick   - the function to call when the image is clicked
 *                Requested file names consist of the concatenation of the name
 *                property, one of the values of the size property, and the
 *                extension property.
 * minimumSize  - the minimum size of icons in the 'dock'
 * maximumSize  - the maximum size of icons in the 'dock'
 * range        - the range of expansion, in icons. This need not be an integer.
 */
function MacStyleDock(node, imageDetails, minimumSize, maximumSize, range, colWidth){

  // Preload images
  var images = new Array();
  for (var i = 0; i < imageDetails.length; i++){
    for (var j = 0; j < imageDetails[i].sizes.length; j++){
      var image = new Image(imageDetails[i].sizes[j],imageDetails[i].sizes[j]);
      image.src = imageDetails[i].name;
      images.push(image);
    }
  }

  // Create the toolbar
  var nodeMargin = 0;
  var nodeMarginSteps = 10;
  var scale         = 0;
  var closeTimeout  = null;
  var closeInterval = null;
  var openInterval  = null;
  var imageNodes    = new Array(imageDetails.length);
  var imageSizes    = new Array(imageDetails.length);
  node.style.textAlign = 'center';
  node.style.height    = maximumSize + 'px';
  node.style.zIndex = '500';
  var nodeWidth = colWidth;
  node.style.width = colWidth+"px";
  //node.style.backgroundColor = "red";
  for (var i = 0; i < imageDetails.length; i++){
    imageNodes[i] = document.createElement('img');
    imageSizes[i] = minimumSize;
    imageNodes[i].style.position = 'relative';
    imageNodes[i].style.zIndex = '500';
    setImageProperties(i);
    node.appendChild(imageNodes[i]);
    if (imageNodes[i].addEventListener){
      imageNodes[i].addEventListener('mousemove', processMouseMove, false); 
      imageNodes[i].addEventListener('mouseout', processMouseOut, false);
      imageNodes[i].addEventListener('click', imageDetails[i].onclick, false);
    }else if (imageNodes[i].attachEvent){
      imageNodes[i].attachEvent('onmousemove', processMouseMove);
      imageNodes[i].attachEvent('onmouseout', processMouseOut);
      imageNodes[i].attachEvent('onclick', imageDetails[i].onclick);
    }
    imageNodes[i].setAttribute('alt', imageDetails[i].title);
  }

  /* Sets a toolbar image to the specified size. The parameters are:
   *
   * index - the 0-based index of the image to be sized
   */
  function setImageProperties(index){
    var imageNode = imageNodes[index];
    var details   = imageDetails[index];
    var size = minimumSize + scale * (imageSizes[index] - minimumSize);
    var sizeIndex = -1;
    do{
      sizeIndex++;
    }while (sizeIndex < details.sizes.length
        &&  details.sizes[sizeIndex] < size)
    if (sizeIndex >= details.sizes.length) sizeIndex--;
    imageNode.setAttribute('src',details.name);
    //imageNode.setAttribute('width',  size);
    imageNode.setAttribute('height', size);
     node.style.marginLeft= (nodeMargin > 0 ? 0 : nodeMargin) +"px";

     node.style.width= ((nodeWidth-2*nodeMargin) < colWidth ? colWidth : (nodeWidth-2*nodeMargin))+"px";
    //imageNode.style.marginTop = (maximumSize - size) + 'px';
    
  }

  /* Processes a mousemove event on an image in the 'dock'. The parameters are:
   *
   * e - the mousemove event. window.event will be used if this is undefined.
   */
   function processMouseMove(e){
    if (!e) e = window.event;
    var target = e.target || e.srcElement;
    var index = 0;
    window.clearTimeout(closeTimeout);
    closeTimeout = null;
    window.clearInterval(closeInterval);
    closeInterval = null;
    if (scale != 1 && !openInterval){
      openInterval = window.setInterval(
          function(){
            if (scale < 1) scale += 0.125;
            nodeMargin -= nodeMarginSteps;
            if (scale >= 1){
              scale = 1;
              window.clearInterval(openInterval);
              openInterval = null;
            }
            for (var i = 0; i < imageNodes.length; i++){
              setImageProperties(i);
	      imageNodes[i].title=imageDetails[i].title;
            }
          },
          20);
    }
    while (imageNodes[index] != target) index++;
    var across = (e.layerX || e.offsetX) / imageSizes[index];
    if (across){
      for (var i = 0; i < imageSizes.length; i++){
        if ((i < index - range) || (i > index + range)){
          imageSizes[i] = minimumSize;
        }else{
          imageSizes[i] = minimumSize
                        + Math.ceil((maximumSize - minimumSize)
                            * (Math.cos(i - index - across + 0.5) + 1) / 2);
        }
        setImageProperties(i);
      }
    }
  }

  // Processes a mouseout event on an image in the 'dock'.
  function processMouseOut(){
    if (!closeTimeout && !closeInterval){
      closeTimeout = window.setTimeout(
          function(){
            closeTimeout = null;
            if (openInterval){
              window.clearInterval(openInterval);
              openInterval = null;
            }
            closeInterval = window.setInterval(
                function(){
                  if (scale > 0) scale -= 0.125;
                  nodeMargin += nodeMarginSteps;
                  if (scale <= 0){
                    scale = 0;
                    window.clearInterval(closeInterval);
                    closeInterval = null;
                  }
                  for (var i = 0; i < imageNodes.length; i++){
                    setImageProperties(i);
                  }
                },
                20);
          },
          100);
    }
  }

}


// error-strings
// step 1
var str_error_username = "";
var str_error_sex = "";
var str_error_birthday = "";
var str_error_email = "";
var str_error_email_confirm = "";
var str_error_mobile = "";
var str_error_zipcode = "";
var str_error_city = "";
var str_error_ssopassword = "";
var str_error_ssopassword_confirm = "";
var str_error_user_agreement = "";
var str_error_checkcode = "";
// step 2
var str_error_first_name = "";
var str_error_last_name = "";
var str_error_phone = "";
var str_error_signature = "";
var str_error_website = "";
// step 3
var str_error_hair_color = "";

// advice-strings
// step 1
var str_advice_username = "";
var str_advice_sex = "";
var str_advice_birthday = "";
var str_advice_email = "";
var str_advice_email_confirm = "";
var str_advice_mobile = "";
var str_advice_zipcode = "";
var str_advice_city = "";
var str_advice_ssopassword = "";
var str_advice_ssopassword_confirm = "";
var str_advice_user_agreement = "";
var str_advice_checkcode = "";
// step 2
var str_advice_first_name = "";
var str_advice_last_name = "";
var str_advice_phone = "";
var str_advice_signature = "";
var str_advice_website = "";
// step 3
var str_advice_hair_color = "";


function clearAllErrorMsgs()
{
  // step 1
  str_error_username = "";
  str_error_sex = "";
  str_error_birthday = "";
  str_error_email = "";
  str_error_email_confirm = "";
  str_error_mobile = "";
  str_error_zipcode = "";
  str_error_city = "";
  str_error_ssopassword = "";
  str_error_ssopassword_confirm = "";
  str_error_user_agreement = "";
  str_error_checkcode = "";
  //step 2
  str_error_first_name = "";
  str_error_last_name = "";
  str_error_phone = "";
  str_error_signature = "";
  str_error_website = "";
  // step 3
  str_error_hair_color = "";

  // step 1
  str_advice_username = "";
  str_advice_sex = "";
  str_advice_birthday = "";
  str_advice_email = "";
  str_advice_email_confirm = "";
  str_advice_mobile = "";
  str_advice_zipcode = "";
  str_advice_city = "";
  str_advice_ssopassword = "";
  str_advice_ssopassword_confirm = "";
  str_advice_user_agreement = "";
  str_advice_checkcode = "";
  // step 2
  str_advice_first_name = "";
  str_advice_last_name = "";
  str_advice_phone = "";
  str_advice_signature = "";
  str_advice_website = "";
  // step 3
  str_advice_hair_color = "";
}

function addError( input, error_msg, advice_msg ) {
  $( 'field_' + input ).addClassName( 'form_error' );
  $( 'field_error_' + input ).innerHTML = error_msg;
  $( 'field_error_' + input ).removeClassName( 'hide' );
  if (advice_msg.length > 0)
  {
    $( 'field_advice_' + input ).innerHTML = advice_msg;
    $( 'field_advice_' + input ).removeClassName( 'hide' );
  }
}

function removeError( input ) {
  $( 'field_' + input ).removeClassName( 'form_error' );
  $( 'field_error_' + input ).innerHTML = "";
  $( 'field_error_' + input ).addClassName('hide');
  $( 'field_advice_' + input ).innerHTML = "";
  $( 'field_advice_' + input ).addClassName('hide');
}

function daysInFebruary(year) {
  // February has 29 days in any year evenly divisible by four,
  // EXCEPT for centurial years which are not also divisible by 400.
  return (((year % 4 == 0) && ((!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28);
}

function isDate(year, month, day){
  var daysInMonth = [31, daysInFebruary(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

  return day <= daysInMonth[month - 1];
}

function isStep1Valid() {
  clearAllErrorMsgs();

  var all_correct = true;
  var error = false;

  var first_error = "";
  var erroneous = new Array();

  // check for birthday-errors
  error = false;
  birthday_day = $('birthday_day');
  birthday_month = $('birthday_month');
  birthday_year = $('birthday_year');
  
  if (birthday_day.selectedIndex == 0) {
    str_error_birthday = error_birthday_choose_day;
    str_advice_birthday = advice_birthday_choose_day;
    error = true;
  }
  if (birthday_month.selectedIndex == 0) {
    str_error_birthday = (!error) ? error_birthday_choose_month : str_error_birthday + '<br/>' + error_birthday_choose_month;
    str_advice_birthday = (!error) ? advice_birthday_choose_month : str_advice_birthday + '<br/>' + advice_birthday_choose_month;
    error = true;
  }
  if (birthday_year.selectedIndex == 0) {
    str_error_birthday = (!error) ? error_birthday_choose_year : str_error_birthday + '<br/>' + error_birthday_choose_year;
    str_advice_birthday = (!error) ? advice_birthday_choose_year : str_advice_birthday + '<br/>' + advice_birthday_choose_year;
    error = true;
  }

  year = parseInt(birthday_year.options[birthday_year.selectedIndex].value);
  month = parseInt(birthday_month.options[birthday_month.selectedIndex].value);
  day = parseInt(birthday_day.options[birthday_day.selectedIndex].value);

  if (!isDate(year, month, day)) {
    str_error_birthday = error_birthday_invalid + '<br/>' + str_error_birthday;
    str_advice_birthday = advice_birthday_invalid + '<br/>' + str_advice_birthday;
    error = true;
  }
  if (error)
  {
    addError( 'birthday', str_error_birthday, str_advice_birthday );
    all_correct = false;
    if (first_error.length == 0) { first_error = "birthday"; }
    erroneous.push( 'birthday' );
  }
  else { removeError( 'birthday' ); }

   // check for email-errors
  error = false;
  email = $F('email').strip();
  if (email.length == 0) {
    str_error_email = error_email_empty;
    str_advice_email = advice_email_empty;
    error = true;
  }
  else
  {
    if (email.length > 250) {
      str_error_email = error_email_maxlength;
      str_advice_email = advice_email_maxlength;
      error = true;
    }
    if (!email.match(/^[a-zA-Z_0-9\-\.]+@[a-zA-Z_0-9\.\-]+\.[a-zA-Z]{2,5}$/)) {
      str_error_email = !error ? error_email_invalid : str_error_email + '<br/>' + error_email_invalid;
      str_advice_email = !error ? advice_email_invalid : str_advice_email + '<br/>' + advice_email_invalid;
      error = true;
    }
  }
  if (error)
  {
    addError( 'email', str_error_email, str_advice_email );
    all_correct = false;
    if (first_error.length == 0) { first_error = "email"; }
    erroneous.push( 'email' );
  }
  else { removeError( 'email' ); }

  // check for mobile-errors
  error = false;
  mobile = $F('mobile').strip();
  // Sinnloszeichen rauswerfen
  mobile = mobile.replace( /\//g , "" );
  mobile = mobile.replace( /\\/g , "" );
  mobile = mobile.replace( /\(/g , "" );
  mobile = mobile.replace( /\)/g , "" );
  mobile = mobile.replace( /-/g  , "" );
  mobile = mobile.replace( / /g  , "" );
  mobile = mobile.replace( /\[/g , "" );
  mobile = mobile.replace( /\]/g , "" );
  // Anfangs 0 in +49 verwandeln
  mobile = mobile.replace( /^0/g , "+49" );

  if (mobile.length > 20) {
    str_error_mobile = error_mobile_maxlength;
    str_advice_mobile = advice_mobile_maxlength;
    error = true;
  }
  if (mobile.length > 0 && !mobile.match(/^\+49[0-9\+\/]{0,13}$/)) {  
    str_error_mobile = (!error) ? error_mobile_invalid : str_error_mobile + '<br/>' + error_mobile_invalid;
    str_advice_mobile = (!error) ? advice_mobile_invalid : str_advice_mobile + '<br/>' + advice_mobile_invalid;
    error = true;
  }
  if (error)
  {
    addError( 'mobile', str_error_mobile, str_advice_mobile );
    all_correct = false;
    if (first_error.length == 0) { first_error = "mobile"; }
    erroneous.push( 'mobile' );
  }
  else { removeError( 'mobile' ); }


  // check for address-errors
  error = false;
  address = $F('address').strip();
  if (address.length > 250) {
    str_error_address = error_address_maxlength;
    str_advice_address = advice_address_maxlength;
    error = true;
  }
  if (address.length > 0 && !address.match(/^[a-zA-Z0-9ÄÖÜäöüß: _\.\-\,]+$/)) {
    str_error_address = (!error)? error_address_invalid : str_error_address + "<br/>" + error_address_invalid;
    str_advice_address = (!error)? advice_address_invalid : str_advice_address + "<br/>" + advice_address_invalid;
    error = true;
  }
  if (error)
  {
    addError( 'address', str_error_address, str_advice_address );
    all_correct = false;
    if (first_error.length == 0) { first_error = "address"; }
    erroneous.push( 'address' );
  }
  else { removeError( 'address' ); }

  // check for zipcode-errors
  error = false;
  zipcode = $F('zipcode').strip();
  country = $F('country').strip();
  if (zipcode.length == 0) {
    str_error_zipcode = error_zipcode_empty;
    str_advice_zipcode = advice_zipcode_empty;
    error = true;
  }
  else
  {
    if ( !zipcode.match(/^[0-9]{5}$/) && country=="Deutschland") {
      str_error_zipcode = error_zipcode_invalid;
      str_advice_zipcode = advice_zipcode_invalid;
      error = true;
    }
  }
  if (error)
  {
    addError( 'zipcode', str_error_zipcode, str_advice_zipcode );
    all_correct = false;
    if (first_error.length == 0) { first_error = "zipcode"; }
    erroneous.push( 'zipcode' );
  }
  else { removeError( 'zipcode' ); }

  // check for city-errors
  error = false;
  city = $F('city');
  if (city.length > 250) {
    str_error_city = error_city_maxlength;
    str_advice_city = advice_city_maxlength;
    error = true;
  }
  if (city.length > 0 && !city.match(/^[a-zA-ZäöüÄÖÜß \-\(\)\/\.]+$/)) {
    str_error_city = !error ? error_city_invalid : str_error_city + '<br/>' + error_city_invalid;
    str_advice_city = !error ? advice_city_invalid : str_advice_city + '<br/>' + advice_city_invalid;
    error = true;
  }
  if (error)
  {
    addError( 'city', str_error_city, str_advice_city );
    all_correct = false;
    if (first_error.length == 0) { first_error = "city"; }
    erroneous.push( 'city' );
  }
  else { removeError( 'city' ); }

  // check for password-errors
  error = false;
  password = $F('ssopassword');
  if (password.length > 0) {
    if (password.length < 4) {
      str_error_ssopassword = error_password_minlength;
      str_advice_ssopassword = advice_password_minlength;
      error = true;
    }

    if (password.length > 30) {
      str_error_ssopassword = error_password_maxlength;
      str_advice_ssopassword = advice_password_maxlength;
      error = true;
    }
  }
  if (error)
  {
    addError( 'ssopassword', str_error_ssopassword, str_advice_ssopassword );
    all_correct = false;
    if (first_error.length == 0) { first_error = "ssopassword"; }
    erroneous.push( 'ssopassword' );
  }
  else { removeError( 'ssopassword' ); }

  // check for password-confirm-errors
  error = false;
  password_confirm = $F('password_confirm');
  if (password != password_confirm) {
    str_error_ssopassword_confirm = error_password_confirm_no_match;
    str_advice_ssopassword_confirm = advice_password_confirm_no_match;
    error = true;
  }
  if (error)
  {
    addError( 'password_confirm', str_error_ssopassword_confirm, str_advice_ssopassword_confirm );
    all_correct = false;
    if (first_error.length == 0) { first_error = "password_confirm"; }
    erroneous.push( 'password_confirm' );
  }
  else { removeError( 'password_confirm' ); }

  $('email').value = email;
  $('mobile').value = mobile;
  $('address').value = address;
  $('zipcode').value = zipcode;
  $('city').value = city;

  return all_correct;
}

function isStep2Valid() {
  clearAllErrorMsgs();

  var all_correct = true;
  var error = false;

  var first_error = "";
  var erroneous = new Array();

  // check for first-name-errors
  first_name = $F('first_name').strip();
  if (first_name.length > 0) {
    if (first_name.length > 250) {
      str_error_first_name = error_first_name_maxlength;
      str_advice_first_name = advice_first_name_maxlength;
      error = true;
    }
    if (!first_name.match(/^[a-zA-Z ÄÖÜäöüß-]+$/)) {
      str_error_first_name = (!error) ? error_first_name_invalid : str_error_first_name + '<br/>' + error_first_name_invalid;
      str_advice_first_name = (!error) ? advice_first_name_invalid : str_advice_first_name + '<br/>' + advice_first_name_invalid;
      error = true;
    }
  }
  if (error)
  {
    addError( 'first_name', str_error_first_name, str_advice_first_name );
    all_correct = false;
    first_error = 'first_name'
    erroneous.push( 'first_name' );
  }
  else { removeError( 'first_name' ); }

  // check for last-name-errors
  error = false;
  last_name = $F('last_name').strip();
  if (last_name.length > 0) {
    if (last_name.length > 250) {
      str_error_first_name = error_last_name_maxlength;
      str_advice_first_name = advice_last_name_maxlength;
      error = true;
    }
    if (!last_name.match(/^[a-zA-Z ÄÖÜäöüß-]+$/)) {
      str_error_first_name = (!error) ? error_last_name_invalid : str_error_first_name + '<br/>' + error_last_name_invalid;
      str_advice_first_name = (!error) ? advice_last_name_invalid : str_advice_first_name + '<br/>' + advice_last_name_invalid;
      error = true;
    }
  }
  if (error)
  {
    addError( 'last_name', str_error_first_name, str_advice_first_name );
    all_correct = false;
    if (first_error.length == 0) { first_error = "last_name"; }
    erroneous.push( 'last_name' );
  }
  else { removeError( 'last_name' ); }


  // check for phone-errors
  error = false;
  phone = $F('phone').strip();

  // remove senseless signs
  phone = phone.replace( /\//g , "" );
  phone = phone.replace( /\\/g , "" );
  phone = phone.replace( /\(/g , "" );
  phone = phone.replace( /\)/g , "" );
  phone = phone.replace( /-/g  , "" );
  phone = phone.replace( / /g  , "" );
  phone = phone.replace( /\[/g , "" );
  phone = phone.replace( /\]/g , "" );
  // format start
  phone = phone.replace( /^0049/g , "+49" );
  phone = phone.replace( /^049/g ,  "+49" );
  phone = phone.replace( /^49/g ,   "+49" );

  if (phone.length > 0) {
    if (phone.length > 20) {
      str_error_phone = error_phone_maxlength;
      str_advice_phone = advice_phone_maxlength;
      error = true;
    }
    if (!phone.match(/^\+4[1|3|9][1-9][0-9]{0,14}$/)) {
      str_error_phone = (!error) ? error_phone_invalid : str_error_phone + '<br/>' + error_phone_invalid;
      str_advice_phone = (!error) ? advice_phone_invalid : str_advice_phone + '<br/>' + advice_phone_invalid;
      error = true;
    }
  }
  if (error)
  {
    addError( 'phone', str_error_phone, str_advice_phone );
    all_correct = false;
    if (first_error.length == 0) { first_error = "phone"; }
    erroneous.push( 'phone' );
  }
  else { removeError( 'phone' ); }

  if ($('signature')) {
    signature = $F('signature').strip();
  }

  // check for website-errors
  error = false;
  website = $F('website').strip();
  if (website.length > 0 && website != 'http://') {
    if (website.length > 250) {
      str_error_website = error_website_maxlength;
      str_advice_website = advice_website_maxlength;
      error = true;
    }

    if (!website.match(/^http:\/\//)) {
      str_error_website = (!error) ? error_website_invalid : str_error_website + '<br/>' + error_website_invalid;
      str_advice_website = (!error) ? advice_website_invalid : str_advice_website + '<br/>' + advice_website_invalid;
      error = true;
    }
  }
  if (error)
  {
    addError( 'website', str_error_website, str_advice_website );
    all_correct = false;
    if (first_error.length == 0) { first_error = "website"; }
    erroneous.push( 'website' );
  }
  else { removeError( 'website' ); }

  if ( !all_correct ) {
    Effect.ScrollTo( 'field_' + first_error, {duration: 0.5} );
  }

  $('first_name').value = first_name;
  $('last_name').value = last_name;
  $('phone').value = phone;
  if ($('signature')) {
    $('signature').value = signature;
  }
  $('website').value = (website == 'http://') ? '' : website;

  $$('textarea.validate_max_length').each(function(textarea) {
    /\bmax_length_([1-9]\d*)\b/.test(textarea.className);
    if (textarea.value.strip() == 'Es stehen ' + parseInt(RegExp.$1) +
                                  ' Zeichen zur Verfügung.') {
      textarea.clear();
    }
  });

  return all_correct;
}

function isStep3Valid() {
  //if ($('motivation_other').checked) {
  //  if ($F('motivation_other').strip().length == 0) {
  //    alert('Bitte gib eine andere Aktivität ein, für die du jemanden suchst.');
  //    $('motivation_other').focus();
  //    return false;
  //  }
  //}
  clearAllErrorMsgs();

  var all_correct = true;
  var error = false;

  var first_error = "";
  var erroneous = new Array();


  // check for hair-color-other-error
  if ($('hair_color')){
    if ($('hair_color').options[$('hair_color').selectedIndex].value == 'andere') {
      if ($F('hair_color_other').strip().length == 0) {
        str_error_hair_color = error_hair_color_missing;
        str_advice_hair_color = advice_hair_color_missing;
        error = true;
      }
    }
    if (error)
    {
      addError( 'hair_color_other', str_error_hair_color, str_advice_hair_color );
      all_correct = false;
      first_error = 'hair_color_other'
      erroneous.push( 'hair_color_other' );
    }
    else { removeError( 'hair_color_other' ); }
  
    if ( !all_correct ) {
      Effect.ScrollTo( 'field_' + first_error, {duration: 0.5} );
    }
  }

  $('self_description').value = $F('self_description').strip();
  if ($('motivation_other')) {
    $('motivation_other').value = $F('motivation_other').strip();
  }
  if ($('hair_color_other')) {
    $('hair_color_other').value = $F('hair_color_other').strip();
  }

  if ($('music_lover_since')) {
    $('music_lover_since').value = $F('music_lover_since').strip();
  }
  if ($('last_books_read')) {
    $('last_books_read').value = $F('last_books_read').strip();
  }
  if ($('instruments_other')) {
    $('instruments_other').value = $F('instruments_other').strip();
  }

  $$('textarea.validate_max_length').each(function(textarea) {
    /\bmax_length_([1-9]\d*)\b/.test(textarea.className);
    if (textarea.value.strip() == 'Es stehen ' + parseInt(RegExp.$1) +
                                  ' Zeichen zur Verfügung.') {
      textarea.clear();
    }
  });

  return all_correct;
}

function isStep4Valid() {
  return true;
}

function saveAtStep1() {
  if (!isStep1Valid())
    return false;

  $('step').value = '5';
  $('alv_profile').submit();
  return true;
}

function saveAtStep2() {
  if (!isStep2Valid())
    return false;

  $('step').value = '5';
  $('alv_profile').submit();
  return true;
}

function saveAtStep3() {
  if (!isStep3Valid())
    return false;

  $('step').value = '5';
  $('alv_profile').submit();
  return true;
}

function saveAtStep4() {
  if (!isStep4Valid())
    return false;

  $('step').value = '5';
  $('alv_profile').submit();
  return true;
}

function saveStep1AndGotoStep2() {
  if (!isStep1Valid())
    return false;

  $('step').value = '2';
  $('alv_profile').submit();
  return true;
}

function saveStep1AndGotoStep3() {
  if (!isStep1Valid())
    return false;

  $('step').value = '3';
  $('alv_profile').submit();
  return true;
}

function saveStep1AndGotoStep4() {
  if (!isStep1Valid())
    return false;

  $('step').value = '4';
  $('alv_profile').submit();
  return true;
}

function saveStep2AndGotoStep1() {
  if (!isStep2Valid())
    return false;

  $('step').value = '1';
  $('alv_profile').submit();
  return true;
}

function saveStep2AndGotoStep3() {
  if (!isStep2Valid())
    return false;

  $('step').value = '3';
  $('alv_profile').submit();
  return true;
}

function saveStep2AndGotoStep4() {
  if (!isStep2Valid())
    return false;

  $('step').value = '4';
  $('alv_profile').submit();
  return true;
}

function saveStep3AndGotoStep1() {
  if (!isStep3Valid())
    return false;

  $('step').value = '1';
  $('alv_profile').submit();
  return true;
}

function saveStep3AndGotoStep2() {
  if (!isStep3Valid())
    return false;

  $('step').value = '2';
  $('alv_profile').submit();
  return true;
}

function saveStep3AndGotoStep4() {
  if (!isStep3Valid())
    return false;

  $('step').value = '4';
  $('alv_profile').submit();
  return true;
}

function saveStep4AndGotoStep1() {
  if (!isStep4Valid())
    return false;

  $('step').value = '1';
  $('alv_profile').submit();
  return true;
}

function saveStep4AndGotoStep2() {
  if (!isStep4Valid())
    return false;

  $('step').value = '2';
  $('alv_profile').submit();
  return true;
}

function saveStep4AndGotoStep3() {
  if (!isStep4Valid())
    return false;

  $('step').value = '3';
  $('alv_profile').submit();
  return true;
}

function addPicture() {
  file = $F('file').strip();

  if (file.length == 0) {
    alert(error_picture_empty);
    $('file').focus();
    return false;
  }

  title = $F('title').strip();

  if (title.length == 0) {
    alert(error_picture_title_empty);
    $('title').focus();
    return false;
  }

  tags = $F('tags').strip();

  if (tags.length == 0) {
    alert(error_picture_tags_empty);
    $('tags').focus();
    return false;
  }

  $('title').value = title;
  $('tags').value = tags;

  return true;
}

function editPicture() {
  title = $F('title').strip();

  if (title.length == 0) {
    alert(error_picture_title_empty);
    $('title').focus();
    return false;
  }

  $('title').value = title;

  return true;
}

function addAudio() {
  file = $F('file').strip();

  if (file.length == 0) {
    alert(error_audio_empty);
    $('file').focus();
    return false;
  }

  title = $F('title').strip();

  if (title.length == 0) {
    alert(error_audio_title_empty);
    $('title').focus();
    return false;
  }

  artist = $F('artist').strip();

  if (artist.length == 0) {
    alert(error_audio_artist_empty);
    $('artist').focus();
    return false;
  }

  tags = $F('tags').strip();

  if (tags.length == 0) {
    alert(error_audio_tags_empty);
    $('tags').focus();
    return false;
  }

  $('title').value = title;
  $('artist').value = artist;
  $('tags').value = tags;

  return true;
}

function editAudio() {
  title = $F('title').strip();

  if (title.length == 0) {
    alert(error_audio_title_empty);
    $('title').focus();
    return false;
  }

  artist = $F('artist').strip();

  if (artist.length == 0) {
    alert(error_audio_artist_empty);
    $('artist').focus();
    return false;
  }

  $('title').value = title;
  $('artist').value = artist;

  return true;
}

function addVideo() {
  file = $F('file').strip();

  if (file.length == 0) {
    alert(error_video_empty);
    $('file').focus();
    return false;
  }

  title = $F('title').strip();

  if (title.length == 0) {
    alert(error_video_title_empty);
    $('title').focus();
    return false;
  }

  artist = $F('artist').strip();

  if (artist.length == 0) {
    alert(error_video_artist_empty);
    $('artist').focus();
    return false;
  }

  tags = $F('tags').strip();

  if (tags.length == 0) {
    alert(error_video_tags_empty);
    $('tags').focus();
    return false;
  }

  $('title').value = title;
  $('artist').value = artist;
  $('tags').value = tags;

  return true;
}

function editVideo() {
  title = $F('title').strip();

  if (title.length == 0) {
    alert(error_video_title_empty);
    $('title').focus();
    return false;
  }

  artist = $F('artist').strip();

  if (artist.length == 0) {
    alert(error_video_artist_empty);
    $('artist').focus();
    return false;
  }

  $('title').value = title;
  $('artist').value = artist;

  return true;
}

function addBlogArticle() {
  title = $F('title').strip();

  if (title.length == 0) {
    alert(error_article_title_empty);
    $('title').focus();
    return false;
  }

  tinyMCE.triggerSave();

  text = $F('text').strip().stripScripts().stripTags();

  if (text.length == 0) {
    alert(error_article_empty);
    $('text').focus();
    return false;
  }

  tags = $F('tags').strip();

  if (tags.length == 0) {
    alert(error_article_tags_empty);
    $('tags').focus();
    return false;
  }

  $('title').value = title;
  $('text').value = $F('text').strip();
  $('tags').value = tags;

  return true;
}

function editBlogArticle() {
  title = $F('title').strip();

  if (title.length == 0) {
    alert(error_article_title_empty);
    $('title').focus();
    return false;
  }

  tinyMCE.triggerSave();

  text = $F('text').strip().stripScripts().stripTags();

  if (text.length == 0) {
    alert(error_article_empty);
    $('text').focus();
    return false;
  }

  $('title').value = title;
  $('text').value = $F('text').strip();

  $('edit_content').submit();
  return true;
}

function printDebug(message) {
  $("debugWindow").innerHTML = message;
}

function VKM_toggle(ob){
  Element.toggleClassName(ob,'more_up');
  Effect.toggle(Element.up(ob,'div.multi').next('div.vkm_group'),'blind',{duration:0.4});
}

function VKM_groupCheck(checkbox, group, all){
  if (all) {
    $$('input.' + group).each(function(checker) {
      checker.checked = checkbox.checked;
    });
  }
  else if ($(group + '_all')) {
    $(group + '_all').checked = $$('input.' + group).all(function(checker) {
      return checker.checked;
    });
  }
}

ProfileSearch = {
};

ProfileSearch.updateFilterOptions = function(username) {
  new Ajax.Updater('profile_search_filter', '/' + username + '/update_search_filter', { method: 'get' });
};

function setInputVisibility(a) {
  el = Element.previous(a).down('.checkbox');

  if (Element.hasClassName(a, 'vis_checked')) {
    el.checked = false;
    Element.removeClassName(a, 'vis_checked');
  } else {
    el.checked = true;
    Element.addClassName(a, 'vis_checked');
  }
}


//////////////////////////////////////////////////////////////////////////////////////

// cosmo: Profile navigation tabs //

var profile_nav_tabs;
var profile_nav_tabsheight=0;
var profile_nav_tabrows = new Array();
var profile_nav_rowClasses = new Array();
var profile_nav_startTop;
var profile_nav_startLeft=0;

profile_nav_rowOrder=new Array();

document.observe('dom:loaded', function() {

	if($('profile_tab_navigation')){
		$('profile_tab_navigation').style.height=$('profile_tab_navigation').getHeight()+'px';

		Element.hasClassName($('profile_tab_navigation'),'fritz_tab_navigation')?isFritz=1:isFritz=0;
		Element.hasClassName($('profile_tab_navigation'),'klassik_tab_navigation')?isKlassik=1:isKlassik=0;
		
		profile_nav_startLeft=Element.cumulativeOffset($('profile_tab_navigation'))[0];

		profile_nav_tabs = Element.select($('profile_tab_navigation'),'li.pr_tab');

		profile_nav_tabs.each(function(o,i){

			if(i==0){
				profile_nav_tabsheight=Element.getHeight(o);
				profile_nav_startTop=Element.cumulativeOffset(o)[1];
			}

			o.tWidth=Element.getWidth(o);
			o.tLeft=Element.cumulativeOffset(o)[0];
			o.tTop=Element.cumulativeOffset(o)[1];

			profile_nav_tabrows.push(o.tTop);

			Element.down(o,'a').onfocus=function(){this.blur();};
			
			var aTarg=Element.down(o,'a.pr_tab_a').getAttribute('href');
			if(aTarg.endsWith("#")||aTarg==""){
				Element.down(o,'a.pr_tab_a').onclick=function(){return false;};
			}
			
			o.observe('menu:select', function() {
				profileNavClearTabs();
				this.addClassName('live_tab');
				if(!isFritz){o.style.paddingBottom='0';}

				if(Element.down(this,'ul')){
					var ap; isFritz==1?ap=2:ap=1;
					Element.down(this,'ul').style.top=Element.getHeight(this)+ap+'px';
					this.style.height=Element.getHeight(this)+ap+1+'px';
				}
				profileNavMoveTabs(this);
				profileNavResizeWrapper(this);
			});

			o.onclick=function(){
			  this.fire('menu:select');
			};
			o.onmouseover=function(){
				if(!o.hasClassName('live_tab')){
					o.setStyle({
						marginTop:'-3px',
						paddingBottom:'3px'
					});
				}
			}
			o.onmouseout=function(){
				if(!o.hasClassName('live_tab')){
					o.setStyle({
						marginTop:'0',
						paddingBottom:'0'
					});
				}
			}
		});

		profile_nav_tabrows=profile_nav_tabrows.uniq();

		profile_nav_tabrows.each(function(o,i){
			profile_nav_tabs.each(function(p,n){
				if(p.tTop==o){
					Element.addClassName(p,'pr_row_'+(i+1));
					profile_nav_rowClasses.push('pr_row_'+(i+1));
					if(p.tLeft==profile_nav_startLeft){
						p.addClassName('first_tab');
					}
					else if(n==profile_nav_tabs.length-1 || profile_nav_tabs[n+1] && profile_nav_tabs[n+1].tLeft==profile_nav_startLeft){
						p.addClassName('last_tab');
					}
					if(i!=0){isFritz?p.tTop-=i:p.tTop-=i*5;}
				}
			});
			if(i!=0){
				isFritz?profile_nav_tabrows[i]=o-i:profile_nav_tabrows[i]=o-i*5;
			}
		});

		profile_nav_rowClasses=profile_nav_rowClasses.uniq();

		profileNavResizeTabs();
		profileNavPositionTabs();
		profileNavSetRowOrder(profile_nav_tabs.last());
		profileNavAddRowOrderClass();
		profileNavResizeWrapper();
		
		if(isFritz || isKlassik){profileNavDoFritz();}
		
		/*profileNavLocate();*/
		
	}
});


function profileNavPositionTabs(){

	profile_nav_tabs.each(function(o){
		o.setStyle({
		position:"absolute",
		left:o.tLeft+"px",
		top:o.tTop+"px",
		cssFloat:"none",
		width:o.tWidth+"px"
		});
		if(Element.down(o,'a.pr_tab_a')){Element.down(o,'a.pr_tab_a').style.width=o.tWidth-20+'px';}
		if(Element.down(o,'ul')){Element.down(o,'ul').style.left=profile_nav_startLeft-o.tLeft+'px';}
	});

}




function profileNavResizeTabs(){

	profile_nav_rowClasses.each(function(o){
		var totalWidth=0;
		var cClass='li.'+o;
		var currWidth=0;
		$$(cClass).each(function(p){
			totalWidth+=p.tWidth;
		});
		var adj=Math.floor(($('profile_tab_navigation').getWidth()-totalWidth)/$$(cClass).length);
		var shift=0;
		$$(cClass).each(function(p,i){
			p.tWidth+=adj;
			currWidth+=p.tWidth;
			if(i==$$(cClass).length-1){p.tWidth+=$('profile_tab_navigation').getWidth()-currWidth}
			p.tLeft+=shift;
			shift+=adj;
		});
	});

}

function profileNavClearTabs(){
	profile_nav_tabs.each(function(o){
		['live_tab','pr_roworder_1','pr_roworder_2','pr_roworder_3'].each(function(p){
			o.removeClassName(p);
		});
		o.style.height="auto";
	});
}

function profileNavSetRowOrder(ob){
	profile_nav_rowOrder.clear();

	var front_class=$w(ob.className)[1];
	var i=profile_nav_rowClasses.indexOf(front_class);

	for(var k=0;k<profile_nav_rowClasses.length;k++){
		var res = i%profile_nav_rowClasses.length;
		profile_nav_rowOrder[k]=profile_nav_rowClasses[res];
		i++;
	}
}

function profileNavMoveTabs(ob){

	if(Element.cumulativeOffset(ob)[1]!=profile_nav_tabrows.last()){

		profileNavSetRowOrder(ob);

		var rPos=0;

		profile_nav_rowOrder.each(function(r,i){
			var cLi='li.'+r;
			if(i==0){
				$$(cLi).each(function(d){
					d.style.top=profile_nav_tabrows[profile_nav_tabrows.length-1]+'px';
					d.style.zIndex=10;
					if(!d.hasClassName('live_tab')){d.style.marginTop=0;}
				});
			}
			else{
				$$(cLi).each(function(d){
					d.style.top=profile_nav_tabrows[rPos]+'px';
					d.style.zIndex=i+1;
					d.style.marginTop=0;
				});
				rPos++;
			}

		});

		
		profileNavAddRowOrderClass();

	}

}

function profileNavAddRowOrderClass(){
	profile_nav_rowOrder.each(function(o,i){
		profile_nav_tabs.each(function(p){
			if(Element.hasClassName(p,o)){
				if(i==0){
					Element.addClassName(p,'pr_roworder_'+(profile_nav_rowOrder.length));
				}
				else{
					Element.addClassName(p,'pr_roworder_'+(i));
				}
			}
		});		
	});
}

function profileNavResizeWrapper(o){
	if(o){
		co=Element.cumulativeOffset(o)[1];
		ht=Element.getHeight(o);
		if(Element.down(o,'ul')){ht+=Element.down(o,'ul').getHeight();}
	}
	else{
		co=Element.cumulativeOffset(profile_nav_tabs.last())[1];
		ht=Element.getHeight(profile_nav_tabs.last());
	}
		
	$('profile_tab_navigation').style.height=co - profile_nav_startTop + ht +'px';
}


function profileNavDoFritz(){
	Element.select($('profile_tab_navigation'),'li.pr_tab').each(function(o,i){
		var corner=document.createElement('span');
		var sideBorder=document.createElement('span');
		var liveCorner=document.createElement('span');
		var withCorner=0;
		if(!Element.down(o,'ul')){
			var addon=2; var addon2=0;
		}else{
			var addon=5; var addon2=5;
		}
		if(Element.hasClassName(o,'first_tab')){
			sideBorder.className='tab_left_border';
			sideBorder.style.height=profile_nav_tabsheight+addon+"px";
		}
		else if(Element.hasClassName(o,'last_tab')){
			sideBorder.className='tab_right_border';
			sideBorder.style.height=profile_nav_tabsheight+addon2+"px";
		}

		liveCorner.className='tab_live_corner';
		corner.className='tab_left_corner';

		Element.hide(corner);
		Element.insert(o,{bottom:corner});
		Element.insert(o,{bottom:liveCorner});
		Element.insert(o,{bottom:sideBorder});	

		Event.observe(o,'mouseover',function(){
			if(!Element.hasClassName(o,'first_tab') && !Element.hasClassName(o,'live_tab')){Element.show(corner);}
			if(!Element.hasClassName(o,'live_tab')){Element.addClassName(o,"raised_tab");}
		});
		Event.observe(o,'mouseout',function(event){
			Element.hide(corner);
			Element.removeClassName(this,"raised_tab");
		});
		Event.observe(o,'click',function(){
			Element.hide(corner);
			Element.removeClassName(this,"raised_tab");
			profile_nav_tabs.each(function(r){
				r.style.paddingBottom="0";
			});
			if(!Element.down(this,'ul')){
				this.style.paddingBottom='2px';
			}
		});
		
		Element.addClassName($('profile_tab_navigation'),'profile_tab_bg');
		
	});
}

function profileNavLocate() {
  var a, url, path, re;
  
  var anchors = $('profile_tab_navigation').select('a');
  
  for (var i = 0, size = anchors.length; i < size; ++i) {
    a = anchors[i];
    a.removeClassName('profile_current_location');
    
    url = a.getAttribute('href');
    
    if (!url.endsWith('#')) {
      path = url.split(location.hostname).last().split('?').first();
      
      if (/\/change$/.test(path)) {
        re = new RegExp('\/change_step(1|2|3|4)$'); // die 4 Profil-Bearbeiten-Schritte
      }
      else if (/\/delete$/.test(path)) {
        re = new RegExp('\/delete(_all)?$'); // die 2 Profil-Löschen-Schritte
      }
      else if (/^\/freunde$/.test(path)) {
        re = new RegExp('^(\/[^\/]+)?\/freunde$'); // Freundeübersicht
      }
      else if (/gruppen$/.test(path)) {
        re = new RegExp('gruppen$'); // Gruppenübersicht
      }
      else if (/^\/[^\/]+$/.test(path)) {
        re = new RegExp('^' + path + '((\/blog)|((\/shouts)?\/[1-9]\\d*))?$'); // Permalinks, Shouts und Blog
      }
      else if (/\/orte\/neu$/.test(path)) {
        re = new RegExp('\/orte\/neu(\/schritt-2)?$'); // die 2 Location-Schritte
      }
      else if (/benachrichtigungen$/.test(path)) {
        // Benachrichtigungen und Inhaltsabos
        re = new RegExp('(benachrichtigungen|inhaltsabos)$');
      }
      else {
        re = new RegExp('^' + path + '$'); // der Rest
      }

      if (re.test(location.pathname)) {
        if (isFritz) {
           a.up('li.pr_tab').setStyle({ marginTop: '-3px', paddingBottom: '0px' });
        }
        
        a.up('li.pr_tab').onclick();
        a.addClassName('profile_current_location');
      }
    }
  }
}

function selectMenuItem(site, selectedMenuItemId) {
  var menu = $('profile_tab_navigation');
  
  if (!menu) { return; }
  
  var menuItem, menuItemHolder, menuItems = menu.select('a');
  
  for (var i = 0, size = menuItems.length; i < size; ++i) {
    menuItem = menuItems[i];
    menuItem.removeClassName('profile_current_location');
    
    if (menuItem.id == selectedMenuItemId) {
      menuItemHolder = menuItem.up('li.pr_tab');
      
      if (site == 'fritz') {
        Element.setStyle.defer(menuItemHolder, { marginTop: '-3px', paddingBottom: '0px' });
      }
      
      Element.fire.defer(menuItemHolder, 'menu:select');
      menuItem.addClassName('profile_current_location');
    }
  }
}


/* see: http://tore.darell.no/posts/simple_custom_event_system */

AppEvents = {
  subscriptions: {}
};

AppEvents.subscribe = function(message, callback, scope) {
  if (!this.subscriptions[message]) {
    this.subscriptions[message] = [];
  }
  
  this.subscriptions[message].push({ callback: callback, scope: scope });
};

AppEvents.unsubscribe = function(message, callback) {
  var i, s;
  
  if (s = this.subscriptions[message]) {
    for (i = 0; i < s.length; i++) {
      if (s[i].callback == callback) { 
        s.splice(i, 1);
      }
    }
  }
};

AppEvents.fire = function(message) {
  var i, s, args, subscriptions;
  
  if (subscriptions = this.subscriptions[message]) {
    args = Array.prototype.slice.apply(arguments, [1]);
    
    for (i = 0; i < subscriptions.length; i++) {
      s = subscriptions[i];
      s.callback.apply(s.scope || window, args);
    }
  }
};


Statusbox = {
};

Statusbox.addToFriendsCounter = function(value) {
  try {
    var friendsCountHolder = $('statusbox_friends_count');
    
    if (friendsCountHolder) {
      var friendsCount = parseInt(friendsCountHolder.innerHTML.strip());
      
      friendsCount += value;
      
      if (friendsCount >= 0) {
        friendsCountHolder.innerHTML = friendsCount;
      }
    }
  }
  catch (e) {
  }
};

Statusbox.addToGroupsCounter = function(value) {
  try {
    var groupsCountHolder = $('statusbox_groups_count');
    
    if (groupsCountHolder) {
      var groupsCount = parseInt(groupsCountHolder.innerHTML.strip());
      
      groupsCount += value;
      
      if (groupsCount >= 0) {
        groupsCountHolder.innerHTML = groupsCount;
      }
    }
  }
  catch (e) {
  }
};

Statusbox.addToFavoritesCounter = function(value) {
  try {
    var favoritesCountHolder = $('statusbox_favorites_count');
    
    if (favoritesCountHolder) {
      var favoritesCount = parseInt(favoritesCountHolder.innerHTML.strip());
      
      favoritesCount += value;
      
      if (favoritesCount >= 0) {
        favoritesCountHolder.innerHTML = favoritesCount;
      }
    }
  }
  catch (e) {
  }
};

Statusbox.incrementFriendsCounter = function() {
  Statusbox.addToFriendsCounter(1);
};

Statusbox.decrementFriendsCounter = function() {
  Statusbox.addToFriendsCounter(-1);
};

Statusbox.incrementGroupsCounter = function() {
  Statusbox.addToGroupsCounter(1);
};

Statusbox.decrementGroupsCounter = function() {
  Statusbox.addToGroupsCounter(-1);
};

Statusbox.incrementFavoritesCounter = function() {
  Statusbox.addToFavoritesCounter(1);
};

Statusbox.decrementFavoritesCounter = function() {
  Statusbox.addToFavoritesCounter(-1);
};

Statusbox.decrementUnseenFriendshipRequestsCounter = function() {
  try {
    var unseenFriendshipRequestsCountHolder = $('statusbox_unseen_friendship_requests_count');
    
    if (unseenFriendshipRequestsCountHolder) {
      var unseenFriendshipRequestsCount = parseInt(unseenFriendshipRequestsCountHolder.innerHTML.strip());
      
      if (unseenFriendshipRequestsCount > 0) {
        unseenFriendshipRequestsCount--;
        unseenFriendshipRequestsCountHolder.innerHTML = unseenFriendshipRequestsCount;
      
        if (unseenFriendshipRequestsCount == 0) {
          var unseenFriendshipRequestsContainer = $('statusbox_unseen_friendship_requests_container');
          
          if (unseenFriendshipRequestsContainer) {
            Effect.SlideUp(unseenFriendshipRequestsContainer, { duration: 0.25 });
          }
        }
      }
    }
  }
  catch (e) {
  }
};

Statusbox.decrementUnseenGroupMembershipInvitationsCounter = function() {
  try {
    var unseenGroupMembershipsInvitationsCountHolder = $('statusbox_unseen_group_membership_invitations_count');
    
    if (unseenGroupMembershipsInvitationsCountHolder) {
      var unseenGroupMembershipsInvitationsCount = parseInt(unseenGroupMembershipsInvitationsCountHolder.innerHTML.strip());
      
      if (unseenGroupMembershipsInvitationsCount > 0) {
        unseenGroupMembershipsInvitationsCount--;
        unseenGroupMembershipsInvitationsCountHolder.innerHTML = unseenGroupMembershipsInvitationsCount;
      
        if (unseenGroupMembershipsInvitationsCount == 0) {
          var unseenGroupMembershipsInvitationsContainer = $('statusbox_unseen_group_membership_invitations_container');
          
          if (unseenGroupMembershipsInvitationsContainer) {
            Effect.SlideUp(unseenGroupMembershipsInvitationsContainer, { duration: 0.25 });
          }
        }
      }
    }
  }
  catch (e) {
  }
};

Statusbox.decrementUnreadPrivateMessagesCounter = function() {
  try {
    var unreadPrivateMessagesCountHolder = $('statusbox_unread_private_messages_count');
    
    if (unreadPrivateMessagesCountHolder) {
      var unreadPrivateMessagesCount = parseInt(unreadPrivateMessagesCountHolder.innerHTML.strip());
      
      if (unreadPrivateMessagesCount > 0) {
        unreadPrivateMessagesCount--;
        unreadPrivateMessagesCountHolder.innerHTML = unreadPrivateMessagesCount;
      
        if (unreadPrivateMessagesCount == 0) {
          var privateMessagesContainer = $('statusbox_private_messages_container');
          
          if (privateMessagesContainer) {
            privateMessagesContainer.removeClassName('new');
          }
        }
      }
    }
  }
  catch (e) {
  }
};

Statusbox.decrementReceivedPrivateMessagesCounter = function() {
  try {
    var receivedPrivateMessagesCountHolder = $('statusbox_received_private_messages_count');
    
    if (receivedPrivateMessagesCountHolder) {
      var receivedPrivateMessagesCount = parseInt(receivedPrivateMessagesCountHolder.innerHTML.strip());
      
      if (receivedPrivateMessagesCount > 0) {
        receivedPrivateMessagesCount--;
        receivedPrivateMessagesCountHolder.innerHTML = receivedPrivateMessagesCount;
      }
    }
  }
  catch (e) {
  }
};

document.observe('dom:loaded', function() {  
  AppEvents.subscribe('friendship_request_seen', function(id) {
    Statusbox.decrementUnseenFriendshipRequestsCounter();
  });  
  
  AppEvents.subscribe('group_membership_invitation_seen', function(id) {
    Statusbox.decrementUnseenGroupMembershipInvitationsCounter();
  });
  
  AppEvents.subscribe('friendship_request_accepted', function(id) {
    Statusbox.incrementFriendsCounter();
  });
  
  AppEvents.subscribe('group_membership_invitation_accepted', function(id) {
    Statusbox.incrementGroupsCounter();
  });
  
  AppEvents.subscribe('group_member_added', function(id) {
    Statusbox.incrementGroupsCounter();
  });
  
  AppEvents.subscribe('group_member_removed', function(id) {
    Statusbox.decrementGroupsCounter();
  });
  
  AppEvents.subscribe('friendship_released', function(id) {
    Statusbox.decrementFriendsCounter();
  });
  
  AppEvents.subscribe('private_message_read_received', function(id) {
    Statusbox.decrementUnreadPrivateMessagesCounter();
  });
  
  AppEvents.subscribe('private_message_delete_received', function(id) {
    Statusbox.decrementReceivedPrivateMessagesCounter();
  });
  
  AppEvents.subscribe('favorite_added', function() {
    Statusbox.incrementFavoritesCounter();
  });
  
  AppEvents.subscribe('favorite_removed', function() {
    Statusbox.decrementFavoritesCounter();
  });
});


Contents = {
  validateFileName: function(errors) {
    if ($(Contents.media_type + '_file')) {
      Validation.validatePresence(errors, Contents.media_type + '_file', Contents.media_type + '_file', Contents.media_type + '_empty');
    }
  },

  validateTitle: function(errors) {
    if ($(Contents.media_type + '_title')) {
      Validation.validatePresence(errors, Contents.media_type + '_title', Contents.media_type + '_title', Contents.media_type + '_title_empty');
    }
  },

  validateTags: function(errors) {
    if ($(Contents.media_type + '_initial_tags')) {
      Validation.validatePresence(errors, Contents.media_type + '_initial_tags', Contents.media_type + '_initial_tags', Contents.media_type + '_tags_empty');
    }
  },

  validateArtist: function(errors) {
    if ($(Contents.media_type + '_artist')) {
      Validation.validatePresence(errors, Contents.media_type + '_artist', Contents.media_type + '_artist', Contents.media_type + '_artist_empty');
    }
  },

  validateArticleText: function(errors) {
    if ($('article_text')) {
      tinyMCE.triggerSave();
      $('article_text').value = $F('article_text').stripScripts().stripTags();
      Validation.validatePresence(errors, 'article_text', 'article_text', 'article_empty');
    }
  },

  validateAssignment: function(errors) {
    var assign_to_profile = $(Contents.media_type + '_assign_to_profile').checked;
    var assign_to_group   = $(Contents.media_type + '_owner_has_groups')    && !$F(Contents.media_type + '_assign_to_group').blank();
    var assign_to_gallery = $(Contents.media_type + '_owner_has_galleries') && !$F(Contents.media_type + '_assign_to_gallery').blank();

    if (!assign_to_profile && !assign_to_group && !assign_to_gallery) {
      errors.add(Contents.media_type + '_assignment', 'picture_assignment_empty');
    }
  },

  validateArticleAssignment: function(errors, id) {
    var assign_to_profile = $('article_' + id + '_assign_to_profile').checked;
    var assign_to_group;

    if ($F('article_' + id + '_no_groups') == '1') {
      assign_to_group = false;
    }
    else {
      assign_to_group = $F('article_' + id + '_group_assignment') != '';
    }
    
    if (!(assign_to_profile || assign_to_group)) {
      errors.add('article_assignment', 'article_assignment_empty');
    }
  },

  alertAndJumpToFirstError: function() {
    var firstErrorFieldWrapper, firstErrorInput;

    alert(ValidationErrors.localizations.get('base') || 'Fehler: Eingaben inkorrekt.');
    if (firstErrorFieldWrapper = $$(' .multi.form_error').first()) {
      firstErrorFieldWrapper.scrollTo();
      if (firstErrorInput = firstErrorFieldWrapper.select('select', 'textarea', 'input').first()) {
        firstErrorInput.activate();
      }
    }
  }
};

Contents.fisheye = function(element, zoom, f) {
  var fct = f ? (f / 100) : 4;
  if (!element.origW) {
    var orig_dims = Element.getDimensions(element);
    element.origW = orig_dims.width;
    element.origH = orig_dims.height;
  }
  
  if (zoom) {
    if (element.imgOutEffect) {
      element.imgOutEffect.cancel();
    }
    
    element.imgEffect = new Effect.Morph(element, { style: 'height: ' + (element.origH * fct) + 'px; width: ' + (element.origW * fct) + 'px;', duration: 0.3 });
  }
  else {
    if (element.imgEffect) {
      element.imgEffect.cancel();
    }
    
    element.imgOutEffect = new Effect.Morph(element, { style: 'height: ' + element.origH + 'px; width: ' + element.origW + 'px;', duration: 0.3 });
  }
};

Contents.isNewPictureFormValid = function() {
  if (($('picture_mode') && $F('picture_mode') == 'existing') || ($('picture_mode_existing') && $('picture_mode_existing').checked)) {
    return true;
  }

  var errors = new ValidationErrors();
  Validation.clearDisplayedErrors();
  Contents.media_type = 'picture';

  Contents.validateFileName(errors);
  Contents.validateTitle(errors);
  Contents.validateTags(errors);
  Contents.validateAssignment(errors)

  if (errors.any()) {
    Validation.displayErrors(errors);
    Contents.alertAndJumpToFirstError();
    return false;
  }

  $('picture_title').value = $F('picture_title').strip();
  $('picture_initial_tags').value = $F('picture_initial_tags').strip();

  return true;
};

Contents.isNewGroupPictureFormValid = function() {
  if (($('mode') && $F('mode') == 'existing') || ($('mode_existing') && $('mode_existing').checked)) {
    return true;
  }

  var errors = new ValidationErrors();
  Validation.clearDisplayedErrors();
  Contents.media_type = 'picture';

  Contents.validateFileName(errors);
  Contents.validateTitle(errors);
  Contents.validateTags(errors);

  if (errors.any()) {
    Validation.displayErrors(errors);
    Contents.alertAndJumpToFirstError();
    return false;
  }

  $('picture_title').value = $F('picture_title').strip();
  $('picture_initial_tags').value = $F('picture_initial_tags').strip();

  return true;
};

Contents.isEditPictureFormValid = function(id) {
  var title = $('picture_' + id + '_title').value.strip();

  if (title.length == 0) {
    alert(error_picture_title_empty);
    $('picture_' + id + '_title').focus();
    return false;
  }

  var assignToProfile = $('picture_' + id + '_assign_to_profile').checked;
  var assignToGroup   = $('picture_' + id + '_owner_has_groups')    && !$F('picture_' + id + '_assign_to_group').blank();
  var assignToGallery = $('picture_' + id + '_owner_has_galleries') && !$F('picture_' + id + '_assign_to_gallery').blank();

  if (!assignToProfile && !assignToGroup && !assignToGallery) {
    alert(error_picture_assignment_empty);
    return false;
  }

  $('picture_' + id + '_title').value = title;

  return true;
};

Contents.isNewAudioFormValid = function() {
  if (($('audio_mode') && $F('audio_mode') == 'existing') || ($('audio_mode_existing') && $('audio_mode_existing').checked) || ($('mode_existing') && $('mode_existing').checked)) {
    return true;
  }

  var errors = new ValidationErrors();
  Validation.clearDisplayedErrors();
  Contents.media_type = 'audio';

  Contents.validateFileName(errors);
  Contents.validateTitle(errors);
  Contents.validateArtist(errors);
  Contents.validateTags(errors);

  if (errors.any()) {
    Validation.displayErrors(errors);
    Contents.alertAndJumpToFirstError();
    return false;
  }

  $('audio_title').value = $F('audio_title').strip();
  $('audio_artist').value = $F('audio_artist').strip();
  $('audio_initial_tags').value = $F('audio_initial_tags').strip();

  return true;
};

Contents.isEditAudioFormValid = function(id) {
  var title = $('audio_' + id + '_title').value.strip();

  if (title.length == 0) {
    alert(error_audio_title_empty);
    $('audio_' + id + '_title').focus();
    return false;
  }

  var artist = $('audio_' + id + '_artist').value.strip();

  if (artist.length == 0) {
    alert(error_audio_artist_empty);
    $('audio_' + id + '_artist').focus();
    return false;
  }
  
  var assign_to_profile = $('audio_' + id + '_assign_to_profile').checked;
  var assign_to_group;
  
  if ($F('audio_' + id + '_no_groups') == '1') {
    assign_to_group = false;
  }
  else {
    assign_to_group = $F('audio_' + id + '_group_assignment') != '';
  }
  
  if (!(assign_to_profile || assign_to_group)) {
    alert(error_audio_assignment_empty);
    return false;
  }

  $('audio_' + id + '_title').value = title;
  $('audio_' + id + '_artist').value = artist;

  return true;
};

Contents.isNewVideoFormValid = function() {
  if (($('video_mode') && $F('video_mode') == 'existing') || ($('video_mode_existing') && $('video_mode_existing').checked) || ($('mode_existing') && $('mode_existing').checked)) {
    return true;
  }

  var errors = new ValidationErrors();
  Validation.clearDisplayedErrors();
  Contents.media_type = 'video';

  Contents.validateFileName(errors);
  Contents.validateTitle(errors);
  Contents.validateArtist(errors);
  Contents.validateTags(errors);

  if (errors.any()) {
    Validation.displayErrors(errors);
    Contents.alertAndJumpToFirstError();
    return false;
  }

  $('video_title').value = $F('video_title').strip();
  $('video_artist').value = $F('video_artist').strip();
  $('video_initial_tags').value = $F('video_initial_tags').strip();

  return true;
};

Contents.isEditVideoFormValid = function(id) {
  var title = $('video_' + id + '_title').value.strip();

  if (title.length == 0) {
    alert(error_video_title_empty);
    $('video_' + id + '_title').focus();
    return false;
  }

  var artist = $('video_' + id + '_artist').value.strip();

  if (artist.length == 0) {
    alert(error_video_artist_empty);
    $('video_' + id + '_artist').focus();
    return false;
  }
  
  var assign_to_profile = $('video_' + id + '_assign_to_profile').checked;
  var assign_to_group;
  
  if ($F('video_' + id + '_no_groups') == '1') {
    assign_to_group = false;
  }
  else {
    assign_to_group = $F('video_' + id + '_group_assignment') != '';
  }
  
  if (!(assign_to_profile || assign_to_group)) {
    alert(error_video_assignment_empty);
    return false;
  }

  $('video_' + id + '_title').value = title;
  $('video_' + id + '_artist').value = artist;

  return true;
};

Contents.isNewArticleFormValid = function() {
  if (($('article_mode') && $F('article_mode') == 'existing') || ($('article_mode_existing') && $('article_mode_existing').checked) || ($('mode_existing') && $('mode_existing').checked)) {
    return true;
  }

  var errors = new ValidationErrors();
  Validation.clearDisplayedErrors();
  Contents.media_type = 'article';

  Contents.validateTitle(errors);
  Contents.validateArticleText(errors);
  Contents.validateTags(errors);

  if (errors.any()) {
    Validation.displayErrors(errors);
    Contents.alertAndJumpToFirstError();
    return false;
  }

  $('article_title').value = $F('article_title').strip();
  $('article_initial_tags').value = $F('article_initial_tags').strip();

  return true;
};

Contents.isEditArticleFormValid = function(id) {
  var errors = new ValidationErrors();
  Validation.clearDisplayedErrors();
  Contents.media_type = 'article';

  Contents.validateTitle(errors);
  Contents.validateArticleText(errors);
  Contents.validateArticleAssignment(errors, id);

  if (errors.any()) {
    Validation.displayErrors(errors);
    Contents.alertAndJumpToFirstError();
    return false;
  }

  $('article_title').value = $F('article_title').strip();
  $('article_initial_tags').value = $F('article_initial_tags').strip();

  return true;
};

Contents.isNewPictureGalleryFormValid = function() {
  var errors = new ValidationErrors();
  Validation.clearDisplayedErrors();
  Contents.media_type = 'picture_gallery';

  Contents.validateTitle(errors);
  Contents.validateTags(errors);

  var existingPresent = $F('picture_gallery_existing_present') == '1';

  if (existingPresent) {
    var anyExistingSelected = $$('#picture_tab_existing_content .existing_picture').any(function(checkbox) { return checkbox.checked; });
    var anyNewProvided = $$('#picture_tab_new_content .new_picture').any(function(filefield) { return !filefield.value.blank(); });

    if (!anyExistingSelected && !anyNewProvided) {
      errors.add('picture_gallery_select_picture', 'picture_gallery_choose_picture');
    }
  }
  else {
    var anyNewProvided = $$('#picture_tab_new_content .new_picture').any(function(filefield) { return !filefield.value.blank(); });
    
    if (!anyNewProvided) {
      errors.add('picture_gallery_select_picture', 'picture_gallery_at_least_one_picture');
    }
  }

  if (errors.any()) {
    Validation.displayErrors(errors);
    Contents.alertAndJumpToFirstError();
    return false;
  }

  $('picture_gallery_title').value = $F('picture_gallery_title').strip();
  $('picture_gallery_initial_tags').value = $F('picture_gallery_initial_tags').strip();

  return true;
};

Contents.isEditPictureGalleryFormValid = function(id) {
  var title = $('picture_gallery_' + id + '_title').value.strip();

  if (title.length == 0) {
    alert(error_picture_gallery_title_empty);
    $('picture_gallery_' + id + '_title').focus();
    return false;
  }

  $('picture_gallery_' + id + '_title').value = title;
  
  if ($('picture_gallery_' + id + '_assign_to_profile')) {
    var assign_to_profile = $('picture_gallery_' + id + '_assign_to_profile').checked;
    var assign_to_group;
    
    if ($F('picture_gallery_' + id + '_no_groups') == '1') {
      assign_to_group = false;
    }
    else {
      assign_to_group = $F('picture_gallery_' + id + '_group_assignment') != '';
    }
    
    if (!(assign_to_profile || assign_to_group)) {
      alert(error_picture_gallery_assignment_empty);
      return false;
    }
  }

  return true;
};

Contents.isPlaylistFormValid = function(form_id) {
  var form = $(form_id);

  
  if (form['mode_add'].checked) {
    if (form['playlist_id'].value.blank()) {
      alert(error_playlist_empty);
      form['playlist_id'].focus();

      return false;    
    }
  }
  else {
    var title = form['playlist_title'].value.strip();

    if (title.length == 0) {
      alert(error_playlist_title_empty);
      form['playlist_title'].focus();
      return false;
    }

    var tags = form['playlist_initial_tags'].value.strip();

    if (tags.length == 0) {
      alert(error_playlist_tags_empty);
      form['playlist_initial_tags'].focus();
      return false;
    }

    form['playlist_title'].value = title;
    form['playlist_initial_tags'].value = tags;
  }
  
  return true;
};

Contents.getAvailableTracks = function(mode, playlist_id, selected_playlist_id) {
  element = "available_tracks_" + playlist_id;

  new Ajax.Updater(element, "/content/available_tracks", { 
    parameters: { mode: mode, playlist_id: playlist_id, selected_playlist_id: selected_playlist_id, authenticity_token: encodeURIComponent(authenticityToken) }
  });
};


var GenreSelector = Class.create({
  initialize: function(fieldName, beforeId, genres, selectedGenre, divClassName, labelClassName, genreLabel, subGenreLabel, help_icon) {
    this.fieldName      = fieldName;
    this.beforeId       = beforeId;
    this.beforeElement  = $(beforeId);
    this.genreTree      = this.buildGenreTree(genres);
    this.selected       = selectedGenre || '';
    this.divClassName   = divClassName || 'genre_selector_div';
    this.labelClassName = labelClassName || 'genre_selector_label';
    this.genreLabel     = genreLabel || 'Genre';
    this.subGenreLabel  = subGenreLabel || 'Subgenre';
    this.boundSelectionChangedHandler = this.onSelectionChanged.bindAsEventListener(this);
    this.help_icon      = help_icon;
    
    this.render();
  },

  getGenreTree: function() {
    return this.genreTree;
  },
  
  buildGenreTree: function(genres) {
    var globalDepth = 0;
    var localDepth;
    
    this.id3GenreTagNumbers = new Hash();
    
    genres = genres.split(':');
    
    for (var i = 0, size = genres.length; i < size; ++i) {
      var genreAndId3GenreTagNumber = genres[i].split('*');
      var genre = genreAndId3GenreTagNumber.first();
      var id3GenreTagNumber = genreAndId3GenreTagNumber.last();
      
      this.id3GenreTagNumbers.set(genre, id3GenreTagNumber);

      genres[i] = genre.split('~');
      
      if (genres[i].length > globalDepth) {
        globalDepth = genres[i].length;
      }      
    }
    
    return this.buildGenreTreeRecursive(genres);
  },
  
  buildGenreTreeRecursive: function(items) {
    var subItems = new Hash();
    
    for (var i = 0, size = items.length; i < size; ++i) {
      var item = items[i];
      
      if (item.first()) {        
        if (!subItems.get(item.first())) {
          subItems.set(item.first(), new Array());
        }
        
        subItems.get(item.first()).push(item.slice(1));        
      }
    }
    
    for (var i = 0, size = subItems.keys().length; i < size; ++i) {
      var sub = subItems.keys()[i];
      
      subItems.set(sub, this.buildGenreTreeRecursive(subItems.get(sub)));
    }
    
    return subItems;
  },
  
  render: function() {
    this.lists = new Array();
    var currentElement = this.beforeElement;
    
    var oldElements = $$('.gsx');
    
    for (var i = 0, size = oldElements.length; i < size; ++i) {
      oldElements[i].remove();
    }
    
    var hidden = document.createElement('input');
    Element.extend(hidden);
    hidden.type = 'hidden';
    hidden.id = hidden.name = this.fieldName;
    hidden.value = this.selected;
    hidden.addClassName('gsx');
    
    currentElement.insert({ after: hidden });
    currentElement = hidden;
    
    var div = document.createElement('div');
    Element.extend(div);  
    div.addClassName('gsx');
    div.addClassName(this.divClassName);
    
    var label = document.createElement('label');
    Element.extend(label);  
    label.setAttribute('for', 'genre_selector_0');
    label.appendChild(document.createTextNode(this.genreLabel + ':'));  
    label.addClassName(this.labelClassName);   
    div.appendChild(label);
    
    var list = document.createElement('select');
    Element.extend(list);  
    list.name = list.id = 'genre_selector_0';
    list.onchange = this.boundSelectionChangedHandler;
    this.lists.push(list);
    
    var option = document.createElement('option');
    option.value = '';
    option.appendChild(document.createTextNode(''));
    list.appendChild(option);
    
    var genres = this.selected.sub(/\*\d+$/, '').split('~');
    var downTheTree = this.genreTree;
    var subGenres = downTheTree.keys().sort();
    var noFurtherSubGenre = false;

    if (this.help_icon)
      Element.insert(div, this.help_icon);

    for (var i = 0, isize = genres.length; i < isize; ++i) {      
      var selectedSubGenre = genres[i];
      
      for (var j = 0, jsize = subGenres.length; j < jsize; ++j) {
        option = document.createElement('option');
        option.value = subGenres[j];
        option.selected = subGenres[j] == selectedSubGenre;
        option.appendChild(document.createTextNode(subGenres[j]));
        list.appendChild(option);
      }
      
      downTheTree = downTheTree.get(selectedSubGenre);
      
      if (downTheTree && downTheTree.size() > 0)
      {      
        subGenres = downTheTree.keys().sort();
        
        div.appendChild(list);
        currentElement.insert({ after: div });
        currentElement = div;
        
        div = document.createElement('div'); 
        Element.extend(div);     
        div.addClassName('gsx');
        div.addClassName(this.divClassName);
        
        label = document.createElement('label');
        Element.extend(label);     
        label.setAttribute('for', 'genre_selector_' + (i + 1));
        label.appendChild(document.createTextNode(this.subGenreLabel + ' ' + (i + 1) + ':'));  
        label.addClassName(this.labelClassName);   
        div.appendChild(label);
        
        list = document.createElement('select');
        Element.extend(list);     
        list.name = list.id = 'genre_selector_' + (i + 1);
        list.onchange = this.boundSelectionChangedHandler;
        this.lists.push(list);
        
        option = document.createElement('option');
        option.value = '';
        option.appendChild(document.createTextNode(''));
        list.appendChild(option);
      }
      else {
        noFurtherSubGenre = true;
      }
    }   
      
    if (!noFurtherSubGenre) {
      for (var i = 0, size = subGenres.length; i < size; ++i) {
        option = document.createElement('option');
        option.value = subGenres[i];
        option.appendChild(document.createTextNode(subGenres[i]));
        list.appendChild(option);
      }
    }
     
    div.appendChild(list);
    currentElement.insert({ after: div });
  },
  
  onSelectionChanged: function(e) {
    var subGenres = new Array();
    var subGenre;
    
    for (var i = 0, last = parseInt(Event.element(e).name.match(/\d+$/)); i <= last; ++i) {
      subGenre = $('genre_selector_' + i).value;

      if (!subGenre.blank()) {
         subGenres.push(subGenre);
      }

    }
    
    var genre = subGenres.join('~');
    
    if (genre.length > 0) {
      genre += '*' + this.id3GenreTagNumbers.get(genre);
    }
    
    this.selected = genre;
    this.render();
    
    if (e) Event.stop(e);
  }
});



SentMessages = {
};

SentMessages.toggleBody = function(id, authenticityToken) {
  var body    = $('sent_message_' + id + '_body');
  var subject = $('sent_message_' + id + '_subject');
  
  if (body.hasClassName('visible')) {
    Effect.SlideUp(body, { duration: 0.25, afterFinish: function() {
      body.removeClassName('visible');
      subject.removeClassName('up');
    }});
  }
  else {
    Effect.SlideDown(body, { duration: 0.25, afterFinish: function() {
      body.addClassName('visible');
      subject.addClassName('up');
    }});
  }
};

SentMessages.isComposeFormValid = function() {
  receiver_name = $F('receiver_name').strip();

  if (receiver_name.length == 0) {
    alert(error_pm_form_receiver_empty);
    $('receiver_name').focus();
    return false;
  }

  subject = $F('subject').strip();

  if (subject.length == 0) {
    alert(error_pm_form_subject_empty);
    $('subject').focus();
    return false;
  }

  body = $F('body').strip();

  if (body.length == 0) {
    alert(error_pm_form_body_empty);
    $('body').focus();
    return false;
  }

  $('receiver_name').value = receiver_name;
  $('subject').value = subject;
  $('body').value = body;

  return true;
};

SentMessages.resetComposeFormInputFields = function() {
  $('receiver_name').value = '';
  $('subject').value = '';
  $('body').value = '';
  
  $('receiver_name').focus();
};


ReceivedMessages = {
};

ReceivedMessages.toggleBody = function(id, path, authenticityToken) {
  var body    = $('received_message_' + id + '_body');
  var subject = $('received_message_' + id + '_subject');
  
  if (body.hasClassName('visible')) {
    Effect.SlideUp(body, { duration: 0.25, afterFinish: function() {
      body.removeClassName('visible');
      subject.removeClassName('up');
    }});
  }
  else {
    Effect.SlideDown(body, { duration: 0.25, afterFinish: function() {
      body.addClassName('visible');
      subject.addClassName('up');
    }});
  }
  
  if (body.hasClassName('unread')) {
    new Ajax.Request(path, { parameters: 'authenticity_token=' + encodeURIComponent(authenticityToken), method: 'put', asynchronous: true, evalScripts: true });
  }
};

ReceivedMessages.markAsRead = function(id) {
  $('received_message_' + id + '_body').removeClassName('unread');
  $('received_message_' + id + '_new_icon').hide();
};

ReceivedMessages.deselect = function(id) {
  var selector = $('ids_' + id);
    
  if (selector && selector.checked) {
    selector.checked = false;
  }
};

Messages = {
};

Messages.toggleCheckAll = function(toggler) {
  var state = toggler.checked;
  var checkboxes = $$('input.message_checker, input.message_toggler');

  for (var i = 0, size = checkboxes.length; i < size; ++i) {
    checkboxes[i].checked = state;
  }
};

Messages.toggleCheck = function(checker) {
  if (!checker.checked) {
    $$('input.message_toggler').each(function(toggler) {
      toggler.checked = false;
    });
  }
  else {
    var all_checked = $$('.message_checker').all(function(check) {
      return check.checked;
    });
    $$('input.message_toggler').each(function(toggler) {
      toggler.checked = all_checked;
    });
  }
};

document.observe('dom:loaded', function() {  
  AppEvents.subscribe('private_message_read_received', function(id) {
    ReceivedMessages.markAsRead(id);
    
    var selector = $('ids_' + id);
    
    if (selector && selector.checked) {
      selector.checked = false;
    }
  });
  
  AppEvents.subscribe('private_message_deselect_received', function(id) {
    ReceivedMessages.deselect(id);
  });
});


GroupForum = {};

GroupForum.isCreateTopicFormValid = function() {
  if ($F('forum_topic_title').blank()) {
    alert(error_forum_topic_title_empty);
    $('forum_topic_title').focus();
    return false;
  }

  if ($F('forum_topic_body').blank()) {
    alert(error_forum_topic_body_empty);
    $('forum_topic_body').focus();
    return false;
  }
  
  $('forum_topic_title').value = $F('forum_topic_title').strip();
  $('forum_topic_body').value = $F('forum_topic_body').strip();

  return true;
};

GroupForum.isEditTopicFormValid = function() {
  if ($F('forum_topic_title').blank()) {
    alert(error_forum_topic_title_empty);
    $('forum_topic_title').focus();
    return false;
  }
  
  $('forum_topic_title').value = $F('forum_topic_title').strip();

  return true;
};

GroupForum.isCreatePostFormValid = function() {
  if ($F('forum_post_body').blank()) {
    alert(error_forum_post_body_empty);
    $('forum_post_body').focus();
    return false;
  }
  
  $('forum_post_body').value = $F('forum_post_body').strip();

  return true;
};

GroupForum.isEditPostFormValid = function() {
  if ($F('forum_post_body').blank()) {
    alert(error_forum_post_body_empty);
    $('forum_post_body').focus();
    return false;
  }
  
  $('forum_post_body').value = $F('forum_post_body').strip();

  return true;
};


/* SWFObject v2.1 <http://code.google.com/p/swfobject/>
	Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis
	This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
*/
var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write("<script id=__ie_ondomload defer=true src=//:><\/script>");J=C("__ie_ondomload");if(J){I(J,"onreadystatechange",S)}}catch(q){}}if(h.webkit&&typeof K.readyState!=b){Z=setInterval(function(){if(/loaded|complete/.test(K.readyState)){E()}},10)}if(typeof K.addEventListener!=b){K.addEventListener("DOMContentLoaded",E,null)}R(E)}();function S(){if(J.readyState=="complete"){J.parentNode.removeChild(J);E()}}function E(){if(e){return }if(h.ie&&h.win){var v=a("span");try{var u=K.getElementsByTagName("body")[0].appendChild(v);u.parentNode.removeChild(u)}catch(w){return }}e=true;if(Z){clearInterval(Z);Z=null}var q=o.length;for(var r=0;r<q;r++){o[r]()}}function f(q){if(e){q()}else{o[o.length]=q}}function R(r){if(typeof j.addEventListener!=b){j.addEventListener("load",r,false)}else{if(typeof K.addEventListener!=b){K.addEventListener("load",r,false)}else{if(typeof j.attachEvent!=b){I(j,"onload",r)}else{if(typeof j.onload=="function"){var q=j.onload;j.onload=function(){q();r()}}else{j.onload=r}}}}}function H(){var t=N.length;for(var q=0;q<t;q++){var u=N[q].id;if(h.pv[0]>0){var r=C(u);if(r){N[q].width=r.getAttribute("width")?r.getAttribute("width"):"0";N[q].height=r.getAttribute("height")?r.getAttribute("height"):"0";if(c(N[q].swfVersion)){if(h.webkit&&h.webkit<312){Y(r)}W(u,true)}else{if(N[q].expressInstall&&!A&&c("6.0.65")&&(h.win||h.mac)){k(N[q])}else{O(r)}}}}else{W(u,true)}}}function Y(t){var q=t.getElementsByTagName(Q)[0];if(q){var w=a("embed"),y=q.attributes;if(y){var v=y.length;for(var u=0;u<v;u++){if(y[u].nodeName=="DATA"){w.setAttribute("src",y[u].nodeValue)}else{w.setAttribute(y[u].nodeName,y[u].nodeValue)}}}var x=q.childNodes;if(x){var z=x.length;for(var r=0;r<z;r++){if(x[r].nodeType==1&&x[r].nodeName=="PARAM"){w.setAttribute(x[r].getAttribute("name"),x[r].getAttribute("value"))}}}t.parentNode.replaceChild(w,t)}}function k(w){A=true;var u=C(w.id);if(u){if(w.altContentId){var y=C(w.altContentId);if(y){M=y;l=w.altContentId}}else{M=G(u)}if(!(/%$/.test(w.width))&&parseInt(w.width,10)<310){w.width="310"}if(!(/%$/.test(w.height))&&parseInt(w.height,10)<137){w.height="137"}K.title=K.title.slice(0,47)+" - Flash Player Installation";var z=h.ie&&h.win?"ActiveX":"PlugIn",q=K.title,r="MMredirectURL="+j.location+"&MMplayerType="+z+"&MMdoctitle="+q,x=w.id;if(h.ie&&h.win&&u.readyState!=4){var t=a("div");x+="SWFObjectNew";t.setAttribute("id",x);u.parentNode.insertBefore(t,u);u.style.display="none";var v=function(){u.parentNode.removeChild(u)};I(j,"onload",v)}U({data:w.expressInstall,id:m,width:w.width,height:w.height},{flashvars:r},x)}}function O(t){if(h.ie&&h.win&&t.readyState!=4){var r=a("div");t.parentNode.insertBefore(r,t);r.parentNode.replaceChild(G(t),r);t.style.display="none";var q=function(){t.parentNode.removeChild(t)};I(j,"onload",q)}else{t.parentNode.replaceChild(G(t),t)}}function G(v){var u=a("div");if(h.win&&h.ie){u.innerHTML=v.innerHTML}else{var r=v.getElementsByTagName(Q)[0];if(r){var w=r.childNodes;if(w){var q=w.length;for(var t=0;t<q;t++){if(!(w[t].nodeType==1&&w[t].nodeName=="PARAM")&&!(w[t].nodeType==8)){u.appendChild(w[t].cloneNode(true))}}}}}return u}function U(AG,AE,t){var q,v=C(t);if(v){if(typeof AG.id==b){AG.id=t}if(h.ie&&h.win){var AF="";for(var AB in AG){if(AG[AB]!=Object.prototype[AB]){if(AB.toLowerCase()=="data"){AE.movie=AG[AB]}else{if(AB.toLowerCase()=="styleclass"){AF+=' class="'+AG[AB]+'"'}else{if(AB.toLowerCase()!="classid"){AF+=" "+AB+'="'+AG[AB]+'"'}}}}}var AD="";for(var AA in AE){if(AE[AA]!=Object.prototype[AA]){AD+='<param name="'+AA+'" value="'+AE[AA]+'" />'}}v.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+AF+">"+AD+"</object>";i[i.length]=AG.id;q=C(AG.id)}else{if(h.webkit&&h.webkit<312){var AC=a("embed");AC.setAttribute("type",P);for(var z in AG){if(AG[z]!=Object.prototype[z]){if(z.toLowerCase()=="data"){AC.setAttribute("src",AG[z])}else{if(z.toLowerCase()=="styleclass"){AC.setAttribute("class",AG[z])}else{if(z.toLowerCase()!="classid"){AC.setAttribute(z,AG[z])}}}}}for(var y in AE){if(AE[y]!=Object.prototype[y]){if(y.toLowerCase()!="movie"){AC.setAttribute(y,AE[y])}}}v.parentNode.replaceChild(AC,v);q=AC}else{var u=a(Q);u.setAttribute("type",P);for(var x in AG){if(AG[x]!=Object.prototype[x]){if(x.toLowerCase()=="styleclass"){u.setAttribute("class",AG[x])}else{if(x.toLowerCase()!="classid"){u.setAttribute(x,AG[x])}}}}for(var w in AE){if(AE[w]!=Object.prototype[w]&&w.toLowerCase()!="movie"){F(u,w,AE[w])}}v.parentNode.replaceChild(u,v);q=u}}}return q}function F(t,q,r){var u=a("param");u.setAttribute("name",q);u.setAttribute("value",r);t.appendChild(u)}function X(r){var q=C(r);if(q&&(q.nodeName=="OBJECT"||q.nodeName=="EMBED")){if(h.ie&&h.win){if(q.readyState==4){B(r)}else{j.attachEvent("onload",function(){B(r)})}}else{q.parentNode.removeChild(q)}}}function B(t){var r=C(t);if(r){for(var q in r){if(typeof r[q]=="function"){r[q]=null}}r.parentNode.removeChild(r)}}function C(t){var q=null;try{q=K.getElementById(t)}catch(r){}return q}function a(q){return K.createElement(q)}function I(t,q,r){t.attachEvent(q,r);d[d.length]=[t,q,r]}function c(t){var r=h.pv,q=t.split(".");q[0]=parseInt(q[0],10);q[1]=parseInt(q[1],10)||0;q[2]=parseInt(q[2],10)||0;return(r[0]>q[0]||(r[0]==q[0]&&r[1]>q[1])||(r[0]==q[0]&&r[1]==q[1]&&r[2]>=q[2]))?true:false}function V(v,r){if(h.ie&&h.mac){return }var u=K.getElementsByTagName("head")[0],t=a("style");t.setAttribute("type","text/css");t.setAttribute("media","screen");if(!(h.ie&&h.win)&&typeof K.createTextNode!=b){t.appendChild(K.createTextNode(v+" {"+r+"}"))}u.appendChild(t);if(h.ie&&h.win&&typeof K.styleSheets!=b&&K.styleSheets.length>0){var q=K.styleSheets[K.styleSheets.length-1];if(typeof q.addRule==Q){q.addRule(v,r)}}}function W(t,q){var r=q?"visible":"hidden";if(e&&C(t)){C(t).style.visibility=r}else{V("#"+t,"visibility:"+r)}}function g(s){var r=/[\\\"<>\.;]/;var q=r.exec(s)!=null;return q?encodeURIComponent(s):s}var D=function(){if(h.ie&&h.win){window.attachEvent("onunload",function(){var w=d.length;for(var v=0;v<w;v++){d[v][0].detachEvent(d[v][1],d[v][2])}var t=i.length;for(var u=0;u<t;u++){X(i[u])}for(var r in h){h[r]=null}h=null;for(var q in swfobject){swfobject[q]=null}swfobject=null})}}();return{registerObject:function(u,q,t){if(!h.w3cdom||!u||!q){return }var r={};r.id=u;r.swfVersion=q;r.expressInstall=t?t:false;N[N.length]=r;W(u,false)},getObjectById:function(v){var q=null;if(h.w3cdom){var t=C(v);if(t){var u=t.getElementsByTagName(Q)[0];if(!u||(u&&typeof t.SetVariable!=b)){q=t}else{if(typeof u.SetVariable!=b){q=u}}}}return q},embedSWF:function(x,AE,AB,AD,q,w,r,z,AC){if(!h.w3cdom||!x||!AE||!AB||!AD||!q){return }AB+="";AD+="";if(c(q)){W(AE,false);var AA={};if(AC&&typeof AC===Q){for(var v in AC){if(AC[v]!=Object.prototype[v]){AA[v]=AC[v]}}}AA.data=x;AA.width=AB;AA.height=AD;var y={};if(z&&typeof z===Q){for(var u in z){if(z[u]!=Object.prototype[u]){y[u]=z[u]}}}if(r&&typeof r===Q){for(var t in r){if(r[t]!=Object.prototype[t]){if(typeof y.flashvars!=b){y.flashvars+="&"+t+"="+r[t]}else{y.flashvars=t+"="+r[t]}}}}f(function(){U(AA,y,AE);if(AA.id==AE){W(AE,true)}})}else{if(w&&!A&&c("6.0.65")&&(h.win||h.mac)){A=true;W(AE,false);f(function(){var AF={};AF.id=AF.altContentId=AE;AF.width=AB;AF.height=AD;AF.expressInstall=w;k(AF)})}}},getFlashPlayerVersion:function(){return{major:h.pv[0],minor:h.pv[1],release:h.pv[2]}},hasFlashPlayerVersion:c,createSWF:function(t,r,q){if(h.w3cdom){return U(t,r,q)}else{return undefined}},removeSWF:function(q){if(h.w3cdom){X(q)}},createCSS:function(r,q){if(h.w3cdom){V(r,q)}},addDomLoadEvent:f,addLoadEvent:R,getQueryParamValue:function(v){var u=K.location.search||K.location.hash;if(v==null){return g(u)}if(u){var t=u.substring(1).split("&");for(var r=0;r<t.length;r++){if(t[r].substring(0,t[r].indexOf("="))==v){return g(t[r].substring((t[r].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(A&&M){var q=C(m);if(q){q.parentNode.replaceChild(M,q);if(l){W(l,true);if(h.ie&&h.win){M.style.display="block"}}M=null;l=null;A=false}}}}}();

/*
 *	textarearesizer.js
 *	
 *	Prototype port of the jQuery TextAreaResizer 
 *	Created on 14th November 2008 by Sam Burney <sburney@sifnt.net.au>
 *	Version 0.1
 *
 *	More info: http://samburney.com/blog/text-area-resizer-prototype-port
 *	Demo: http://stmarys.sifnt.net.au/~sam/textarearesizer/
 *	Original version: http://plugins.jquery.com/project/TextAreaResizer
 */

function TextAreaResizer(id, options){
	this.textarea = id;
	this.staticOffset;
	this.iLastMousePos = 0;
	this.iMin = 32;
	this.grip;
	this.options = options;
	
	this.init();
}

TextAreaResizer.prototype.init = function(){
		this.textarea.addClassName('processed')
		this.staticOffset = null;

		var span = new Element('span');
		Element.wrap(this.textarea, span);
		span.wrap(new Element('div', {'class': 'resizable-textarea'}));
		
		var grippie = new Element('div', {'class': 'grippie'});
		span.parentNode.insert(grippie);
		grippie.style.marginRight = (grippie.getWidth() - this.textarea.getWidth()) +'px';
		
		Event.observe(grippie, 'mousedown', this.startDrag.bindAsEventListener(this));
}

TextAreaResizer.prototype.startDrag = function(event){
	var data = $A(arguments);
	data.shift();
	
	this.textarea = $(Event.element(event)).previous().firstDescendant();
	
	this.iLastMousePos = event.pointerY();
	this.staticOffset = this.textarea.getHeight() - this.iLastMousePos;
	this.textarea.setStyle({'opacity': 0.25});
	
	Event.observe(document, 'mousemove', this.performDrag.bindAsEventListener(this));
	Event.observe(document, 'mouseup', this.endDrag.bindAsEventListener(this));
	
	return false;
}

TextAreaResizer.prototype.performDrag = function(event){
	var data = $A(arguments);
	data.shift();

	var iThisMousePos = event.pointerY();
	var iMousePos = this.staticOffset + iThisMousePos;
	if(this.iLastMousePos >= (iThisMousePos)){
		iMousePos -= 5;
	}
	this.iLastMousePos = iThisMousePos;
	iMousePos = Math.max(this.iMin, iMousePos);
	this.textarea.setStyle({height: iMousePos + 'px'});
	if(iMousePos < this.iMin){
		this.endDrag(event);
	}

	return false;
}

TextAreaResizer.prototype.endDrag = function(event){
	var data = $A(arguments);
	data.shift();

	Event.stopObserving(document, 'mousemove');
	Event.stopObserving(document, 'mouseup');
	
	this.textarea.setStyle({'opacity': 1});
	this.textarea.focus();
	this.staticOffset = null;
	this.textarea = null;
	this.iLastMousePos = 0;

	if(this.options){
		if(this.options.afterDrag){
			this.options.afterDrag();
		}
	}
}


Groups = {
  validateGroupName: function(errors) {
    if ($('group_name')) {
      Validation.validatePresence(errors, 'group_name', 'group_name', 'group_name_empty');
      Validation.validateMinLength(errors, 'group_name', 'group_name', 3, 'group_name_minlength');
      Validation.validateMaxLength(errors, 'group_name', 'group_name', 60, 'group_name_maxlength');
    }
  },

  validatePermalink: function(errors) {
    if ($('group_permalink')) {
      Validation.validateMinLength(errors, 'group_permalink', 'group_permalink', 3, 'group_url_minlength');
      Validation.validateMaxLength(errors, 'group_permalink', 'group_permalink', 60, 'group_url_maxlength');
      Validation.validateFormat(errors, 'group_permalink', 'group_permalink', /^[a-zA-Z0-9][a-zA-Z0-9\-_\+]+[a-zA-Z0-9]$/, 'group_url_invalid');
    }
  },

  validateDescription: function(errors) {
    if ($('group_description')) {
      Validation.validateMaxLength(errors, 'group_description', 'group_description', 1000, 'group_description_maxlength');
    }
  },

  validateCategory: function(errors) {
    if ($('group_category_id_1')) {
      Validation.validatePresence(errors, 'group_category', 'group_category_id_1', 'group_category_empty');
    }
  },

  validateWebsite: function(errors) {
    if ($('group_website')) {
      Validation.validateMaxLength(errors, 'group_website', 'group_website', 200, 'group_website_maxlength');
    }
  },

  validateTags: function(errors) {
    if ($('group_initial_tags')) {
      Validation.validatePresence(errors, 'group_initial_tags', 'group_initial_tags', 'group_tags_empty');
      Validation.validateMaxLength(errors, 'group_initial_tags', 'group_initial_tags', 100, 'group_tags_maxlength');
    }
  },

  alertAndJumpToFirstError: function() {
    var firstErrorFieldWrapper, firstErrorInput;

    alert(ValidationErrors.localizations.get('base') || 'Fehler: Eingaben inkorrekt.');
    if (firstErrorFieldWrapper = $$(' .multi.form_error').first()) {
      firstErrorFieldWrapper.scrollTo();
      if (firstErrorInput = firstErrorFieldWrapper.select('select', 'textarea', 'input').first()) {
        firstErrorInput.activate();
      }
    }
  },

  checkGroupName: function(url) {
    var errors = new ValidationErrors();
    var field = $('group_name');

    Validation.clearDisplayedError('group_name');
    Groups.validateGroupName(errors);

    if (errors.any()) {
      Validation.displayErrors(errors);
      field.activate();

      return false;
    }

    new Ajax.Request(url, {
      method: 'get',
      parameters: 'v=' + encodeURIComponent(field.value),
      onSuccess: function(xhr) { alert(xhr.responseText); }
    });
  },

  checkPermalink: function(url) {
    var errors = new ValidationErrors();
    var field = $('group_permalink');

    Validation.clearDisplayedError('group_permalink');
    Groups.validatePermalink(errors);

    if (errors.any()) {
      Validation.displayErrors(errors);
      field.activate();

      return false;
    }

    new Ajax.Request(url, {
      method: 'get', 
      parameters: 'v=' + encodeURIComponent(field.value),
      onSuccess: function(xhr) { alert(xhr.responseText); }
    });
  }
};

Groups.toggleReceivedInvitationBody = function(id, path, authenticityToken) {
  var body    = $('group_membership_invitation_' + id + '_body');
  var subject = $('group_membership_invitation_' + id + '_subject');

  if (body.hasClassName('visible')) {
    Effect.SlideUp(body, { duration: 0.25, afterFinish: function() {
      body.removeClassName('visible');
      subject.removeClassName('up');
    }});
  }
  else {
    Effect.SlideDown(body, { duration: 0.25, afterFinish: function() {
      body.addClassName('visible');
      subject.addClassName('up');
    }});
  }

  if (body.hasClassName('unseen')) {
    var ar = new Ajax.Request(path, { parameters: 'authenticity_token=' + encodeURIComponent(authenticityToken), method: 'put', asynchronous: true, evalScripts: true });

    body.removeClassName('unseen');
    $('group_membership_invitation_' + id + '_new_icon').hide();
  }
};

Groups.toggleReceivedRequestBody = function(id, authenticityToken) {
  var body    = $('group_membership_request_' + id + '_body');
  var subject = $('group_membership_request_' + id + '_subject');
  
  if (body.hasClassName('visible')) {
    Effect.SlideUp(body, { duration: 0.25, afterFinish: function() {
      body.removeClassName('visible');
      subject.removeClassName('up');
    }});
  }
  else {
    Effect.SlideDown(body, { duration: 0.25, afterFinish: function() {
      body.addClassName('visible');
      subject.addClassName('up');
    }});
  }
};

Groups.toggleSentRequestBody = function(id, authenticityToken) {
  var body    = $('group_membership_request_' + id + '_body');
  var subject = $('group_membership_request_' + id + '_subject');
  
  if (body.hasClassName('visible')) {
    Effect.SlideUp(body, { duration: 0.25, afterFinish: function() {
      body.removeClassName('visible');
      subject.removeClassName('up');
    }});
  }
  else {
    Effect.SlideDown(body, { duration: 0.25, afterFinish: function() {
      body.addClassName('visible');
      subject.addClassName('up');
    }});
  }
};

Groups.toggleSentInvitationBody = function(id, authenticityToken) {
  var body    = $('group_membership_invitation_' + id + '_body');
  var subject = $('group_membership_invitation_' + id + '_subject');
  
  if (body.hasClassName('visible')) {
    Effect.SlideUp(body, { duration: 0.25, afterFinish: function() {
      body.removeClassName('visible');
      subject.removeClassName('up');
    }});
  }
  else {
    Effect.SlideDown(body, { duration: 0.25, afterFinish: function() {
      body.addClassName('visible');
      subject.addClassName('up');
    }});
  }
};

Groups.isCreateInvitationFormValid = function() {
  var receiver_name = $F('group_membership_invitation_receiver_name').strip();
  
  if (receiver_name.blank()) {
    alert(error_invitation_receiver_name_empty);
    $('group_membership_invitation_receiver_name').focus();
    return false;
  }
  
  $('group_membership_invitation_receiver_name').value = receiver_name;
  $('group_membership_invitation_message').value = $F('group_membership_invitation_message').strip();
  
  return true;
};

Groups.isHighslideCreateInvitationFormValid = function(groupId) {
  var receiver_name = $F('group_' + groupId + '_receiver_name').strip();
  
  if (receiver_name.blank()) {
    alert(error_invitation_receiver_name_empty);
    $('group_' + groupId + '_receiver_name').focus();
    return false;
  }
  
  $('group_' + groupId + '_receiver_name').value = receiver_name;
  $('group_' + groupId + '_message').value = $F('group_' + groupId + '_message').strip();
  
  return true;
};

Groups.resetCreateInvitationFormInputFields = function() {
  $('group_membership_invitation_receiver_name').value = '';
  $('group_membership_invitation_message').value = '';
  
  $('group_membership_invitation_receiver_name').focus();
};

Groups.isMembershipMemberFormValid = function(btn, groupId, leaveConfirmText) {
  if ($('group_' + groupId + '_mode_keep').checked) { 
    hs.close(btn); 
    return false; 
  }
  else if ($('group_' + groupId + '_mode_invite') && $('group_' + groupId + '_mode_invite').checked) { 
    return this.isHighslideCreateInvitationFormValid(groupId);
  }
  else if ($('group_' + groupId + '_mode_leave').checked) { 
    return confirm(leaveConfirmText);
  }
  
  return true;
};

Groups.toggleFilterTabs = function(tabLink) {
  Element.extend(tabLink);
  
  if (tabLink.blur) {
    tabLink.blur();
  }
  
  var tabs = $$('.filter_tab');
  var tabContents = $$('.filter_tab_content');
  
  for (var i = 0, size = tabs.length; i < size; ++i) {
    tabs[i].removeClassName('live_form_tab');
    tabContents[i].addClassName('hidden_form_tab');
  }
  
  var activateTabId = tabLink.up().id;
  
  $(activateTabId).addClassName('live_form_tab');
  $(activateTabId + '_content').removeClassName('hidden_form_tab');
};

Groups.toggleMembershipBody = function(id, authenticityToken) {
  var body    = $('membership_' + id + '_body');
  var subject = $('membership_' + id + '_subject');
  
  if (body.hasClassName('visible')) {
    Effect.SlideUp(body, { duration: 0.25, afterFinish: function() {
      body.removeClassName('visible');
      subject.removeClassName('up');
    }});
  }
  else {
    Effect.SlideDown(body, { duration: 0.25, afterFinish: function() {
      body.addClassName('visible');
      subject.addClassName('up');
    }});
  }
};

Groups.isCreateFormValid = function() {
  var errors = new ValidationErrors();
  Validation.clearDisplayedErrors();

  Groups.validateGroupName(errors);
  Groups.validatePermalink(errors);
  Groups.validateDescription(errors);
  Groups.validateCategory(errors);
  Groups.validateWebsite(errors);
  Groups.validateTags(errors);

  if (errors.any()) {
    Validation.displayErrors(errors);
    Groups.alertAndJumpToFirstError();
    return false;
  }

  $('group_name').value = $F('group_name').strip();
  $('group_permalink').value = $F('group_permalink').strip();
  $('group_description').value = $F('group_description').strip();
  $('group_website').value = $F('group_website').strip();
  $('group_initial_tags').value = $F('group_initial_tags').strip();
  
  return true;
};

Groups.isEditFormValid = function() {
  var errors = new ValidationErrors();
  Validation.clearDisplayedErrors();

  Groups.validateDescription(errors);
  Groups.validateCategory(errors);
  Groups.validateWebsite(errors);

  if (errors.any()) {
    Validation.displayErrors(errors);
    Groups.alertAndJumpToFirstError();
    return false;
  }

  $('group_description').value = $F('group_description').strip();
  $('group_website').value = $F('group_website').strip();
  
  return true;
};

Groups.transliterate = function(str) {
  str = str.replace(/À|Á|Â|Ã|Å/g, 'A');
  str = str.replace(/Ä|Æ/g, 'Ae');
  str = str.replace(/Ç/g, 'C');
  str = str.replace(/Ð/g, 'D');
  str = str.replace(/È|É|Ê|Ë/g, 'E');
  str = str.replace(/Ì|Í|Î|Ï/g, 'I');
  str = str.replace(/Ñ/g, 'N');
  str = str.replace(/Ò|Ó|Ô|Õ|Ø/g, 'O');
  str = str.replace(/Ö/g, 'Oe');
  str = str.replace(/Ù|Ú|Û/g, 'U');
  str = str.replace(/Ü/g, 'Ue');
  str = str.replace(/Ý/g, 'Y');
  str = str.replace(/Þ/g, 'p');
  str = str.replace(/à|á|â|ã|å/g, 'a');
  str = str.replace(/ä|æ/g, 'ae');
  str = str.replace(/ç/g, 'c');
  str = str.replace(/ð/g, 'd');
  str = str.replace(/è|é|ê|ë/g, 'e');
  str = str.replace(/ì|í|î|ï/g, 'i');
  str = str.replace(/ñ/g, 'n');
  str = str.replace(/ò|ó|ô|õ|ø/g, 'o');
  str = str.replace(/ö/g, 'oe');
  str = str.replace(/ß/g, 'ss');
  str = str.replace(/ù|ú|û/g, 'u');
  str = str.replace(/ü/g, 'ue');
  str = str.replace(/ý/g, 'y');
  str = str.replace(/[^\x00-\x7F]+/g, '');
  
  return str;
};

Groups.updatePermalinkField = function(name) {
  var str = this.transliterate(name);
  
  str = str.replace(/[^a-zA-Z0-9\-_\+]+/g, '-');
  str = str.replace(/\-\-+/g, '-');
  str = str.replace(/^\-|\-$/g, '');
  
  $('group_permalink').value = str;
};

Groups.openDetailSearch = function() {
  $('d').value = '1';
  
  $('detail_search').slideDown({
    afterFinish: function() {
      $('anchor_open_detail_search').hide();
      $('anchor_close_detail_search').show();
    }, duration: 0.4});
};

Groups.closeDetailSearch = function() {
  $('d').value = '';
  
  $('detail_search').slideUp({
    afterFinish: function() {
      $('anchor_close_detail_search').hide();
      $('anchor_open_detail_search').show();
    }, duration: 0.4});
};

Groups.updateMembersCount = function(groupId, membersCount) {
  if ($('group_' + groupId + '_members_count')) {
    $('group_' + groupId + '_members_count').innerHTML = membersCount;
  }
};

Groups.daysInFebruary = function(year) {
  // February has 29 days in any year evenly divisible by four,
  // EXCEPT for centurial years which are not also divisible by 400.
  return (((year % 4 === 0) && ((!(year % 100 === 0)) || (year % 400 === 0))) ? 29 : 28);
};

Groups.isDate = function(year, month, day){
  var daysInMonth = [31, this.daysInFebruary(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

  return day <= daysInMonth[month - 1];
};

Groups.leadingZeroOnSingleDigits = function(number) {
  return (number > 9 ? '' : '0') + number;
};

Groups.isAnnouncementFormValid = function(counter) {
  if ($F('title_' + counter).blank()) {
    alert(error_group_announcement_title_empty);
    $('title_' + counter).focus();
    return false;
  }
  
  if ($F('title_' + counter).length > 100) {
    alert(error_group_announcement_title_maxlength);
    $('title_' + counter).focus();
    return false;
  }
  
  var descriptionField = $('description_' + counter);
  var disposalValue = descriptionField.retrieve('disposalValue');
  
  if (disposalValue && descriptionField.value.strip() == disposalValue) {
    descriptionField.clear();
  }
  
  if ($F('description_' + counter).blank()) {
    alert(error_group_announcement_description_empty);
    $('description_' + counter).focus();
    return false;
  }

  var starts_on_day   = parseInt($F('starts_on_' + counter + '_3i'), 10);
  var starts_on_month = parseInt($F('starts_on_' + counter + '_2i'), 10);
  var starts_on_year  = parseInt($F('starts_on_' + counter + '_1i'), 10);

  if (!this.isDate(starts_on_year, starts_on_month, starts_on_day)) {
    alert(group_announcement_starts_on_invalid);
    $('starts_on_' + counter + '_3i').focus();
    return false;
  }

  var expires_on_day   = parseInt($F('expires_on_' + counter + '_3i'), 10);
  var expires_on_month = parseInt($F('expires_on_' + counter + '_2i'), 10);
  var expires_on_year  = parseInt($F('expires_on_' + counter + '_1i'), 10);

  if (!this.isDate(expires_on_year, expires_on_month, expires_on_day)) {
    alert(group_announcement_expires_on_invalid);
    $('expires_on_' + counter + '_3i').focus();
    return false;
  }
  
  var starts_on  = starts_on_year + this.leadingZeroOnSingleDigits(starts_on_month) + this.leadingZeroOnSingleDigits(starts_on_day);
  var expires_on = expires_on_year + this.leadingZeroOnSingleDigits(expires_on_month) + this.leadingZeroOnSingleDigits(expires_on_day);
  
  if (starts_on > expires_on) {
    alert(group_announcement_starts_on_after_expires_on);
    $('starts_on_' + counter + '_3i').focus();
    return false;
  }
  
  $('title_' + counter).value = $F('title_' + counter).strip();
  $('description_' + counter).value = $F('description_' + counter).strip();
  
  return true;
};

document.observe('dom:loaded', function() {  
  AppEvents.subscribe('group_deleted', function(id) {
    if ($('group_' + id)) {
      $('group_' + id).fade();
    }
  });
  
  AppEvents.subscribe('group_member_added', function(id, memberName, membersCount) {
    Groups.updateMembersCount(id, membersCount);
  });
  
  AppEvents.subscribe('group_member_removed', function(id, memberName, membersCount) {
    Groups.updateMembersCount(id, membersCount);
  });
});
