document.observe('dom:loaded', function(){
  $$('.handle').each(function(node){
    new HeaderMenu(node, node.id);
  });
	
  $$('#title .iconlink, #content .iconlink').each(function(node){
    if(node.parentNode.href) {
      new IconMenu(node, node.parentNode.href + "/iconmenu");
    }
  });
  
  contactForm       = new ContactForm;
  logoFaceBox       = new LogoFaceBox;  
  largeDescription  = new LargeDescription('description_span', 400);
  
  if($('recentlyticker')) 
    new RecentlyTicker('recentlyticker');
});



// Cookie handler, by Peter-Paul Koch - http://www.quirksmode.org
var Cookie = {
  set: function(name, value) {
    var expires = '', options = arguments[2] || {};
    if (options.duration) {
      var date = new Date();
      date.setTime(date.getTime() + options.duration * 1000 * 60 * 60 * 24);
      value += '; expires=' + date.toGMTString();
    }
    document.cookie = name + "=" + value + expires + "; path=/";
  },

  remove: function(name) { this.set(name, '', -1) },

  get: function(name) {
    var cookies = document.cookie.split(';'), nameEQ = name + "=";
    for (var i = 0, l = cookies.length; i < l; i++) {
      var c = cookies[i];
      while (c.charAt(0) == ' ')
        c = c.substring(1,c.length);
      if (c.indexOf(nameEQ) == 0)
        return c.substring(nameEQ.length, c.length);
    }
    return null;
  }
};



// When right-click on logo, show a print-friendly logo in a facebox
var LogoFaceBox = Class.create({
  initialize: function() {
    this.logoWasClosed = false;
    
    if($('logo')) {
  	  $('logo').oncontextmenu = this.showLogoBox.bindAsEventListener(this);
  	  $('facebox_close').onclick = this.closeLogoBox.bindAsEventListener(this);
  	}
  },
  
  showLogoBox: function() {
  	if (!this.logoWasClosed) {
      $('facebox_logo').show();
  		return false;
  	}
  },
  
  closeLogoBox: function() {
  	$('facebox_logo').hide(); 	
  	this.logoWasClosed = true;
  	return false;
  }
});



// Contact form via feedback button
var ContactForm = Class.create({  
  initialize: function() {
    this.shown = false;
    
    if($('contact_button')) {
      $('contact_button').observe('click', this.toggle.bindAsEventListener(this));
    }
  },
  
  toggle: function(event) {
    if(this.shown) {
      this.close();
      this.shown = false;
    } else {
      this.open();
      this.shown = true;
    }
    Event.stop(event);
  },
  
  focus: function() {
    function focusIt() {
       $('help_description').focus();
       $('help_agent').value = navigator.userAgent;
     }
     setTimeout(this.focus, 300);
  },
  
  reload: function() {
    new Ajax.Updater('contact_form', '/help', { 
       asynchronous: true, 
       evalScripts: true, 
       onComplete: function(request) {
         this.focus();         
       }
     });
  },
  
  open: function() {    
     new Effect.Morph('contact_form', {style: 'margin-left:0', duration: 0.3});
     this.focus();
  },
  
  close: function() {
    new Effect.Morph('contact_form', {style: 'margin-left:-300px', duration: 0.3});
  }
});



// Submit button disable on click
function showSubmit(element) {
	element.addClassName("submitted_button");
}
function activateSubmit(element) {
	element.disabled = false;
	element.removeClassName("submitted_button");
}



// Truncate the description on a software profile
var LargeDescription = Class.create({
  initialize: function(id, max_chars) {
    this.elm = $(id);
    if(!this.elm) {return;}
    if(this.elm.innerHTML.length < max_chars) {
      this.elm.innerHTML = this.elm.innerHTML.stripTags();
      return;
    }
    
    this.large_text = this.elm.innerHTML;
    this.small_text = this.large_text.substring(0, max_chars);
    this.small_text = this.small_text.substring(0, this.small_text.lastIndexOf(' ')) + ' &hellip;';
    this.small_text = this.small_text.stripTags();
    
    this.elm.innerHTML = '<span id="' + id + '_span"></span> <a id="' + id + '_link" href="#more">More</a>';
    this.span = $(id + '_span');
    this.link = $(id + '_link');
    
    this.span.innerHTML = this.small_text;
    this.link.onclick = this.toggle.bindAsEventListener(this);
    
    this.isFull = false;
  },
  
  toggle: function() {
    this.span.innerHTML = (this.isFull) ? this.small_text: this.large_text;
    this.link.innerHTML = (this.isFull) ? 'More' : 'Less';
    
    this.isFull = !this.isFull;
    return false;
  }
});



// Search software in AJAX box
var search_running = false;

function searchSoftware(search_url) {
	var search_query = $F('search_query');
	
	if (!search_running && search_query.length >= 3) {
		new Ajax.Request(search_url, {method:'post', postBody:'query=' + escape(search_query),
		 									 onLoading: function() { $('spinner').show(); search_running = true; },
											 onComplete: function() { search_running = false; $('spinner').hide(); },
											 onSuccess: function(t) { $('search_hits').innerHTML = t.responseText || "Nothing found :("; }
											 });
	} else {
		$('search_hits').innerHTML = "";
	}
}

function observePicker(search_url, field_id) {
	search_query = $F(field_id + "_input");
	search_hits = $(field_id +'_hits');
	spinner = $(field_id + '_spinner');
	
	if (!search_running && search_query.length >= 3) {
		new Ajax.Request(search_url, {method:'post', postBody:'query=' + escape(search_query),
		 									 onLoading: function() { spinner.show(); search_running = true; },
											 onComplete: function() { search_running = false; spinner.hide(); search_hits.show(); },
											 onSuccess: function(t) { search_hits.innerHTML = t.responseText || "Nothing found :("; }
											 });
	} else {
		search_hits.hide();
		search_hits.innerHTML = "";
	}
}

function setApp(el, item_id, field_id, item_shortcut) {
	if(field = $(field_id)) {
		$(field_id + "_hits").innerHTML = field.innerHTML;
		field.innerHTML = "<span>" + el.innerHTML + "<input type=\"hidden\" name=\"split[similar_software_id]\" value=\"" + item_id + "\" /></span>";
		field.innerHTML += " - <a href=\"#developers\" onclick=\"setPicker('" + field_id + "')\">change</a>";  
	}
	$(field_id + "_hits").hide();
	
	// Update preview + c/p code, but only when you're on the widget page (kinda dirty check, I know)
	if($('devbadge_code')) {
	  setDevWidget(item_shortcut);
	}
}

function setPicker(field_id) {
	if(field = $(field_id)) {
		field.innerHTML = $(field_id + "_hits").innerHTML;
		$(field_id + "_input").className = "greyed";
		$(field_id + "_hits").innerHTML = "";
		new Form.Element.Observer(field_id + '_input', 1, function(element, value) {
		  observePicker('/search/autocomplete?field_id=' + field_id, field_id)
		});
	}
}

function setBlockStatus(id, status) {
	var spinner_name = "usage_spinner_" + id;
	var usage_node = "usage_software_" + id;
	var block_options = "block_" + id;
	var unblock_options = "unblock_" + id;
	var flag_description = "flag_description_" + id;
	
	new Ajax.Request('/account/display_settings', {method:'post', postBody:'id=' + escape(id) + "&display_flag=" + escape(status),
    onLoading: function() { $(spinner_name).show(); },
	  onSuccess: function(t) {
  	  if (status == -1) {
				$(spinner_name).hide();
				$(usage_node).remove();
				if ($('currently_blocked').childNodes.length <= 1) {
					$('none_blocked').show();
				}
			} else {
				$(spinner_name).hide(); 
				$('none_blocked').hide();
				$(block_options).hide();
				$(flag_description).innerHTML = t.responseText;
				$(unblock_options).show();
				$('currently_blocked').appendChild($(usage_node));
			}
		},
  	on403: function() { $(spinner_name).hide(); }
	 });
}

function setActiveSummaryLink(id) {
	$w('day_link week_link month_link').each(function(e) {
		$(e).removeClassName('active');
		if (id == e) {
			$(e).addClassName('active');
		}
	});
}

/*  Header Menu
 *  Copyright 2008 Robert Gaal - http://wakoopa.com
 *
 *  Displays a menu in the Wakoopa header
 *
 *  Dependencies:     prototype.js, global.sass
 *  Takes arguments:  node (element of handle), menu (ID of handle, appended with "menu" will show the correct uh... menu)
 *
 *--------------------------------------------------------------------------*/

var HeaderMenuOpen = null;
var HeaderMenu = Class.create({    
  initialize: function(node, menu) {
    this.node             = $(node);    
    this.menu             = $(menu == "os_link" ? "os_menu" : menu + "menu");
    this.link             = (menu == "os_link" ? $(menu) : $(menu + "link"));
    this.os_select_form   = $('os_select_form');
    this.search_input     = $('search_input');
    this.escEvent         = this.escape.bindAsEventListener(this);
    this.outEvent         = this.outside.bindAsEventListener(this);
    this.menuOpened       = false;
    this.effect           = false;
    
    this.node.observe('click', this.toggle.bindAsEventListener(this));
    this.os_select_form.onsubmit = this.filterPlatforms.bindAsEventListener(this);
    
    this.search_input.onfocus = this.clearInput.bindAsEventListener(this);
    this.search_input.onblur = this.setInput.bindAsEventListener(this);
    
    // Set a global variable to use z-index on multiple menu instances
    if (!window.HMZI)
      window.HMZI = 2;
  },
  
  toggle: function(event) {
    this.menu.style.zIndex = HMZI++;
    
    if(this.menuOpened) {
      this.close(event);
    } else {
      this.open(event);
    }
  },

  open: function(event) {
    // First, close all other menu's
    if(HeaderMenuOpen) {
      HeaderMenuOpen.close(event);
    }
    HeaderMenuOpen = this;
    
    new Effect.BlindDown(this.menu, {duration: .2});
    this.link.addClassName("opened");

    document.observe('click', this.outEvent);
    document.observe('keydown', this.escEvent);
  
    this.menuOpened = true;
    Event.stop(event);
  },
  
  close: function(event) {
    this.effect = new Effect.BlindUp(this.menu, {duration: .2,
      afterFinish: (function(node) {
        this.link.removeClassName('opened');
      }).bindAsEventListener(this)
    });
  
    document.stopObserving('click', this.outEvent);
    document.stopObserving('keydown', this.escEvent);
    
    this.menuOpened = false;
    element = Event.element(event);
    if(element.hasClassName("handle") || element.hasClassName("innerhandle")) {
      Event.stop(event);
    }
  },
  
  escape: function(event) { // when pushing escape the menu closes
    if(event.keyCode == 27) {
      this.close(event);
    }
  },
  
  outside: function(event) { // when clicking outside of the header the menu closes
    element = Event.element(event);
    if(!element.descendantOf('header')) {
      this.close(event);
    }
  },
  
  filterPlatforms: function() {
    os = '';
    $$('.os_select').each(function(node) {
      if(node.checked) {
        os += node.value + ',';
      }
    });
    document.location.href = '/platforms?os=' + os.slice(0, -1);
    return false;
  },
  
  clearInput: function() {
    if (!this.default_search_text)
      this.default_search_text = this.search_input.value;
    
    if (this.default_search_text == this.search_input.value)
  	  this.search_input.value = '';
  	
  	this.search_input.addClassName('focussed');
  },
  
  setInput: function() {
    if (this.search_input.value.length == 0 && this.default_search_text)
      this.search_input.value = this.default_search_text;
    
  	this.search_input.removeClassName('focussed');
  }
});

/*  Icon Menu, version 1.0
 *  By Robert Gaal - http://wakoopa.com
 *
 *  Displays a Flickr-like menu when hovering on an icon
 *
 *  Licensed under the MIT:
 *  http://www.opensource.org/licenses/mit-license.php
 *
 *  Dependencies:     prototype.js, iconmenu.sass
 *  Takes arguments:  node (<img> element of icon), ajaxURL (the url of the HTML loaded when folding out the menu)
 *
 *--------------------------------------------------------------------------*/

var iconMenuIndex = 1;
var iconMenuContents = [];
var IconMenu = Class.create({    
  initialize: function(node, ajaxURL) {
    this.node       = node;    
    this.ajaxURL    = ajaxURL || "iconmenu.html";
    this.image      = this.node.longDesc;
    this.closeEvent = this.close.bindAsEventListener(this);
    this.outEvent   = this.outside.bindAsEventListener(this);
    this.escEvent   = this.escape.bindAsEventListener(this);
    this.menuLink   = false;
    this.menuOpener = false;
    this.menu       = false;
    this.wrapper    = false;
    this.linkShown  = false;
    this.menuOpened = false;
    this.active     = false;
    this.timeout    = null;
    
    this.node.observe('mouseover', this.toggle.bindAsEventListener(this));
    this.node.observe('mouseout', this.toggle.bindAsEventListener(this));
  },
  
  /**
   * Toggle the menu link (slight delay to combat lacking mouseout's)
   */
  toggle: function(event) {
    var preload = new Image();
    preload.src = this.image;
    
    if(this.timeout) {
      this.timeout = clearTimeout(this.timeout);
    } else {
      this.timeout = setTimeout(this.show.bindAsEventListener(this), 300);
    }
  },
 
  /**
   * Show (and construct) the menu link
   */ 
  show: function(event) {
    clearTimeout(this.timeout);
    if(!this.linkShown) {
        if(!this.menuLink) { // To prevent creating and observing the menu link multiple times
        this.menuLink   = new Element('div', { 'class': 'iconmenu_link' });
        this.menuOpener = new Element('a', {'class': 'iconmenu_opener', 'href': this.node.parentNode.href});
        this.menuLink.appendChild(this.menuOpener);
        cloneIt(this.menuLink, this.node, {setWidth: false, setHeight: false});
    
        img   = new Element('img', {'src': this.image});       
        link  = new Element('a', {'class': 'iconmenu_img', 'href': this.node.parentNode.href});
        link.appendChild(img);
    
        link.wrap(this.menuLink);
        this.menuLink.hide();
        document.body.appendChild(this.menuLink);
        
        this.menuLink.observe('mouseout', this.hide.bindAsEventListener(this));
        this.menuOpener.observe('click', this.toggleMenu.bindAsEventListener(this));
      }
      document.observe('click', this.outEvent);
      document.observe('keydown', this.escEvent);
    
      this.menuLink.show();
      this.linkShown = true;
    }
  },
  
  /**
   * Hide the menu link (if you're hovering out of the menu(link) that is)
   */
  hide: function(event) {    
    if(this.linkShown) {
      // Check what element was hovered onto (fix for event bubbling)
      var relTarg = event.relatedTarget || event.toElement;
    
      if(relTarg && relTarg.className != "iconmenu_link" && relTarg.className != "iconmenu_opener" && !this.menuOpened) {
        this.menuLink.hide();
        this.linkShown = false;
  
        document.stopObserving('click', this.outEvent);
        document.stopObserving('keydown', this.escEvent);
      }
    }
  },
  
  /**
   * Open and close the menu
   */
  toggleMenu: function(event) {        
    if(this.menuOpened) {
      this.menu.style.display = "none";
      this.menuLink.removeClassName('opened');
      this.menuOpened = false;
    } else {
      // Build the menu
      if(!this.menu) {
        this.menu = new Element('div', { 'class': 'iconmenu' });  
        indicator = new Element('img', {'src': '/images/indicator_big.gif', 'id': 'indicator'});   
        this.menu.appendChild(indicator);
        cloneIt(this.menu, this.node, {setWidth: false, setHeight: false});
        if(iconMenuContents[this.ajaxURL]) {
          this.menu.update(iconMenuContents[this.ajaxURL]);
        } else {
          menu  = this.menu;
          url   = this.ajaxURL;
          new Ajax.Request(url, { 
            method: 'get', 
            evalScripts: true,
            onSuccess: function(request) {
              menu.update(request.responseText);
              iconMenuContents[url] = menu.innerHTML;
            }
          });
        }
      }
      this.menu.style.display = "";
      this.menuLink.insert({after: this.menu});
      this.menuLink.addClassName('opened');
      this.menuOpened = true;
      
      // Display the newest menu always on top of any old ones
      iconMenuIndex = iconMenuIndex + 2;
      this.menuLink.style.zIndex = iconMenuIndex;
      this.menu.style.zIndex = iconMenuIndex - 1;
    }
    Event.stop(event); // do not follow href
  },
  
  /**
   * Close up everything
   */
  close: function(event) {
    if(this.menu) {
      // Hide the menuLink
      this.menuLink.hide();
      this.linkShown = false;
      
      // Hide the menu
      this.menu.style.display = "none";
      this.menuLink.removeClassName('opened');
      this.menuOpened = false;
      
      document.stopObserving('click', this.outEvent);
      document.stopObserving('keydown', this.escEvent);
    }    
  },
  
  /**
   * When clicking outside of the menu it closes
   */
  outside: function(event) {
    element = Event.element(event);
    if(!element.descendantOf(this.menu)) {
      this.close(event);
    }
  },
  
  /**
   * When pushing escape the menu closes
   */
  escape: function(event) {
    if(event.keyCode == 27) {
      this.close(event);
    }
  }
});

// Taken from prototype.js
function cloneIt(element, source) {
  var options = Object.extend({
    setLeft:    true,
    setTop:     true,
    setWidth:   true,
    setHeight:  true,
    offsetTop:  0,
    offsetLeft: 0
  }, arguments[2] || { });

  // find page position of source
  source = $(source);
  var p = source.cumulativeOffset();

  // find coordinate system to use
  element = $(element);

  // set position
  if (options.setLeft)   element.style.left   = (p[0] + options.offsetLeft) + 'px';
  if (options.setTop)    element.style.top    = (p[1] + options.offsetTop) + 'px';
  if (options.setWidth)  element.style.width  = source.offsetWidth + 'px';
  if (options.setHeight) element.style.height = source.offsetHeight + 'px';
  return element;
}

/* Pushup
 * Copyright (c) 2008 Nick Stakenburg (www.nickstakenburg.com)
 *
 * License: MIT-style license.
 * Website: http://www.pushuptheweb.com
 *
 */

var Pushup = {
  Version: '1.0.1',
  options: {
    appearDelay: .5,
    fadeDelay: 6,
    images: '../images/pushup/',
    message: 'Important browser update available',
    reminder: {
      hours: 6,
      message: 'Remind me again in #{hours}'
    },
    skip: true
  },
  updateLinks: {
    IE: 'http://www.microsoft.com/windows/downloads/ie/',
    Firefox: 'http://www.getfirefox.com',
    Safari: 'http://www.apple.com/safari/download/',
    Opera: 'http://www.opera.com/download/'
  },
  Browser: {
    IE: !!(window.attachEvent &&
      navigator.userAgent.indexOf('Opera') === -1),
    Firefox: navigator.userAgent.indexOf('Firefox') > -1,
    Safari: navigator.userAgent.indexOf('AppleWebKit/') > -1 &&
      /Apple/.test(navigator.vendor),
    Opera: navigator.userAgent.indexOf('Opera') > -1
  }
};

Pushup.conditions = {
  IE: (function(agent) {
    var version = /MSIE ([\d.]+)/.exec(agent);
    return version && parseFloat(version[1]) < 7;
  })(navigator.userAgent),
  Firefox: Pushup.Browser.Firefox &&
    parseFloat(navigator.userAgent.match(/Firefox[\/\s](\d+)/)[1]) < 2,
  Safari: Pushup.Browser.Safari &&
    parseFloat(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) < 500,
  Opera: Pushup.Browser.Opera && (!window.opera.version ||
    parseFloat(window.opera.version()) < 9.25)
};

(function() {
// find current browser and check if it needs an update
for (var browser in Pushup.Browser)
  if (Pushup.Browser[browser]) Pushup._browserUsed = browser;
Pushup._updateBrowser = Pushup.conditions[Pushup._browserUsed] &&
  Pushup._browserUsed;

// stop if no update is required and we want to skip build
if (!Pushup._updateBrowser && Pushup.options.skip) return;

function Extend(destination, source) {
  for (var property in source)
    destination[property] = source[property];
  return destination;
}

Extend(Pushup, {
  start: function() {
    // get the image directory
    if (/^(https?:\/\/|\/)/.test(this.options.images))
      this.images = this.options.images;
    else {
      var srcMatch = /pushup(?:-[\w\d.]+)?\.js(.*)/,
       scripts = document.getElementsByTagName('script');
      for (var i = 0, l = scripts.length; i < l; i++) {
        var s = scripts[i];
        if (s.src && s.src.match(srcMatch))
          this.images = s.src.replace(srcMatch, '') + this.options.images;
      }
    }
    if (Pushup._updateBrowser) this.show();
  },

  build: function() {
    this.pushup = document.createElement('div');
    Opacity.set(this.pushup, 0);
    this.pushup.id = 'pushup';

    this.messageLink = this.pushup.appendChild(document.createElement('a'));
    this.messageLink.className = 'pushup_messageLink';
    this.messageLink.target = '_blank';

    this.messageLink.appendChild(this.icon = document.createElement('div'));
    this.icon.className = 'pushup_icon';

    this.messageLink.appendChild(this.message = document.createElement('span'));
    this.message.className = 'pushup_message';
    this.message.innerHTML = this.options.message;

    // reminder message if cookies are enabled
    var hours = this.options.reminder.hours;
    if (hours && Pushup.cookiesEnabled) {
      this.pushup.appendChild(this.reminder = document.createElement('a'));
      this.reminder.href = '#';
      this.reminder.className = 'pushup_reminder';
      this.pushup.className = 'withReminder';
      var H = hours + ' hour' + (hours > 1 ? 's' : ''),
       message = this.options.reminder.message.replace('#{hours}', H);
      this.reminder.innerHTML = message;
    }

    // Older Opera doesn't handle float correctly
    if (Pushup.conditions.Opera) {
      this.messageLink.style.cssFloat = 'none';
      this.reminder.style.cssFloat = 'none';
    }

    Pushup.setBrowser(Pushup._updateBrowser);
    document.body.appendChild(this.pushup);
    Pushup.addEvents();
  },

  addEvents: function() {
    if (this.reminder) {
      Event.add(this.reminder, 'click', function(event) {
        Event.stop(event);
        Pushup.setReminder(Pushup.options.reminder.hours);
        Pushup.fade();
      });
    }
    Event.add(this.pushup, 'mouseover', Pushup.clearFade);
    Event.add(this.pushup, 'mouseout', function() {
      Pushup.fade({ delay: Pushup.options.fadeDelay })
    });
  },

  setBrowser: function(browser) {
    browser = browser || 'IE';
    setPngBackground(this.icon, this.images + browser.toLowerCase() + '.png');
    this.messageLink.href = this.updateLinks[browser];
  },

  show: function() {
    // default to IE if no browser was detected
    var browser = typeof arguments[0] == 'string' ?
      arguments[0] : Pushup._browserUsed || 'IE',
     options = arguments[browser ? 1 : 0] || {};

    if (options.resetReminder) Pushup.resetReminder();

    // show if not blocked by cookie
    if (!options.ignoreReminder && Pushup.cookiesEnabled &&
      Cookie.get('_pushupBlocked')) return;

    if (!Pushup.pushup) Pushup.build();
    Opacity.set(Pushup.pushup, 0);
    Pushup.pushup.style.display = 'block';
    if (browser) Pushup.setBrowser(browser);
    this.appear({ fadeAfter: true, delay: Pushup.options.appearDelay });
  },

  appear: function(delay) {
    Pushup.clearFade();
    var options = arguments[0] || {};
    return window.setTimeout(function() {
      Appear(Pushup.pushup, { afterFinish: function() {
        if (options.fadeAfter)
          Pushup.fade({ delay: Pushup.options.fadeDelay });
      }});
    }, (options.delay || 0.01) * 1000);
  },

  clearFade: function() {
    if (Pushup._fadeTimer) {
      window.clearTimeout(Pushup._fadeTimer);
      Pushup._fadeTimer = null;
    }
  },

  fade: function() {
    var options = arguments[0] || {};
    Pushup._fadeTimer = window.setTimeout(function() {
      Fade(Pushup.pushup);
    }, (options.delay || 0.01) * 1000);
  },

  setReminder: function(hours) {
    Cookie.set('_pushupBlocked', 'blocked', { duration: 1 / 24 * hours })
  },

  resetReminder: function() { Cookie.remove('_pushupBlocked') }
});

// Opacity adapted from the Prototype JavaScript framework
// http://www.prototypejs.org
var Opacity = {
  set: function(element, value) {
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;
  },

  get:  function(element) {
    var opacity = element.style.opacity;
    return opacity ? parseFloat(opacity) : 1.0;
  }
};

if (Pushup.Browser.IE) {
  Opacity.get = function(element) {
    var opacity = element.style.opacity;
    if (!opacity && element.currentStyle) opacity = element.currentStyle[opacity];

    if (opacity = (element.style.filter || '').match(/alpha\(opacity=(.*)\)/))
      if (opacity[1]) return parseFloat(opacity[1]) / 100;
    return 1.0;
  };

  Opacity.set = function(element, value) {
    function stripAlpha(filter) {
      return filter.replace(/alpha\([^\)]*\)/gi,'')
    }
    var currentStyle = element.currentStyle;
    if ((currentStyle && !currentStyle.hasLayout) ||
      (!currentStyle && element.style.zoom == 'normal'))
        element.style.zoom = 1;
    var filter = element.style.filter,
     style = element.style;
    if (value == 1 || value === '') (filter = stripAlpha(filter)) ?
      style.filter = filter : style.filter = '';
    else style.filter = stripAlpha(filter) +
      'alpha(opacity=' + (value * 100) + ')';
  };
}

function Appear(element) {
  var current = Opacity.get(element),
   options = arguments[1] || {};
  if (element.style.display != 'block')
    element.style.display = 'block';
  if (current < 1) {
    setTimeout(function() {
      Opacity.set(element, current += 0.05);
      Appear(element, options);
    }, 0.01);
  }
  else {
    if (Pushup.Browser.IE && element.style.filter)
      element.style.removeAttribute('filter');
    if (options.afterFinish) options.afterFinish.call();
  }
}

function Fade(element) {
  var current = Opacity.get(element),
   options = arguments[1] || {};
  if (current > 0) {
    setTimeout(function() {
      Opacity.set(element, current -= 0.05);
      Fade(element, options);
    }, 0.01);
  }
  else {
    element.style.display = 'none';
    if (options.afterFinish) options.afterFinish.call();
  }
}

function setPngBackground(element, url) {
  var options = Extend({
    align: 'top left',
    repeat: 'no-repeat',
    sizingMethod: 'crop',
    backgroundColor: ''
  }, arguments[2] || {});

  Extend(element.style, arguments.callee.IEBelow7 ? {
    filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' +
      url + '\'\', sizingMethod=\'' + options.sizingMethod + '\')'
  } : {
    background: options.backgroundColor + ' url(' + url + ') ' +
      options.align + ' ' + options.repeat
  });
}
setPngBackground.IEBelow7 = Pushup.Browser.IE &&
  parseFloat(/MSIE ([\d.]+)/.exec(navigator.userAgent)[1]) < 7;

// Based on the work of Peter-Paul Koch - http://www.quirksmode.org
var Cookie = {
  set: function(name, value) {
    var expires = '', options = arguments[2] || {};
    if (options.duration) {
      var date = new Date();
      date.setTime(date.getTime() + options.duration * 1000 * 60 * 60 * 24);
      value += '; expires=' + date.toGMTString();
    }
    document.cookie = name + "=" + value + expires + "; path=/";
  },

  remove: function(name) { this.set(name, '', -1) },

  get: function(name) {
    var cookies = document.cookie.split(';'), nameEQ = name + "=";
    for (var i = 0, l = cookies.length; i < l; i++) {
      var c = cookies[i];
      while (c.charAt(0) == ' ')
        c = c.substring(1,c.length);
      if (c.indexOf(nameEQ) == 0)
        return c.substring(nameEQ.length, c.length);
    }
    return null;
  }
};

// check if cookies are enabled
Pushup.cookiesEnabled = (function(test) {
  if (Cookie.get(test)) return true;
  Cookie.set(test, 'test', { duration: 15 });
  return Cookie.get(test);
})('_pushupCookiesEnabled');

var Event = {
  add: function(obj, type, fn) {
    if (obj.attachEvent) {
      obj['e' + type + fn] = fn;
      obj[type + fn] = function(){ obj['e' + type +fn](window.event) };
      obj.attachEvent('on' + type, obj[type + fn]);
    }
    else obj.addEventListener(type, fn, false);
  },

  stop: function(event) {
    if (Pushup.Browser.IE) {
      event.cancelBubble = true;
      event.returnValue = false;
    }
    else {
      event.preventDefault();
      event.stopPropagation();
    }
  }
};

Event.add(window, 'load', function() { Pushup.start() });
})();

/*  Facebox for Prototype, version 2.0
 *  By Robert Gaal - http://wakoopa.com 
 *
 *  Heavily based on Facebox by Chris Wanstrath - http://famspam.com/facebox
 *  First ported to Prototype by Phil Burrows - http://blog.philburrows.com
 *
 *  Licensed under the MIT:
 *  http://www.opensource.org/licenses/mit-license.php
 *
 *  Dependencies:   prototype & script.aculo.us + images & CSS files from original facebox
 *  Usage:          Append 'rel="facebox"' to an element to call it inside a so-called facebox
 *
 *--------------------------------------------------------------------------*/

var Facebox = Class.create({
	initialize	: function(extra_set){
		this.settings = {
			loading_image	: '/images/facebox/loading.gif',
			close_image		: '/images/facebox/closelabel.gif',
			image_types		: new RegExp('\.' + ['png', 'jpg', 'jpeg', 'gif'].join('|') + '$', 'i'),
			inited				: true,	
			facebox_html	: '\
	  <div id="facebox" style="display:none;"> \
	    <div class="popup"> \
	      <table id="facebox_table"> \
	        <tbody> \
	          <tr> \
	            <td class="tl"/><td class="b"/><td class="tr"/> \
	          </tr> \
	          <tr> \
	            <td class="b"/> \
	            <td class="body"> \
	              <div class="content"> \
	              </div> \
	              <div class="footer"> \
	                <a href="#" class="close"> \
	                  <img src="/images/facebox/closelabel.gif" title="close" class="close_image" /> \
	                </a> \
	              </div> \
	            </td> \
	            <td class="b"/> \
	          </tr> \
	          <tr> \
	            <td class="bl"/><td class="b"/><td class="br"/> \
	          </tr> \
	        </tbody> \
	      </table> \
	    </div> \
	  </div>'
		};
		if (extra_set) Object.extend(this.settings, extra_set);
		$(document.body).insert({bottom: this.settings.facebox_html});
		
		this.preload = [ new Image(), new Image() ];
		this.preload[0].src = this.settings.close_image;
		this.preload[1].src = this.settings.loading_image;
		
		f = this;
		$$('#facebox .b:first, #facebox .bl, #facebox .br, #facebox .tl, #facebox .tr').each(function(elem){
			f.preload.push(new Image());
			f.preload.slice(-1).src = elem.getStyle('background-image').replace(/url\((.+)\)/, '$1');
		});
		
		this.facebox = $('facebox');
    this.keyPressListener = this.watchKeyPress.bindAsEventListener(this);
		
		this.watchClickEvents();
		fb = this;
		Event.observe($$('#facebox .close').first(), 'click', function(e){
			Event.stop(e);
			fb.close()
		});
		Event.observe($$('#facebox .close_image').first(), 'click', function(e){
			Event.stop(e);
			fb.close()
		});
	},
	
  watchKeyPress : function(e){
    // Close if espace is pressed or if there's a click outside of the facebox
    if (e.keyCode == 27 || !Event.element(e).descendantOf(this.facebox)) this.close();
  },
	
	watchClickEvents	: function(e){
		var f = this;
		$$('a[rel=facebox]').each(function(elem,i){
			Event.observe(elem, 'click', function(e){
				Event.stop(e);
				f.click_handler(elem, e);
			});
		});
	},
	
	loading	: function() {
		if ($$('#facebox .loading').length == 1) return true;
		
		contentWrapper = $$('#facebox .content').first();
		contentWrapper.childElements().each(function(elem, i){
			elem.remove();
		});
		contentWrapper.insert({bottom: '<div class="loading"><img src="'+this.settings.loading_image+'"/></div>'});
		
		var pageScroll = document.viewport.getScrollOffsets();
		this.facebox.setStyle({
			'top': pageScroll.top + (document.viewport.getHeight() / 10) + 'px',
			'left': document.viewport.getWidth() / 2 - (this.facebox.getWidth() / 2) + 'px'
		});
		
    Event.observe(document, 'keypress', this.keyPressListener);
    Event.observe(document, 'click', this.keyPressListener);
	},
	
	reveal	: function(data, klass){
		this.loading();
		load = $$('#facebox .loading').first();
		if(load) load.remove();
		
		contentWrapper = $$('#facebox .content').first();
		if (klass) contentWrapper.addClassName(klass);
		contentWrapper.insert({bottom: data});
		
    $$('#facebox .body').first().childElements().each(function(elem,i){
     elem.show();
    });
    		
		if(!this.facebox.visible()) new Effect.Appear(this.facebox, {duration: .3});
		this.facebox.setStyle({
			'left': document.viewport.getWidth() / 2 - (this.facebox.getWidth() / 2) + 'px'
		});
		
    Event.observe(document, 'keypress', this.keyPressListener);
    Event.observe(document, 'click', this.keyPressListener);
	},
	
	close		: function(){
		 new Effect.Fade('facebox', {duration: .3});
	},
	
	click_handler	: function(elem, e){
	  this.loading();
		Event.stop(e);
		
		// support for rel="facebox[.inline_popup]" syntax, to add a class
		var klass = elem.rel.match(/facebox\[\.(\w+)\]/);
		if (klass) klass = klass[1];
		
		new Effect.Appear(this.facebox, {duration: .3});
		
		if (elem.href.match(/#/)){
			var url			= window.location.href.split('#')[0];
			var target	= elem.href.replace(url+'#','');
			// var data			= $$(target).first();
			var d			  = $(target);
			// create a new element so as to not delete the original on close()
			var data = new Element(d.tagName);
			data.innerHTML = d.innerHTML;
			this.reveal(data, klass);
		} else if (elem.href.match(this.settings.image_types)) {
			var image = new Image();
			fb = this;
			image.onload = function() {
				fb.reveal('<div class="image"><img src="' + image.src + '" /></div>', klass)
			}
			image.src = elem.href;
		} else {
			var fb  = this;
			var url = elem.href;
			new Ajax.Request(url, {
				method		: 'get',
				onFailure	: function(transport){
					fb.reveal(transport.responseText, klass);
				},
				onSuccess	: function(transport){
					fb.reveal(transport.responseText, klass);
				}
			});
			
		}
	}
});

var facebox;
document.observe('dom:loaded', function(){
	facebox = new Facebox();
});


