var Utils = new Class({

  clearLocationHash : function(str)
  {
    if(str.substr(0, 1) == '#')
      return str.substr(1, str.length);

    return str;
  }
});

var mateGallery = new Class({

  Implements : [Options, Log, Modalizer],

  options : {
    basepath      : 'galerias/',
    assetBaseUrl  : 'css/mateGallery/',
    useDefaultCss : true,
    loader        : 'gallery.php',
    imgBiggest    : 'biggest',
    imgPreview    : 'preview',
    imgThumb      : 'thumb',
    galleryDir    : 'galerias/obras/',
    overlayStyles : {
      'opacity'    : 0.9,
      'background' : '#fff',
      zIndex       : 2001
    }
  },

  initialize : function(element, options){
    if(!$defined(element) || !$(element)) return;
    this.setOptions(options);
    if(this.options.useDefaultCss) this.addCss();
    this.element = $(element);
    this.titles  = [];
    this.info    = [];
    this.addHtmlElements();
  },

  addHtmlElements : function(){
    this.element_container     = new Element('div', {'class':'MGContainer'}).inject(this.element);
    this.element_categories    = new Element('div', {'class':'MGCategories'}).inject(this.element_container);
    this.element_categories_ul = new Element('ul').inject(this.element_categories);
    this.element_thumbnails    = new Element('div', {'class':'MGThumbs'}).inject(this.element_container);
    this.element_wrapper       = new Element('div', {'class':'MGThumbsWrapper'}).inject(this.element_thumbnails);
    this.element_thumbnails_ul = new Element('ul').inject(this.element_wrapper);

    this.element_preview_container = new Element('div', {'class':'MGPreviewContainer'}).inject(this.element_container);
    this.element_preview           = new Element('div', {'class':'MGPreview'}).inject(this.element_preview_container);

    this.element_enlarge = new Element('div', {'class':'MGBiggestContainer'}).inject(this.element);
    this.element_enlarge.hide();

    //titles
    this.element_title_biggest = new Element('div', {'class':'MGTitleBiggest'}).inject(this.element);
    var inner = new Element('div', {'class':'MGTitleInner'}).inject(this.element_title_biggest);
    var picker = new Element('div', {'class':'MGPicker'}).inject(this.element_title_biggest);
    picker.store('element', 'biggest');
    picker.addEvent('click', this.clickPicker.pass(picker, this));
    new Element('div', {'class':'MGTitleText'}).inject(inner);
    this.element_title_biggest.hide();

    this.element_title_preview = new Element('div', {'class':'MGTitlePreview'}).inject(this.element_preview_container);
    var inner  = new Element('div', {'class':'MGTitleInner'}).inject(this.element_title_preview);
    var picker = new Element('div', {'class':'MGPicker'}).inject(this.element_title_preview);
    picker.store('element', 'preview');
    picker.addEvent('click', this.clickPicker.pass(picker, this));
    new Element('div', {'class':'MGTitleText'}).inject(inner);
    this.element_title_preview.hide();

    this.element_info = new Element('div', {'class':'MGInfo'}).inject(this.element);
    var inner = new Element('div', {'class':'MGInfoInner'}).inject(this.element_info);
    var picker = new Element('div', {'class':'MGPicker'}).inject(this.element_info);
    picker.addEvent('click', this.clickInfoPicker.pass(picker, this));
    new Element('div', {'class':'MGInfoText'}).inject(inner);
  },

  addCss: function(){
    window.addEvent('domready', function(){
      if($('BeforeAfterBoxCss')) return;
      new Element('link', {
        rel: 'stylesheet',
        media: 'screen',
        type: 'text/css',
        href: this.options.assetBaseUrl + 'mategallery.css',
        id: 'BeforeAfterBoxCss'
      }).inject(document.head);
    }.bind(this));
  },

  loadElements : function(url)
  {
    url = ($defined(url)) ? url : this.options.loader;
    new Request.JSON({'url':url, onComplete : this.explode.bind(this)}).get({'x':$time(), 'dir':this.options.galleryDir});
  },

  explode : function(json)
  {
    var j = $H(json);
    this.galleryLocation = j.get('location');
    this.galeries        = j.get('projects');
    this.currentGallery  = 0;
    this.currentPreview  = 0;

    this.addCategories();
  },

  getPic : function(id, section, collector){
    id = ($defined(id)) ? id : 0;
    for(var i=0; i < collector.length; i++){
      if(collector[i].name == section){
        return  collector[i].content[id];
        }
    }
  },

  addCategories : function()
  {
    this.tn = 0;
    this.galeries.each(function(gallery, id){
      var cover = this.getURL(id, this.options.imgThumb) + this.getPic(0, this.options.imgThumb, gallery.content).name;
      this.addCategory(id, cover, gallery.name);
    }, this);
  },

  addCategory : function(id, cover, name){
    return this.addThumb('category', id, cover, name);
  },

  setCategoryStyle : function(){
    this.element_categories_ul.getElements('li').each(function(item, id){
      if(item.hasClass('current'))
        item.removeClass('current');

      if(id == this.currentGallery)
        item.addClass('current');
    }, this);

  },

  setThumbsStyle : function(){
    this.element_thumbnails_ul.getElements('li').each(function(item, id){
      if(item.hasClass('current'))
        item.removeClass('current');

      if(id == this.currentPreview)
        item.addClass('current');
    }, this);

  },

  addThumbs : function(category_id){
    this.tn = 0;
    this.currentGallery = category_id;
    this.setCategoryStyle();
    this.element_wrapper.setStyle('width', 10);
    var gal = this.galeries[category_id];
    gal.content.each(function(section){
      if(section.name == this.options.imgThumb){
        section.content.each(function(img, i){
          this.addThumb('thumb', i,  this.getURL(this.currentGallery, this.options.imgThumb) + img.name, false);
          if(i == 0)  this.preview(0);
        }, this);
      }
    }, this);
  },

  addThumb : function(section, id, img_src, label){
    var self      = this;
    var container = (section == 'category')?this.element_categories_ul:this.element_thumbnails_ul;
    var wrapper   = this.element_wrapper;
    var li        = new Element('li').inject( container );
    var a         = new Element('a', {'href':'javascript:void(0);', 'section':section, 'item':id}).inject(li);

    a.addEvent('click', this.show.pass(a, this));
    new Asset.image(img_src, {
      'styles' : { 'opacity':0},
      onload : function(){
        this.inject(a);
        new Fx.Tween(this).start('opacity', 1);
        if($defined(label))
          new Element('div', {'class':((section == 'category')?'MGCategoryTitle':'MGThumbTitle'), 'html':label}).inject(a);

        switch(section){
          case 'thumb':
            if(id > self.tn){
              var size  = li.getComputedSize();
              var width = (size.totalWidth + 10) * (id+1);
              wrapper.setStyle('width', width);
              self.tn = id;
            }
            break;
          case 'category':
            if(id == self.currentGallery)
              self.addThumbs(self.currentGallery);
            break;
        }
      }
    });
    return li;
  },

  addImage : function(options)
  {
    var el = options.el;
    el.inject(options.link);
    new Fx.Tween(el).start('opacity', 1);
    if($defined(options.label))
      new Element('div', {'class':((options.section == 'category')?'MGCategoryTitle':'MGThumbTitle'), 'html':options.label}).inject(options.link);

    if(options.section == 'thumb')
    {
      var size = el.getComputedSize();
      this.element_thumbnails_ul.setStyle('width', this.element_thumbnails_ul.getSize().x + size.totalWidth);
    }
  },

  show : function(el)
  {
    var section = el.get('section');

    /*if(el.retrieve('etype') == 'document'){
      this.showDoc(el.get('item'));
    }
    else*/ if(section == 'category'){
      this.element_thumbnails_ul.empty();
      this.addThumbs(el.get('item'));
    }
    else{
      this.preview(el.get('item'));
    }

    return false;
  },

  preview : function(id){
    this.currentPreview = id;
    this.setThumbsStyle();

    var img       = this.getPic(id, this.options.imgPreview, this.galeries[this.currentGallery].content);
    var image     = this.getURL(this.currentGallery, this.options.imgPreview) + img.name;
    var container = this.element_preview;
    var size      = container.getSize();
    var self      = this;
    container.getElements('img.MGPreviewImage').each(function(im){ im.destroy(); });
    var waiter = new Waiter(container).start();
    var img = new Asset.image(image, {
      'class'  : 'MGPreviewImage',
      'styles' : { 'opacity':0},
      onload   : function(){
        this.inject(container);
        var rsize = self.resize(this.width, this.height, size.x, size.y);
        this.setStyles({'width':rsize.width -5, 'height':rsize.height -5});
        this.position({relativeTo:container});
        new Fx.Tween(this).start('opacity', 1);
        waiter.stop();
        self.getTitle();
      }
    });

    img.store('item_id', id);
    img.setStyle('cursor', 'pointer');

    if(image.split('/').getLast().substr(0, 7) == 'pdf_doc')
      img.addEvent('click', this.showDoc.pass(id, this));
    else if(image.split('/').getLast().substr(0, 7) == 'video_')
      img.addEvent('click', this.enlarge.pass(img, this));
    else
      img.addEvent('click', this.enlarge.pass(img, this));
  },

  enlarge : function(el){
    if(!el) return false;
    var id = el.retrieve('item_id');
    var self = this;

    this.element_enlarge.empty();
    this.element_enlarge.show();
    this.setModalOptions({elementsToHide: ''});
    this.setModalStyle(this.options.overlayStyles);
    this.overlay = this.layer().addClass('MGOverlay');
    this.overlay.inject(this.element_enlarge).setStyles(this.options.overlayStyles);
    this.overlay.addEvent('click', this.close.bind(this));

    var waiter = new Waiter(this.element_enlarge).start();
    var img    = this.getPic(id, this.options.imgBiggest, this.galeries[this.currentGallery].content);
    var image  = this.getURL(this.currentGallery, this.options.imgBiggest) + img.name;
    var size   = this.element.getSize();
    var container  = new Element('div', {'class':'MGBiggestImage'}).inject(this.element_enlarge);
    var econtainer = this.element_enlarge;
    var img = new Asset.image(image, {
      'styles' : { 'opacity':0},
      onload : function(){
        this.inject(container);
        var rsize = self.resize(this.width, this.height, size.x, size.y);
        this.setStyles({'width':rsize.width -80, 'height':rsize.height -80});
        container.position({relativeTo:econtainer, offset:{y:-10, x:-10} });
        new Fx.Tween(this).start('opacity', 1);
        waiter.stop();
        self.getTitle();
        self.getInfo();
      }
    });
    img.setStyle('cursor', 'pointer');
    img.addEvent('click', this.close.bind(this));

    return false;
  },

  showDoc : function(id){
    if(!$defined(id)) return false;
    var self = this;

//     this.element_enlarge.empty();
//     this.element_enlarge.show();

//     if(!$defined(this.overlay)){
//       this.setModalOptions({elementsToHide: ''});
//       this.setModalStyle(this.options.overlayStyles);
//       this.overlay = this.layer().addClass('MGOverlay');
//       this.overlay.inject(this.element_enlarge).setStyles(this.options.overlayStyles);
//       this.overlay.addEvent('click', this.close.bind(this));
//     }

    this.modal = new Modalizer().modalShow({
      modalStyle : this.options.overlayStyles
    });
    var overlay = this.modal.layer().addClass('MGOverlay');
    overlay.setStyles(this.options.overlayStyles);
    overlay.addEvent('click', this.closeDoc.bind(this));

    var e         = this.element.getParent('div.frame');
    e             = (!e) ? this.element : e;
    var doc       = this.getPic(id, this.options.imgThumb, this.galeries[this.currentGallery].content);
    var size      = e.getSize();
    var container = new Element('div', {'class':'MGBiggestImage', 'id':'MGBiggestContainer'}).inject(document.body);
    container.setStyles({'width':size.x, 'height':size.y, 'z-index':6000});
    var doc_name  = doc.name.substr(4).split('.');
    var doc_obj   = doc_name[0];
    var doc_key   = doc_name[1];
    var doc_id    = doc_name[2];

    this.object_id = doc_obj;

    var obj = new Swiff('http://d.scribd.com/ScribdViewer.swf', {
      'id'      : doc_obj,
      'name'    : doc_obj,
      'width'   : '100%',
      'height'  : '100%',
      params: {
        'play'       : 'true',
        'loop'       : 'true',
        'scale'      : 'showall',
        'devicefont' : 'false',
        'wmode'      : 'opaque',
        'bgcolor'    : '#ffffff',
        'menu'       : 'true',
        'salign'     : '',
        'allowScriptAccess' : 'always',
        'allowFullScreen'   : 'true'
      },
      vars: {
        'document_id' : doc_id,
        'access_key'  : doc_key,
        'page'        : 1,
        'version'     : 1,
        'viewMode'    : ''
      }
    });

    obj.inject(container);

    container.position({relativeTo:e});

    var myFloatingDivShim = new IframeShim(container, {
      display: false,
      name: 'MGBiggestIframe'
    });
    return false;
  },

  closeDoc : function(){
    if($('MGBiggestContainer'))
      $('MGBiggestContainer').destroy();
  },

  close : function(){
    this.element_enlarge.hide();
    this.element_enlarge.empty();
    if(this.element_title_biggest) this.element_title_biggest.hide();
    if(this.element_info) this.element_info.hide();
  },

  getURL : function(category_id, folder){
    return this.galleryLocation + this.galeries[category_id].name + '/' + folder + '/';
  },

  /**
   * TITLES
   */
  getTitle : function(){
    if($defined(this.titles[this.currentGallery]))
      if($defined(this.titles[this.currentGallery][this.currentPreview]))
        return this.setTitle();

    var f   = this.getURL(this.currentGallery, this.options.imgBiggest);
    f = f.substr(0, f.length - this.options.imgBiggest.length - 1) + 'data/titles.php';
    var img = this.getPic(this.currentPreview, this.options.imgBiggest, this.galeries[this.currentGallery].content);

    new Request.JSON({url:this.options.loader, onComplete:this.__getTitle.bind(this)}).post({'mod':'title', 'url':f, 'file':img.name});
  },

  __getTitle : function(json){
    if(!$defined(json)) json = {'title':null, 'error':''};
    if(json.title == '' || !json.title || json.title === null){
      if(this.element_title_biggest.isDisplayed()) this.element_title_biggest.hide();
      if(this.element_title_preview.isDisplayed()) this.element_title_preview.hide();
      return false; /*($defined(json.error)) ? this.log('ERROR: ' +json.error) : false;*/
     }

    if(!$defined(this.titles[this.currentGallery])) this.titles[this.currentGallery] = [];
    this.titles[this.currentGallery][this.currentPreview] = json.title;

    this.setTitle();
  },

  setTitle : function(title){
    title = ($defined(title)) ? title : this.titles[this.currentGallery][this.currentPreview];
    if(!title) return;
    if(!$defined(this.picker_state)){
      this.picker_state = {};
      var setpicker = true;
    }

    if(this.element_enlarge.isDisplayed()){
//       if(!$defined(this.element_title_biggest) || !$('MGTitleBiggest') ){
//         this.element_title_biggest = new Element('div', {'class':'MGTitleBiggest', 'id':'MGTitleBiggest'}).inject(this.element);
//         var inner = new Element('div', {'class':'MGTitleInner'}).inject(this.element_title_biggest);
//         var picker = new Element('div', {'class':'MGPicker'}).inject(this.element_title_biggest);
//         picker.store('element', 'biggest');
//         picker.addEvent('click', this.clickPicker.pass(picker, this));
//         new Element('div', {'class':'MGTitleText'}).inject(inner);
//       }
//       else{
        if(!this.element_title_biggest.isDisplayed()) this.element_title_biggest.show();
        var picker = this.element_title_biggest.getElement('div.MGPicker');
//       }

      var el = this.element_title_biggest.getElement('div.MGTitleText');
      el.set('html', title);

      if(!$defined(this.picker_state.biggest)){
        this.element_title_biggest.position({relativeTo:this.element_enlarge, position:'centerTop', edge:'centerBottom'});
        this.picker_state.biggest = 'close';
        this.clickPicker(picker);
      }
//       this.element_title_biggest.move({relativeTo:this.element_enlarge, position:'centerTop', edge:'centerTop'});
    }
    else{
//       if(!$defined(this.element_title_preview) || !$('MGTitlePreview') ){
//         this.element_title_preview = new Element('div', {'class':'MGTitlePreview', 'id':'MGTitlePreview'}).inject(this.element_preview_container);
//         var inner  = new Element('div', {'class':'MGTitleInner'}).inject(this.element_title_preview);
//         var picker = new Element('div', {'class':'MGPicker'}).inject(this.element_title_preview);
//         picker.store('element', 'preview');
//         picker.addEvent('click', this.clickPicker.pass(picker, this));
//         new Element('div', {'class':'MGTitleText'}).inject(inner);
//       }
//       else{
        var picker = this.element_title_preview.getElement('div.MGPicker');
        if(!this.element_title_preview.isDisplayed()) this.element_title_preview.show();
//       }

      var el = this.element_title_preview.getElement('div.MGTitleText');
      el.set('html', title);

      if(!$defined(this.picker_state.preview)){
        this.element_title_preview.position({relativeTo:this.element_preview, position:'centerTop', edge:'centerBottom'});
        this.picker_state.preview = 'close';
        this.clickPicker(picker);
      }
//       this.element_title_preview.move({relativeTo:this.element_preview, position:'centerTop', edge:'centerTop'});
    }
  },

  clickPicker : function(el){
    var eltype   = el.retrieve('element');
    var element  = (eltype == 'preview') ? this.element_title_preview : this.element_title_biggest;
    var relative = (eltype == 'preview') ? this.element_preview : this.element_enlarge;

    switch(this.picker_state[eltype]){
      case 'open':
        element.move({relativeTo:relative, position:'centerTop', edge:'centerBottom', offset:{y:17} });
        this.picker_state[eltype] = 'close';
//         el.store('state', 'close');
        break;

      case 'close':
        element.move({relativeTo:relative, position:'centerTop', edge:'centerTop' });
        this.picker_state[eltype] = 'open';
//         el.store('state', 'open');
        break;
    }
  },


  /**
   * INFO
   */
  getInfo : function(){
    if($defined(this.info[this.currentGallery]))
      if($defined(this.info[this.currentGallery][this.currentPreview]))
        return this.setInfo();

    var f   = this.getURL(this.currentGallery, this.options.imgBiggest);
    f = f.substr(0, f.length - this.options.imgBiggest.length - 1) + 'data/info.php';
    var img = this.getPic(this.currentPreview, this.options.imgBiggest, this.galeries[this.currentGallery].content);

    new Request.JSON({url:this.options.loader, onComplete:this.__getInfo.bind(this)}).post({'mod':'info', 'url':f, 'file':img.name});
  },

  __getInfo : function(json){
    if(!$defined(json)) json = {'info':null, 'error':''};
    if(json.info == '' || !json.info || json.info === null){
      this.element_info.hide();
      return false /*($defined(json.error)) ? this.log('ERROR: ' +json.error) : false;*/
     }

    if(!$defined(this.info[this.currentGallery])) this.info[this.currentGallery] = [];
    this.info[this.currentGallery][this.currentPreview] = json.info;

    this.setInfo();
  },

  setInfo : function(){
    var info  = this.info[this.currentGallery][this.currentPreview];
    if(!info) return;

    if(this.element_enlarge.isDisplayed()){
      if(!this.element_info.isDisplayed()) this.element_info.show();
      var picker = this.element_info.getElement('div.MGPicker');

      var el = this.element_info.getElement('div.MGInfoText');
      el.set('html', info);
//       this.log(info);

      if(!$defined(this.info_picker)){
        this.element_info.position({relativeTo:this.element, position:'centerBottom', edge:'centerTop'});
        this.info_picker = 'close';
        this.clickInfoPicker();
      }
      else if(this.info_picker == 'open'){
        this.element_info.position({relativeTo:this.element, position:'centerBottom', edge:'centerBottom'});
      }
    }
  },

  clickInfoPicker : function(){
    var element  = this.element_info;
    var relative = this.element;

    switch(this.info_picker){
      case 'open':
        element.move({relativeTo:relative, position:'centerBottom', edge:'centerTop', offset:{y:-17}});
        this.info_picker = 'close';
        break;

      case 'close':
        element.move({relativeTo:relative, position:'centerBottom', edge:'centerBottom'});
        this.info_picker = 'open';
        break;
    }
  },

  resize : function(width, height, new_width, new_height, force_resize){
    var obj = {'width':width, 'height':height};
    var resize_by = false;

    if(new_width > new_height){
      if(width > height && width > new_width){
        obj.width  = new_width;
        obj.height = (height/width)*new_width;
      }
      else if(height > width && height > new_height){
        obj.width  = (width/height)*new_height;
        obj.height = new_height;
      }
    }

    return obj;
  }


});


var BeforeAfterBox = new Class({

  Implements: [Options, Events, Modalizer, Chain],

  options: {
    resizeDuration  : 400,
    initialWidth    : 300,
    initialHeight   : 300,
    zIndex          : 5000,
    animateCaption  : true,
    showCounter     : true,
    autoScanLinks   : true,
    relString       : 'babox',
    useDefaultCss   : true,
    prefixBefore    : 'before_',
    prefixAfter     : 'after_',
    assetBaseUrl    : 'css/babox/',
    overlayStyles   : {
      'opacity'    : 0.8,
      'background' : '#fff'
    }
//  onImageShow: $empty,
//  onDisplay: $empty,
//  onHide: $empty
  },

  initialize : function(options)
  {
    var args = Array.link(arguments, {options: Object.type, links: Array.type});
    this.setOptions(args.options);
    this.options.overlayStyles.zIndex = this.options.zIndex +1;
    var anchors = args.links || this.options.anchors;
    if (this.options.autoScanLinks && !anchors) anchors = $$('a[rel^='+this.options.relString+']');
    if(!$$(anchors).length) return; //no links!
    this.addAnchors(anchors);
    if(this.options.useDefaultCss) this.addCss();
    window.addEvent('domready', this.addHtmlElements.bind(this));
  },

  anchors: [],

  loadedImages : [],

  addAnchors: function(anchors){
    $$(anchors).each(function(el){
      if(!el.retrieve('babox') && !el.retrieve('lightbox')) {
        el.store('babox', this);
        this.attach(el);
      }
    }.bind(this));
  },

  addCss: function(){
    window.addEvent('domready', function(){
      if($('BeforeAfterBoxCss')) return;
      new Element('link', {
        rel: 'stylesheet',
        media: 'screen',
        type: 'text/css',
        href: this.options.assetBaseUrl + 'babox.css',
        id: 'BeforeAfterBoxCss'
      }).inject(document.head);
    }.bind(this));
  },

  attach: function(el) {
    el.addEvent('click', this.click.pass(el, this));
    this.anchors.include(el);
  },

  click: function(el){
    link = $(el);
    var rel = link.get('rel')||this.options.relString;
    if (rel == this.options.relString){
      var src = link.get('href');
      if(!this.isValidImage(src)) return;
      var src_before = (this.isAfter(src.split('/').getLast())) ? src.replace(this.options.prefixAfter, this.options.prefixBefore) : src;
      var src_after  = (this.isBefore(src.split('/').getLast())) ? src.replace(this.options.prefixBefore, this.options.prefixAfter) : src;
      return this.show(src_before, src_after);
    }

    /*
    var j, imageNum, images = [];
    this.anchors.each(function(el){
      if (el.get('rel') == link.get('rel')){
        for (j = 0; j < images.length; j++) if(images[j][0] == el.get('href')) break;
        if (j == images.length){
          images.push([el.get('href'), el.get('title')]);
          if (el.get('href') == link.get('href')) imageNum = j;
        }
      }
    }, this);
    return this.open(images, imageNum);
    */
  },

  isValidImage : function(src){
    var valids = ['gif', 'jpg', 'png'];
    return valids.contains(src.split('.').getLast().toLowerCase());
  },

  isBefore : function(src){
    return (src.substr(0, this.options.prefixBefore.length) == this.options.prefixBefore);
  },

  isAfter : function(src){
    return (src.substr(0, this.options.prefixAfter-length) == this.options.prefixAfter);
  },

  addHtmlElements : function()
  {
    this.setModalOptions({elementsToHide: ''});
    this.setModalStyle(this.options.overlayStyles);
    this.overlay = this.layer().addClass('babOverlay');
//     this.modalHide();

    this.container       = new Element('div', {'class' : 'babContainer', 'styles' : {zIndex : this.options.zIndex} }).inject(document.body);
    this.popup           = new Element('div', {'class' : 'babPopup',     'styles' : {zIndex : this.options.zIndex +2}}).inject(this.container);
    this.popupBefore     = new Element('div', {'class' : 'babPopupBefore'}).inject(this.popup);
    this.popupAfter      = new Element('div', {'class' : 'babPopupAfter'}).inject(this.popup);
    this.labels          = new Element('div', {'class' : 'babLabels'}).inject(this.popup);
    this.labelBefore     = new Element('div', {'class' : 'babLabelBefore'}).inject(this.labels);
    this.labelAfter      = new Element('div', {'class' : 'babLabelAfter'}).inject(this.labels);
    this.btnClose        = new Element('a',   {'class' : 'babCloseLink', href: 'javascript:void(0);'}).inject(this.popup).addEvent('click', this.close.bind(this));

    this.overlay.inject(this.container).setStyles(this.options.overlayStyles);
    this.overlay.addEvent('click', this.close.bind(this));

    this.container.hide();
  },

  show: function(before, after){
    return this.open([[before, after]], 0);
  },

  open: function(images, imageNum){
    this.fireEvent('onDisplay');
    this.images = images;
    this.setup(true);
    return this.changeImage(imageNum);
  },

  setup: function(open){
    var elements = $$('object, iframe');
    elements.extend($$(Browser.Engine.trident ? 'select' : 'embed'));
    elements.reverse().each(function(el){
      if (open) el.store('babBackupStyle', el.getStyle('visibility') || 'visible');
      var vis = (open ? 'hidden' : el.retrieve('babBackupStyle') || 'visible');
      el.setStyle('visibility', vis);
    });
    var fn = open ? 'addEvent' : 'removeEvent';
    document[fn]('keydown', this.keyboardListener);
    this.step = 0;
  },

  changeImage: function(imageNum){
    this.fireEvent('onImageShow', [imageNum, this.images[imageNum]]);

    this.popupBefore.empty();
    this.popupAfter.empty();

    this.popupBefore.setStyles({'opacity':0});
    this.popupAfter.setStyles({'opacity':0});

    this.labels.setStyle('opacity', 0);
    this.popup.setStyles({
      'width'  : this.options.initialWidth,
      'height' : this.options.initialHeight,
      'opacity': 0,
      'backgroundImage' : 'url("' + this.options.assetBaseUrl + 'icn_loader.gif")'
    });
    this.container.show();
    this.popup.setPosition();

    new Fx.Tween(this.popup, {duration:this.options.resizeDuration}).start('opacity', 1);
    new Fx.Tween(this.btnClose).set('opacity', 0);
//     this.loading = new Asset.image(this.options.assetBaseUrl + 'icn_loader.gif', {
//       onload:function(){
//         this.loading.inject(this.container);
//         this.loading.setPosition();
//       }.bind(this)
//     });

    this.loadedImages = new Asset.images(this.images[imageNum], {
      onProgress : function(){ this.store('size', {x:this.width, y:this.height}) },
      onComplete : this.startEffects.bind(this)
    });
    return false;
  },

  startEffects : function(){
    var before_img  = this.loadedImages[0];
    var after_img   = this.loadedImages[1];
    var before_size = before_img.retrieve('size');
    var after_size  = after_img.retrieve('size');

    var maxHeight   = Math.min(before_size.y, after_size.y);

    this.popupBefore.setStyles({'height':maxHeight, 'width':before_size.x, 'opacity':0});
    this.popupAfter.setStyles({'height':maxHeight, 'width':after_size.x, 'opacity':0});
    before_img.inject(this.popupBefore);
    after_img.inject(this.popupAfter);

    var size  = {'width' : before_size.x + after_size.x + 20, 'height' : maxHeight + 20};
    var csize = {'width' : this.popup.getSize().x, 'height':this.popup.getSize().y};
    this.popup.setStyles({'width':size.width, 'height':size.height});
    var pos = this.popup.setPosition({returnPos:true});
    this.popup.setStyles({'width':csize.width, 'height':csize.height});



    var fxChain = new Chain();
    var fxContainer = new Fx.Morph(this.popup, {duration:this.options.resizeDuration, onComplete:function(){fxChain.callChain()}});
    fxChain.chain(
      function(){ fxContainer.start({'width':size.width, 'left':pos.left}) }.bind(this),
      function(){ fxContainer.start({'height':size.height, 'top':pos.top}) }.bind(this),
      function(){
        this.popupBefore.setPosition({relativeTo:this.popup, 'position':'leftTop', 'edge':'leftTop', 'offset':{x:5, y:5}});
        this.popupAfter.setPosition({relativeTo:this.popup, 'position':'rightTop', 'edge':'rightTop', 'offset':{x:-10, y:5}});
        new Fx.Tween(this.popupBefore, {duration:this.options.resizeDuration, onComplete:function(){fxChain.callChain()} }).start('opacity', 1);
      }.bind(this),
      function(){ new Fx.Tween(this.popupAfter, {duration:this.options.resizeDuration, onComplete:function(){fxChain.callChain()} }).start('opacity', 1); }.bind(this),
      function(){ this.popup.setStyle('background-image', 'none'); fxChain.callChain() }.bind(this),
      function(){ fxContainer.start({'height' : size.height + this.labels.getSize().y}); }.bind(this),
      function(){
        this.labels.setPosition({relativeTo:this.popup, 'position':'centerBottom', 'edge':'centerBottom', 'offset':{y:-2}});
        new Fx.Tween(this.labels, {duration:this.options.resizeDuration, onComplete:function(){fxChain.callChain()} }).start('opacity', 1);
      }.bind(this),
      function(){
        this.btnClose.setPosition({relativeTo:this.popup, 'position':'rightBottom', 'edge':'rightBottom', 'offset':{x:-5, y:-2} });
        new Fx.Tween(this.btnClose, {duration:this.options.resizeDuration, onComplete:function(){fxChain.callChain()} }).start('opacity', 1);
      }.bind(this),
      function(){ this.fireEvent('onComplete'); fxChain.callChain(); }.bind(this)
//       function(){  }.bind(this),
    );
    fxChain.callChain();

  },

  close: function(){
    this.fireEvent('onHide');
    this.container.hide();
    return;
  },

  keyboardListener: function(event){
    switch (event.code){
      case 27: case 88: case 67: this.close(); break;
//       case 37: case 80: this.previous(); break;
//       case 39: case 78: this.next();
    }
  }
});
window.addEvent('domready', function(){if($(document.body).get('html').match(/rel=?.babox/i)) new BeforeAfterBox()});