var extractPath = function(url){  
  var segments = url.split('/');

  if(url.startsWith("http://"))
  {
    segments = segments.slice(3);
  }
  else{
    segments = segments.slice(1);
  }
  
  return segments.join('/');
};

var extractBase = function(url){
  var segments = url.split('/');

  if(url.startsWith("http://"))
  {
    segments = segments.slice(0, 3);
  }
  else{
    segments = segments.slice(0, 1);
  }
  
  return segments.join('/') + '/';
};

String.prototype.startsWith = function(str)
{
  return this.match("^" + str) == str;
};

String.prototype.endsWith = function(str)
{
  return this.match(str+"$") == str;
};

function isDefined(variable)
{
    return (typeof(variable) == "undefined")?  false: true;
}

/*
---
description: A class that creates a carousel control

license: MIT-style

authors:
- Andre Eckardt

requires:
- core/1.3: [Object,Class,Class.Extras,Element,Element.Event,Element.Style]

provides: [ContentCarousel]
*/
var ContentCarousel = new Class({
  Implements: [Options, Events],
  
  options: {        
    nextButton: null,
    prevButton: null,
    
    transition: Fx.Transitions.Back.easeOut,
    duration: 500,
    
    instant: false
  },
  
  container: null,
  wrapper: null,
  fx: null,
  locked: false,
  
  itemSize: { 'x': 0, 'y': 0 },
  offset: { 'x': 0, 'y': 0 },
  current: 0,
  
  initialize: function(container, items, options){
    this.setOptions(options);
    
    this.container = document.id(container);
    this.items = items;
    
    this.itemSize = this.items[0].getSize();
    this.offset = {'x': this.itemSize.x, 'y': this.itemSize.y }
      
      this.wrapper = new Element('div', {
        'class': 'content-carousel-inner',
        'styles': {
          'width': this.items.length * this.itemSize.x,
          'height': this.itemSize.y,
          'overflow': 'hidden',
          'position': 'relative'
        }
      });   
    
    this.wrapper.adopt(this.items);
    this.wrapper.inject(this.container);
    
    this.fx = new Fx.Tween(this.wrapper, {
      'property': 'margin-left',
      'transition': this.options.transition,
      'duration': this.options.duration
    });
    
    this.options.nextButton.addEvent('click', Function.from(this.next).bind(this));
    this.options.prevButton.addEvent('click', Function.from(this.prev).bind(this));
    
    this.fireEvent('onStartReached');
  },
  
  next: function(cb){     
    document.clearSelection();
    
    if(this.locked === true)
    {
      return;
        }    
    
    if(this.current + 1 >= this.items.length){
      this.fireEvent('onEndReached', this);
      return;
        }
    this.locked = true;  
    
    this.fireEvent('onNextStart', this);
    
    var cb = function(){      
      //this.offset.x += this.itemSize.x;
      
      this.current++;  
      
      if(this.current >= this.items.length - 1){
        this.fireEvent('onEndReached', this);
      }
      
      this.locked = false;
      this.fireEvent('onNextCompleted', this);
    }.bind(this);
    
    if(this.options.instant)
    {
      this.fx.set(-((this.current + 1) * this.itemSize.x));
      cb();
    }
    else
    {
      this.fx.start(-((this.current + 1) * this.itemSize.x)).chain(cb);
    }    
  },
  
  prev: function(){        
    document.clearSelection();  
    
    if(this.locked === true)
    {
      return;
        }
    
    if(this.current - 1 < 0){
      this.fireEvent('onStartReached', this);
      return;
        }
    
    this.locked = true;
    
    this.fireEvent('onPrevStart', this);
    
    var cb = function(){
      //this.offset.x -= this.itemSize.x;
      
      this.current--;    
      
      if(this.current < 1){
        this.fireEvent('onStartReached', this);
      }
      
      this.locked = false;  
      this.fireEvent('onPrevCompleted', this);
    }.bind(this);
    
    if(this.options.instant)
    {
      this.fx.set(-((this.current - 1) * this.itemSize.x));
      cb();
    }
    else
    {
      this.fx.start(-((this.current - 1) * this.itemSize.x)).chain(cb);
    }    
  },
  
  getCurrentPage: function(){
    return this.items[this.current];
  }
});

var trc = function(msg, level)
{
  try
  {
    if(level == null)
    {
      level = 'log';
    }
  
    eval('console.' + level + '("' + msg + '")');
  }
  catch(ex)
  {
    //throw ex;
  }
};

var makeCallable = function(flashObj, methodName) {
  flashObj[methodName] = 
    (function(methodName) {
      return function() {
        this.CallFunction(
          '<invoke name="' + methodName + '" returntype="javascript">'
          + __flash__argumentsToXML(arguments, 0)
          + '</invoke>');
      }; // dangling semi-colon for IE 6
    })(methodName); // force re-closure to prevent IE memory leaks
};

/*
---
description: A class that creates a lightbox control

license: MIT-style

authors:
- Andre Eckardt

requires:
- core/1.3: [Object,Class,Class.Extras,Element,Element.Event,Element.Style]

provides: [LightBox]
*/
var LightBox = new Class({
    Implements: [Options, Events],
    
    options: {
        noAnimations: false,
        duration: 100,
        transition: Fx.Transitions.linear.easeInOut,
        overlayOpacity: 0.7
    },
    
    isOpen: false,
    locked: false,
    
    overlay: null,
    overlayTween: null,
    
    content: null,
    contentTween: null,
        
    initialize: function(selector, options){
        this.setOptions(options);
        
        document.addEvent('click:relay(' + selector + ')', this.show.bind(this));
        
        this.overlay = new Element('div', {
            'class': 'lightbox-overlay',
            'styles': {
                'opacity': 0,
                'width': '100%',
                'height': '100%',
                'position': 'absolute'
            }
        });
        this.overlay.addEvent('click', this.close.bind(this));
                
        this.overlayTween = new Fx.Tween(this.overlay, {
            'property': 'opacity',
            'duration': this.options.duration,
            'translation': this.options.translation,
            'onStart': function(){
                this.locked = true;
            }.bind(this)
        });
        
        this.content= new Element('div', {
            'class': 'lightbox-content',
            'styles': {
                'position': 'absolute',
                'display': 'none'
            }
        });
                
        
        this.overlay.inject(document.body, 'top');
        this.content.inject(this.overlay, 'after');
    },
    
    show: function(e){
        e.preventDefault();
        
        if(this.options.noAnimations)
        {
            this.overlayTween.set(this.options.overlayOpacity);  
            this.showContent(e.target);
        }
        else
        {
            this.overlayTween.start(this.options.overlayOpacity).chain(function(){
                this.locked = false;
                this.showContent(e.target);
            }.bind(this));    
        }
    },
    
    showContent: function(a){        
        var img = new Element('img', {
            'src':  a.src,
            'title': a.getProperty('title')
        });
        var caption= new Element('div', {
            'html':  a.getProperty('title')
        });
        
        this.content.empty();
        
        img.inject(this.content);
        caption.inject(this.content);
        this.content.setStyle('display', 'block');
        
        var imgSize = img.getSize();
        var docSize= document.body.getSize();
        var newSize = this.scale(docSize.x, docSize.y, imgSize.x, imgSize.y);
        
        img.setProperties({
            'width': newSize[0] + 'px',
            'height': newSize[0] + 'px'
        });
        
        this.content.position();
        
        this.isOpen = true;
    },
    
    close: function(){
        if(this.options.noAnimations)
        {
            this.overlayTween.set(0);  
        }
        else if(this.locked === false)
        {
            this.overlayTween.start(0);    
        }
        else
        {
         return;   
        }
        
        this.content.setStyle('display', 'none');
        this.isOpen = false;
    },
       
    scale: function(maxW, maxH, currW, currH){
        var ratio = currH / currW;
        
        if(currW >= maxW && ratio <= 1){
            currW = maxW;
            currH = currW * ratio;
        } else if(currH >= maxH){
            currH = maxH;
            currW = currH / ratio;
        }
        
        return [currW, currH];
    }
});

/*
---
description: A Class that provides a cross-browser history-management functionaility, using the browser hash to store the application's state

license: MIT-style

authors:
- Arieh Glazer
- Dave De Vos
- Digitarald

requires:
- core/1.3: [Object,Class,Class.Extras,Element,Element.Event,Element.Style]

provides: [HashListener]

...
*/
(function($){

Element.NativeEvents['hashchange'] =  2;

HashListener = new Class({
  Implements : [Options,Events],
  options : {
    blank_page : 'blank.html',
    start : false
  },
  iframe : null,
  currentHash : '',
  firstLoad : true,
  handle : false,
  useIframe : (Browser.ie && (typeof(document.documentMode)=='undefined' || document.documentMode < 8)),
  ignoreLocationChange : false,
  initialize : function(options){
    var $this=this;
      
    this.setOptions(options);
    
    // Disable Opera's fast back/forward navigation mode
    if (Browser.opera && window.history.navigationMode) {
      window.history.navigationMode = 'compatible';
    }

    
     // IE8 in IE7 mode defines window.onhashchange, but never fires it...
        if (
      ('onhashchange' in window) &&
            (typeof(document.documentMode) == 'undefined' || document.documentMode > 7)
       ){
        
                // The HTML5 way of handling DHTML history...
        window.addEvent('hashchange' , function () {
          var hash = $this.getHash();
          if (hash == $this.currentHash) {
            return;
          }
          $this.fireEvent('hashChanged',hash);
          $this.fireEvent('hash-changed',hash);
        });;
        } else  {
      if (this.useIframe){
        this.initializeHistoryIframe();
      } 
        } 
    
    window.addEvent('unload', function(event) {
      $this.firstLoad = null;
    });
    
    if (this.options.start) this.start();
  },
  initializeHistoryIframe : function(){
    var hash = this.getHash(), doc;
    this.iframe = new IFrame({
      src    : this.options.blank_page,
      styles  : { 
        'position'  : 'absolute',
        'top'    : 0,
        'left'    : 0,
        'width'    : '1px', 
        'height'  : '1px',
        'visibility': 'hidden'
      }
    }).inject(document.body);

    doc  = (this.iframe.contentDocument) ? this.iframe.contentDocument  : this.iframe.contentWindow.document;
    doc.open();
    doc.write('<html><body id="state">' + hash + '</body></html>');
    doc.close();
    return;
  },
  checkHash : function(){
    var hash = this.getHash(), ie_state, doc;
    if (this.ignoreLocationChange) {
      this.ignoreLocationChange = false;
      return;
    }

    if (this.useIframe){
      doc  = (this.iframe.contentDocument) ? this.iframe.contentDocumnet  : this.iframe.contentWindow.document;
      ie_state = doc.body.innerHTML;
      
      if (ie_state!=hash){                
                this.setHash(ie_state);        
                hash = ie_state;                
      } 
    }    
    
    if (this.currentLocation == hash) {
      return;
    }
    
    this.currentLocation = hash;
    
    this.fireEvent('hashChanged',hash);
    this.fireEvent('hash-changed',hash);
  },
  setHash : function(newHash){
    window.location.hash = this.currentLocation = newHash;
    
    if (
      ('onhashchange' in window) &&
            (typeof(document.documentMode) == 'undefined' || document.documentMode > 7)
       ) return;
    
    this.fireEvent('hashChanged',newHash);
    this.fireEvent('hash-changed',newHash);
  },
  getHash : function(){
    var m;
    if (Browser.firefox){
      m = /#(.*)$/.exec(window.location.href);
      return m && m[1] ? m[1] : '';
    }else if (Browser.safari || Browser.chrome){
      return decodeURI(window.location.hash.substr(1));
    }else{
      return window.location.hash.substr(1);
    }
  },
  setIframeHash: function(newHash) {
    var doc  = (this.iframe.contentDocument) ? this.iframe.contentDocumnet  : this.iframe.contentWindow.document;
    doc.open();
    doc.write('<html><body id="state">' + newHash + '</body></html>');
    doc.close();
    
  },
  updateHash : function (newHash){
    if (document.id(newHash)) {
      this.debug_msg(
        "Exception: History locations can not have the same value as _any_ IDs that might be in the document,"
        + " due to a bug in IE; please ask the developer to choose a history location that does not match any HTML"
        + " IDs in this document. The following ID is already taken and cannot be a location: "
        + newHash
      );
    }
    
    this.ignoreLocationChange = true;
    
    if (this.useIframe) this.setIframeHash(newHash);
    else this.setHash(newHash);
  },
  start : function(){
    this.handle = this.checkHash.periodical(100, this);
  },
  stop : function(){
    clearInterval(this.handle);
  }
});

})(document.id);
