
/**
 * Proyecto:    Planeta del Este
 * Archivo:     Planeta.js
 *
 *
 * @link http://www.planetadeleste.com/
 * @copyright 2009 Planeta del Este
 * @author Alvaro Canepa <alvaro.canepa@planetadeleste.com>
 * @requirements PHP: PHP5; PEAR; Smarty - Javascript: Mootools Core 1.2, Mootools More 1.2
 * @version 1.0
 */


/*
Script: Element.Extends.removeClasses.js
  Remove all classes of the element.
  If var addClass is defined, after removed all classes, add this class

  License:
    MIT-style license.

  Authors:
    Alvaro Canepa

  Usage:
    $('element').removeClasses('className')

*/

Element.implement({

  removeClasses: function(addClass){
    this.get('class').split(' ').each(function(cls){
      if($defined(addClass))
        if(addClass == cls)
          return;

      this.removeClass(cls);
    }, this);

    if($defined(addClass))
      if(!this.hasClass(addClass))
        this.addClass(addClass);
  }

});


var AutoOvers = new Class({
  Implements : [Options],
  options : {
  },

  initialize : function(options){

  }
})


 var Planeta = new Class({

    Implements : [Options, Chain, Log],

    options : {
      'container' : 'content',
      'backgrounds' : {
        1024 : 'set1024/',
        1440 : 'set1440/',
        1680 : 'set1680/'
      },
      'BASE_URL'     : 'http://alvaro/planeta/',
      'TEMPLATE_URL' : 'templates/',
      'TEMPLATE'     : 'planeta',
      'LANG'         : 'es',
      'LANGS'        : ['es', 'en']
    },

    initialize : function(options){
      this.setOptions(options);
      this.page = false;

      window.addEvent('domready', this.domReady.pass('', this));
    },

    /////////////////////////////////////////////////////////////////
    //  Metodos de navegacion
    /////////////////////////////////////////////////////////////////

    pages : [],

    setNavigation : function(elements){
      elements = ($defined(elements)) ? elements : $$('.nav ul li');
      if(!elements) return false;

      elements.each(function(el){
        var img  = el.getElement('img.over');
        var out  = el.getElement('img.selected');
        var link = el.getElement('a');
        if(!img || !out || !link) return false;
        img.fade('hide');
        out.fade('hide');


        link.addEvents({
          'click'       : this.navClick.pass(link, this),
          'mouseenter'  : this.navOver.pass(el, this),
          'mouseleave'  : this.navOut.pass(el, this)
        });

        link.store('page', this.getPageFromLink(link));
        this.pages.include(this.getPageFromLink(link));
      }, this);
      this.links = elements;
    },

    navClick : function(el){
      var p = el.retrieve('page');
      this.pageLoad(p);
      return false;
    },

    navOver : function(el){
      var img = el.getElement('img.over');
      var out = el.getElement('img.static');
      var sel = el.getElement('img.selected');
      if(!img || !out || sel.getStyle('opacity') > 0) return false;
      new Fx.Tween(img, {duration:300}).start('opacity', 1);
      new Fx.Tween(out, {duration:300}).start('opacity', 0);
    },

    navOut : function(el){
      var img = el.getElement('img.over');
      var out = el.getElement('img.static');
      if(!img || !out) return false;
      new Fx.Tween(img, {duration:300}).start('opacity', 0);
      new Fx.Tween(out, {duration:300}).start('opacity', 1);
    },

    navCurrent : function(){
      this.links.each(function(el){
        var out  = el.getElement('img.selected');
        out.fade('hide');

        var link = el.getElement('a[href^='+this.page+']');
        if(link){
          link.getElement('img.selected').fade('in');
        }
      }, this)
    },

    getPage : function(str){
      str = ($defined(str)) ? str : this.getPageFromUrl();
      if($type(str) == 'object'){
        if($defined(str.page))
          return str.page;
        return 'index';
      }
      return (!str) ? 'index' : str;
    },

    getPageFromUrl : function(){
      var uri = new URI(location.href);
      var hash = uri.get('fragment');
      var file = uri.get('path');
      if(hash){
        return hash.parseQueryString();
      }
      return file;
    },

    getPageFromLink : function(link){
      if(!$(link)) return false;
      var p     = link.href.split('/').getLast();
      var ext   = p.split('.').getLast();
      return p.substr(0, p.length - (ext.length +1));
    },


    /////////////////////////////////////////////////////////////////
    //  Metodos de interface
    /////////////////////////////////////////////////////////////////

    guiBackground : function(){
      var set    = ['clouds.png', 'clouds2.png', 'land.png', 'boat01.png', 'boat02.png',
                    'boat03.png', 'boat04.png', 'boat05.png', 'boat06.png', 'plane.png',
                    'birds.png', 'icons.png', 'bgIndex.jpg', 'bgPortfolio.jpg'];
      var bgs    = $H(this.options.backgrounds);
      var docDim = $(document.body).getDimensions({computeSize:true});
      var k      = bgs.getKeys();
      var src    = false;
      var images = [];
      k = k.sort();
      k.each(function(resolution, i){
        if((docDim.totalWidth < resolution || i == k.length-1) && !src){
          this.resolution = resolution;
          src = this.options.BASE_URL + this.options.TEMPLATE_URL + this.options.TEMPLATE +'/images/' + bgs.get(resolution);
          images = set.map(function(item){ return src + item; });
        }
      }, this);

      var self = this;
      var maxy = 0;
      new Asset.images(images, {
        onProgress : function(l, i){
          if($('guiLoading')){
            self.Loading({'element':$('guiLoading'), 'loaded':l, 'total':images.length, 'offset':{y:50}, 'class':'guiLoadingHome' });
          }

          var img = this.get('src').split('/').getLast();
          if(img == 'bgIndex.jpg' || img == 'bgPortfolio.jpg')  return;

          var cls = self.utilRemoveExt(this.get('src'));
          this.addClass(cls);
          if(cls.substr(0, 4) == 'boat') this.addClass('boat');
          this.inject($('footer_background'));
          maxy = [maxy, this.height].max();
        },
        onComplete : function(){
          self.Loading(true);
          $('footer').setStyle('height', maxy);
          $('footer_background').setStyle('height', maxy);
          self.guiAnim();
        }
      });
//       new Asset.image(src, {onload : function(){
//         this.inject($('footer_background'));
//         $('footer').setStyle('height', this.height);
//         $('footer_background').setStyle('height', this.height);
//         self.guiAnim();
//       }})

    },

    guiAnimateBackground : function(){
      var el      = $('footer_background');
      var size    = el.getSize();

      // CLOUDS
      var cloudsContainer = el.getElement('.cloudsContainer');
      var clouds  = el.getElement('img.clouds');
      var clouds2 = el.getElement('img.clouds2');
      var move_clouds;
      var move_clouds2;
      var clouds_duration = 250000;

      move_clouds = new Fx.Move(clouds, {
        transition : 'linear',
        duration   : clouds_duration,
        relativeTo : cloudsContainer,
        position   : 'leftTop',
        edge       : 'rightTop',
        offset     : {x:-1},
        onComplete : function(){

          clouds.position({
            relativeTo : cloudsContainer,
            position   : 'rightTop',
            edge       : 'leftTop',
            offset     : {x:-1}
          });

          new Fx.Move(clouds, {
            transition : 'linear',
            duration   : clouds_duration,
            relativeTo : cloudsContainer,
            position   :'leftTop',
            edge       : 'leftTop',
            offset     : {x:-1},
            onComplete : function(){
              move_clouds.start();
            }
          }).start();

        }
      }).start();


      move_clouds2 = new Fx.Move(clouds2, {
        transition : 'linear',
        duration   : clouds_duration,
        relativeTo : cloudsContainer,
        position   : 'leftTop',
        edge       : 'leftTop',
        offset     : {x:-1},
        onComplete : function(){

          new Fx.Move(clouds2, {
            transition : 'linear',
            duration   : clouds_duration,
            relativeTo : cloudsContainer,
            position   :'leftTop',
            edge       : 'rightTop',
            offset     : {x:-1},
            onComplete : function(){
              clouds2.position({
                relativeTo : cloudsContainer,
                position   : 'rightTop',
                edge       : 'leftTop',
                offset     : {x:-1}
              });
              move_clouds2.start();
            }
          }).start();

        }
      }).start();

      // BOATS
      var boats = el.getElements('img[class^=boat]');
      var boat_fx = [];
      boats.each(function(boat, i){
        var boat_duration = $random(1800, 3000);
        var top           = i + 1;

        boat_fx[i] = new Fx.Morph(boat, {
          duration:boat_duration,
          onComplete : function(){
            new Fx.Morph(boat, {
              duration:boat_duration,
              onComplete : function(){
                boat_fx[i].start({'top':top});
              }
            }).start({'top':0})
          }
        });
        boat_fx[i].start({'top':top});
      });
    },

    guiStart : function(){
      this.elLogo = $('logo');
      this.elNav  = $('nav');
      this.elContent = $('content');
      this.elFooter  = $('footer');

      [this.elLogo, this.elNav, this.elContent, this.elFooter].each(function(el){ el.fade('hide') });
      this.guiBackground();

      this.elLogo.addEvents({
        'mouseenter' : function(){this.fade(.5);},
        'mouseleave' : function(){this.fade(1);}
      })
    },

    guiAnim : function(){

      var el      = $('footer_background');
      var size    = el.getSize();

      //ICONS
      var icons = el.getElement('img.icons');
      icons.position({relativeTo:el, position:'rightBottom', edge:'rightBottom'});

      // CLOUDS
      var clouds  = el.getElement('img.clouds');
      var clouds2 = el.getElement('img.clouds2');
      var cloudsContainer = new Element('div', {
        'class':'cloudsContainer',
        'styles' : {
          'width'    : clouds.width,
          'height'   : clouds.height
        }
      }).inject(el);
      clouds.inject(cloudsContainer);
      clouds2.inject(cloudsContainer);

      clouds2.position({
        relativeTo : cloudsContainer,
        position   : 'rightTop',
        edge       : 'leftTop',
        offset     : {x:-1}
      });

      this.guiLoading(true);

      // get page
      var init_page = 'index';
      var cpage = new URI(location.href);
      if(cpage.get('fragment')){
        if(this.pages.contains(cpage.get('fragment')))
          init_page = cpage.get('fragment');
      }

      var chains = [
        function(){ new Fx.Reveal(this.elLogo, {duration:400, onComplete:function(){ this.callChain() }.bind(this) }).reveal();}.bind(this),
        function(){ new Fx.Reveal(this.elNav, {duration:400, onComplete:function(){ this.callChain() }.bind(this)}).reveal() }.bind(this),
        function(){ new Fx.Reveal(this.elContent, {duration:800, onComplete:function(){ this.callChain() }.bind(this)}).reveal() }.bind(this),
        function(){ new Fx.Tween(this.elFooter, {duration:400, onComplete:function(){ this.callChain() }.bind(this) }).start('opacity', 1) }.bind(this),
        function(){ this.guiAnimateBackground(); this.pageLoad(init_page) }.bind(this)
      ];

      this.chain(chains);
      this.callChain();
    },

    guiLoading : function(hide, options){
      options = (!$defined(options)) ? {} : options;
      var op  = {'image':'loading.jpg', 'element':this.options.container};
      options = $merge(op, options);

      var loading = this.options.BASE_URL + this.options.TEMPLATE_URL + this.options.TEMPLATE + '/images/' + this.options.LANG + '/slides/' + options.image;

      if($('guiLoading')){
        if(hide){
          $('guiLoading').hide();
          return false;
        }

        var size  = options.element.getSize();
        var image = $('guiLoading').getElement('img');
        if(image.get('src') != loading){
          image.destroy();
          new Asset.image(loading, {
            onload : function(){
              this.inject($('guiLoading'));
            }
          });
        }

        $('guiLoading').setStyles({'width':size.x, 'height':size.y});
        $('guiLoading').position({relativeTo : options.element});
        $('guiLoading').show();
        return false;
      }

      var content = new Element('div', {'id' : 'guiLoading'}).inject(document.body);
      new Asset.image(loading, {
        onload : function(){
          this.inject(content);
        }
      });

      if(!$(options.element)) return;
      var size    = options.element.getSize();
      content.setStyles({'width':size.x, 'height':size.y});
      content.position({relativeTo : options.element});
    },

    /////////////////////////////////////////////////////////////////
    //  Metodos de paginas
    /////////////////////////////////////////////////////////////////

    pageLoad : function(page){
      if(page == this.page) return false;
      this.guiLoading();

      var slides_url = this.options.BASE_URL + this.options.TEMPLATE_URL + this.options.TEMPLATE + '/images/' + this.options.LANG + '/slides/';
      var fn = false;
      eval("fn = this.pageLoad" + page.capitalize());
      if($type(fn) == 'function'){
        new Fx.Tween(this.options.container, {
          duration:300,
          onComplete : function(){
            this.options.container.empty();
            fn.attempt(slides_url, this);
          }.bind(this)
        }).start('opacity', 0);
      }

      var uri = new URI(location.href);
      uri.set('fragment', page);
      uri.go();
    },

    pageLoadIndex : function(url){
      if(this.page == 'index') return false;
      var container = this.options.container;
      var self = this;

      var portfolio = new Element('div', {'class':'portfolioIndex'});

      new Asset.image(url + 'slide01.png', {
        onload : function(){
          this.inject(container);
          self.guiLoading(1);
          portfolio.inject(container);
          portfolio.position({relativeTo:this, offset:{x:40, y:185}, position:'leftTop', edge:'leftTop'});
          self.Portfolio(new Date().get('year'), portfolio);
          new Fx.Tween(container, {duration:300}).start('opacity', 1);
        }
      });

      this.page = 'index';
      this.navCurrent();
    },

    pageLoadAbout : function(url){
      if(this.page == 'about') return false;
      var container = this.options.container;
      var self      = this;

      new Asset.image(url + 'slide02.png', {
        onload : function(){
          this.inject(container);
          self.guiLoading(1);
          new Fx.Tween(container, {duration:300}).start('opacity', 1);
        }
      });

      this.page = 'about';
      this.navCurrent();
    },

    pageLoadPortfolio : function(url){
      if(this.page == 'portfolio') return false;
      var container = this.options.container;
      var self      = this;

      var portfolio = new Element('div', {'class':'portfolioPortfolio'});

      new Asset.image(url + 'slide03.png', {
        onload : function(){
          this.inject(container);
          self.guiLoading(1);

          portfolio.inject(container);
          portfolio.position({relativeTo:this, offset:{x:22, y:62}, position:'leftTop', edge:'leftTop'});
          self.Portfolio(0, portfolio);

          new Fx.Tween(container, {duration:300}).start('opacity', 1);
        }
      });

      this.page = 'portfolio';
      this.navCurrent();
    },

    pageLoadServices : function(url){
      if(this.page == 'services') return false;
      var self = this;
      var container = this.options.container;
      var services  = new Element('div', {
        'class' : 'services',
        'id'    : 'services'
      }).inject(container);

      new Asset.image(url + 'slide04.png', {
        'class' : 'services_background',
        onload : function(){
          this.inject(services);
          new Fx.Tween(container, {duration:300}).start('opacity', 1);
        }
      });

      var services_slides = new Element('ul', {'class':'services-list'});
      var services_images = [];
      var loaded_services = [];
      for(var i=1; i<8; i++){
        services_images.push(url + 'Slide04-sector0'+i+'.png');
      }
      new Asset.images(services_images, {
        onProgress : function(c, i){
          this.hide();
          loaded_services[i] = new Element('li').adopt(this);
        },
        onComplete : function(){
          self.guiLoading(1);
          loaded_services.each(function(item){ item.inject(services_slides) });
          services_slides.inject(services);
          self.servicesAnim();
        }
      })

      this.page = 'services';
      this.navCurrent();
    },

    servicesAnim : function(){
      this.clearChain();
      var chains = [];
      $$('#services ul li img').each(function(item){
        var fn = function(){ new Fx.Reveal(item, {duration:500, mode:'both', transition:'back:out', onComplete:function(){this.callChain()}.bind(this) }).reveal() }.bind(this);
        chains.push(fn);
      }, this);

      this.chain(chains);
      this.callChain();
    },

    pageLoadContact : function(url){
      if(this.page == 'contact') return false;
      var container = this.options.container;
      var self      = this;
      var contact   = new Element('div', {
        'class' : 'contact',
        'id'    : 'contact'
      }).inject(container);

      var images  = [url + 'slide05-phone.png', url + 'slide05-email.png'];
      var lImages = [];

      new Asset.image(url + 'slide05.png', {
        'class' : 'slideContact',
        onload  : function(){
          this.inject(contact);
          var fc = new Element('div', {'class':'formContainer'}).inject(contact);
          fc.position({relativeTo:contact, position:'centerTop', edge:'centerTop', offset:{y:154}});
          self.contactForm(fc);

          new Asset.images(images, {
            onProgress : function(img, i){ lImages[i] = this;},
            onComplete : function(){
              var phone = lImages[0];
              var email = lImages[1];
              var link  = new Element('a', {'href':'mailto:info@planetadeleste.com'}).adopt(email);
              phone.inject(contact).position({relativeTo:contact, position:'leftTop', edge:'leftTop', offset:{y:63}});
              link.inject(contact).position({relativeTo:contact, position:'leftTop', edge:'leftTop', offset:{y:63 + phone.height}});
              this.guiLoading(1);
              new Fx.Tween(container, {duration:300}).start('opacity', 1);
            }.bind(self)
          });
        }
      });

      this.page = 'contact';
      this.navCurrent();
    },

    contactForm : function(el){
      if(!el) return;
      var f     = new Element('form').inject(el);
      new Element('input', {'type':'hidden', 'name':'referer', 'value':'form.php'}).inject(f);
      var cols  = new Element('div', {'class':'columns'}).inject(f);
      var left  = new Element('div', {'class':'col2'}).inject(cols);
      var right = new Element('div', {'class':'col2'}).inject(cols);
      new Element('div', {'class':'clear'}).inject(cols);

      var cName      = new Element('div', {'class':'formRow'}).inject(left);
      var cNameTitle = new Element('div', {'class':'colTitle', 'html':this.tr('Name')}).inject(cName);
      var cNameInput = new Element('div', {'class':'colInput'}).adopt(new Element('input', {'type':'text', 'name':'name', 'id':'Name', 'class':'inputText'})).inject(cName);
      new Element('div', {'class':'clear'}).inject(cName);

      var cEmail      = new Element('div', {'class':'formRow'}).inject(left);
      var cEmailTitle = new Element('div', {'class':'colTitle', 'html':this.tr('Email')}).inject(cEmail);
      var cEmailInput = new Element('div', {'class':'colInput'}).adopt(new Element('input', {'type':'text', 'name':'email', 'id':'Email', 'class':'inputText required validate-email'})).inject(cEmail);
      new Element('div', {'class':'clear'}).inject(cEmail);

      var cPhone      = new Element('div', {'class':'formRow'}).inject(left);
      var cPhoneTitle = new Element('div', {'class':'colTitle', 'html':this.tr('Phone')}).inject(cPhone);
      var cPhoneInput = new Element('div', {'class':'colInput'}).adopt(new Element('input', {'type':'text', 'name':'phone', 'id':'Phone', 'class':'inputText'})).inject(cPhone);
      new Element('div', {'class':'clear'}).inject(cPhone);

      var cComment      = new Element('div', {'class':'formRow'}).inject(right);
      var cCommentTitle = new Element('div', {'class':'colTitle', 'html':this.tr('Comments')}).inject(cComment);
      var cCommentInput = new Element('div').adopt(new Element('textarea', {'name':'comments', 'id':'comments', 'class':'TextArea'})).inject(cComment);
      new Element('div', {'class':'clear'}).inject(cComment);

      var cButton      = new Element('div', {'class':'formRow toRight'}).inject(right);
      var cButtonInput = new Element('input', {'type':'submit', 'name':'btnGo', 'class':'inputButton', 'value':this.tr('Send')}).inject(cButton);

      f.getElements('input, textarea').each(function(item){ if(item.hasClass('inputButton')) return; new InputFocus(item);});
      f.addEvent('submit', this.sendContactForm.pass(f, this));
    },

    sendContactForm : function(form){
      var requireds = new InputValidator('required', {
        errorMsg: FormValidator.getMsg.pass('email'),
        test: function(element){

          if(element.hasClass('validate-email')){
            return !FormValidator.getValidator('IsEmpty').test(element) && (/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i).test(element.get('value'));
          }

          return !FormValidator.getValidator('IsEmpty').test(element)
        }
      });

      if(!requireds.test($('Email'))){
        this.msg(form, this.tr('contact.error.email'), form.getElement('.columns'), 2500);
        return false;
      }

      var w = new Waiter(form).start();
      new Request.HTML({
        'url' : '_lib/phpmailer-fe.php',
        onComplete : function(rt, re, rh){
          if(rh.split('\n')[0].contains('ok')){
            this.msg(form, this.tr('contact.thanks'), form.getElement('.columns'));
            form.reset();
          }
          else{
            this.log(rh);
          }
          w.stop();
        }.bind(this)
      }).post(form);
      return false;
    },

    msg : function(el, txt, hide, delay){
      if(!el) return;
      delay = (!$defined(delay)) ? 5000 : delay;
      var m = new Element('div', {'class':'Message', 'html':txt}).inject(el, 'top');
      if($(hide)){ $(hide).hide();}
      (function(){ new Fx.Tween(m, { onComplete:function(){
        m.destroy();
        if($(hide)){ $(hide).show();}
      } }).start('opacity', 0); }).delay(delay, this);
    },

    /////////////////////////////////////////////////////////////////
    //  Portfolio
    /////////////////////////////////////////////////////////////////

    Portfolio : function(year, el){
      if(!$(el)) return false;
      this.PortfolioContainer = el;

      new Request.JSON({
        url:'gallery.php',
        onSuccess: this.PortfolioResponse.bind(this)
      }).get({'year':year, 'mod':'portfolio'});
    },

    PortfolioWrapper : function(){
      this.PortfolioContainer.empty();
      new Element('div', {'class':'PortfolioWrapper'}).inject(this.PortfolioContainer);
    },

    PortfolioResponse : function(data){
      this.PortfolioData = data;
      this.PortfolioWrapper();
      this.PortfolioThumbs();
    },

    PortfolioThumbs : function(){
      var self   = this;
      var years  = $H(this.PortfolioData.years);
      var thumbs = [];
      var obj_thumbs = [];
      years.each(function(projects, year){
        projects.each(function(project){
          thumbs.include(this.options.BASE_URL + this.PortfolioData.dir + year + '/' + project + '/' + this.PortfolioData.thumb + '.jpg');
          obj_thumbs.include({'year':year, 'project':project});
        }, this);
      }, this);

      var loadedImages = [];
      new Asset.images(thumbs, {
        onProgress : function(loaded, current){
          loadedImages[current] = this;
          self.Loading(self.PortfolioContainer, (loaded+1), thumbs.length);
        },
        onComplete : function(){
          this.Loading(true);
          var wp = this.PortfolioContainer.getElement('.PortfolioWrapper');
          if(!wp) return;
          loadedImages.each(function(thumb, i){
            var tn = this.PortfolioThumb(thumb, obj_thumbs[i].project, obj_thumbs[i].year);
            if(!tn) return;
            wp.adopt(tn);
            if(this.PortfolioContainer.getStyle('overflow') == 'hidden') wp.setStyle('width', (tn.getDimensions().width) * (i + 1) + 5);
            tn.getElement('.PortfolioThumbImage').position({relativeTo:tn});
          }, this);

          wp.adopt(new Element('div', {'class':'clear'}));

          if(wp.getSize().x < this.PortfolioContainer.getSize().x && this.PortfolioContainer.getStyle('overflow') == 'hidden')
            wp.position({relativeTo:this.PortfolioContainer});
        }.bind(this)
      });
    },

    PortfolioThumb : function(img, project, year){
      var thumbContainer  = new Element('div', {'class':'PortfolioThumb'});
      var thumbBackground = new Element('div', {'class':'PortfolioThumbBackground', 'styles':{ 'opacity':0.3 }}).inject(thumbContainer);
      var thumbAnchor     = new Element('a', {'href':'javascript:void(0)'}).inject(thumbContainer);
      var thumbImage      = new Element('div', {'class':'PortfolioThumbImage'}).adopt(img).inject(thumbAnchor);

      thumbAnchor.store('project', project);
      thumbAnchor.store('year', year);

      thumbAnchor.addEvent('click', this.PortfolioLink.pass(thumbAnchor, this));
      return thumbContainer;
    },

    PortfolioLink : function(el){
      var year = el.retrieve('year');
      var project = el.retrieve('project');

      this.PortfolioShow(year, project);

      return false;
    },

    PortfolioShow : function(year, project){
      new Request.JSON({
        url:'gallery.php',
        onSuccess: this.PortfolioShowResponse.bind(this)
      }).get({'year':year, 'project':project, 'mod':'portfolioShow'});
    },

    PortfolioShowResponse : function(data){
      if($type(data) != 'object') return;
      if(!$defined(data.data) || !$defined(data.url) || !$defined(data.images)) return;

      this.PortfolioClose();

      var info = data.data;

      var pShow       = new Element('div', {'class':'PortfolioShow', 'id':'PortfolioShow'}).inject(document.body);
      var pClose      = new Element('div', {'class':'PortfolioClose', 'id':'PortfolioClose', 'title':this.tr('Close')}).inject(pShow);
      var pImage      = new Element('div', {'class':'PortfolioImages'}).inject(pShow);
      var pContent    = new Element('div', {'class':'PortfolioContent'}).inject(pShow);
      var pLeft       = new Element('div', {'class':'PortfolioContentLeft'}).inject(pContent);
      var pRight      = new Element('div', {'class':'PortfolioContentRight'}).inject(pContent);
      var pReview     = new Element('div', {'class':'PortfolioContentRight'}).inject(pContent);
      var pClear      = new Element('div', {'class':'clear'}).inject(pContent);
      var pLeftInner  = new Element('div', {'class':'PortfolioInner'}).inject(pLeft);
      var pRightInner = new Element('div', {'class':'PortfolioInner'}).inject(pRight);
      var pReviewInner = new Element('div', {'class':'PortfolioInner'}).inject(pReview);

      var pName    = new Element('h2', {'html':info.Title}).inject(pLeftInner);
      var pDate    = new Element('div', {'class':'PortfolioContentDate', 'html':info.Date}).inject(pLeftInner);
      if(info.Info) var pInfo = new Element('div', {'class':'PortfolioContentInfo', 'html':info.Info}).inject(pLeftInner);
      if(info.Link) var pLink = new Element('a', {'href':info.Link, 'target':'_blank', 'html':info.Link}).inject(pLeftInner);
      var pRightTitle = new Element('h3', {'html':this.tr('Discipline')}).inject(pRightInner);
      var pDiscipline = new Element('ul', {'class':'PortfolioContentDiscipline'}).inject(pRightInner);
      info.Discipline.each(function(item){
        var li = new Element('li').inject(pDiscipline);
        new Element('a', {'href':'javascript:void(0)', 'html':item}).inject(li);
      });

      new Element('h3', {'html':this.tr('Review')}).inject(pReviewInner);
      if(info.Review){
        new Element('div', {'html':info.Review, 'class':'PortfolioReview'}).inject(pReviewInner);
      }

      pShow.position({relativeTo:$(document.body), position:'centerTop', edge:'centerTop', offset:{y:80}});
      pClose.position({relativeTo:pShow, position:'rightTop', edge:'center'});
      pClose.addEvent('click', this.PortfolioClose.pass('', this));

      // Creo el fondo
      var pBTop = new Element('div', {'class':'PortfolioTop', 'id':'PortfolioBG'}).inject(document.body);
      var pBBot = new Element('div', {'class':'PortfolioBot'}).inject(pBTop);
      var pBMid = new Element('div', {'class':'PortfolioMid'}).inject(pBBot);
      pBMid.setStyle('height', pShow.getDimensions().height + 10);
      pBTop.setStyle('opacity', 0.5);
      pBTop.position({relativeTo:pShow, offset:{y:-7}});

      // Creo el Modal
      var pModal = new Element('div', {'class':'PortfolioBackground', 'id':'PortfolioBackground'}).inject(document.body);
      var url    = this.options.BASE_URL + this.options.TEMPLATE_URL + this.options.TEMPLATE +'/images/' + this.options.backgrounds[this.resolution];
      pModal.setStyles({
        'width'  : $(document.body).getDimensions().width,
        'height' : $(document.body).getDimensions().height,
        'background-image' : 'url('+url+'bg'+this.page.capitalize()+'.jpg)'
      });
      pModal.position({relativeTo:$(document.body), position:'centerTop', edge:'centerTop'});
      pModal.addEvent('click', this.PortfolioClose.pass('', this));

      var pImages = [];
      data.images.each(function(img){
        pImages.include(data.url + img);
      });

      this.guiLoading(false, {'element':pImage, 'image':'loading2.png'});
      this.PortfolioScreens(pImages, pImage);

    },

    PortfolioScreens : function(images, el, current){
      if($defined(this.PortfolioTimer)){
        $clear(this.PortfolioTimer);
      }

      if($type[images[0]] == 'array' && !$defined(el) && !$defined(current)){
        el      = images[1];
        current = images[2];
        images  = images[0];
      }
      current = (!$defined(current)) ? 0 :current;
      if(images.length == 0) return;
      if(current == images.length) current = 0;
      if(!images[current] || !$(el)) return;

      var self = this;
      new Asset.image(images[current], {
        onload : function(){
          self.guiLoading(true);
          var cim = el.getElement('img');
          this.inject(el);
          if(cim){
            new Fx.Tween(cim, {onComplete : function(){ cim.destroy() }}).start('opacity', 0);
          }
          new Fx.Tween(this, {
            onComplete : function(){
              if(images.length > 1)
                self.PortfolioTimer = self.PortfolioScreens.delay(3000, self, [images, el, current+1])
            }
          }).start('opacity', 0, 1);
        }
      });
    },

    PortfolioClose : function(){
      var p = $('PortfolioShow');
      var b = $('PortfolioBG');
      var m = $('PortfolioBackground');
      var c = $('PortfolioClose');
      if(p) p.destroy();
      if(b) b.destroy();
      if(m) m.destroy();
      if(c) c.destroy();
      if(this.PortfolioTimer) $clear(this.PortfolioTimer);
      this.guiLoading(true);
    },

    /////////////////////////////////////////////////////////////////
    //  Metodos de utilidad
    /////////////////////////////////////////////////////////////////

    /**
     *  Traductor
     */
    tr : function(str){
      var Lang = {
        'es' : {
          'DISCIPLINE' : 'Disiplina',
          'CLOSE'      : 'Cerrar',
          'REVIEW'     : 'Rese&ntilde;a',
          'NAME'       : 'Nombre',
          'EMAIL'      : 'Email',
          'PHONE'      : 'Teléfono',
          'COMMENTS'   : 'Comentarios',
          'SEND'       : 'Enviar',
          'CONTACT.THANKS'      : 'Muchas gracias,<br>su mensaje ha sido enviado correctamente.<br><br>En breve responderemos su consulta.',
          'CONTACT.ERROR.EMAIL' : '<h3>ERROR</h3>No ha especificado un email valido.'
        },
        'en' : {
          'DISCIPLINE' : 'Discipline',
          'CLOSE'      : 'Close',
          'REVIEW'     : 'Review',
          'NAME'       : 'Name',
          'EMAIL'      : 'Email',
          'PHONE'      : 'Phone',
          'COMMENTS'   : 'Comments',
          'SEND'       : 'Send',
          'CONTACT.THANKS'      : 'Thank you,<br>your message has been sent.<br><br>We will get back to you shortly.',
          'CONTACT.ERROR.EMAIL' : '<h3>ERROR</h3>You have not specified a valid email.'
        }
      };
      Lang = $H(Lang[this.options.LANG]);
      return (Lang.has(str.toUpperCase())) ? Lang.get(str.toUpperCase()) : str;
    },

    /**
     *  Lenguaje
     */
    LangInit : function(){
      if(!$('languaje')) return;
      if(!$('flang')) return;

      var langs = $('languaje').getElements('.lang-item');

      langs.each(function(lang){
        var l = lang.get('rel');
        if(!this.options.LANGS.contains(l)) return;
        if(l == this.options.LANG){
          lang.hide();
        }
        else {
          lang.addEvent('click', this.LangChange.pass(l, this));
        }
      }, this)
    },

    LangChange : function(lang){
      if(!$('flang')) return;
      if(!$('lang')) return;
      var uri = new URI(location.href);

      $('lang').set('value', lang);
      if(uri.get('fragment'))
        $('lang_go').set('value', '#' + uri.get('fragment'));
      else if(uri.get('path') && uri.get('path') != 'index.php')
        $('lang_go').set('value', '#' + uri.get('path'));

      $('flang').submit();
    },

    Loading : function(element, loaded, total){
      var options = {};
      var op      = {'offset':{y:0, x:0}, 'class':'utilLoading', 'message':this.tr('Loading')+'...' }

      if($type(element) == 'object'){
        options = element;
        if(!$defined(options.element) || !$defined(options.loaded) || !$defined(options.total)) return;
        element = options.element;
        loaded  = options.loaded;
        total   = options.total;
      }
      options = $H($merge(op, options));

      if(($type(element) != 'element' && $type(element) != 'boolean') || loaded > total) return false;
      if(!$('utilLoading') && !this.utilLoading){
        this.utilLoading = new Element('div', {'id':'utilLoading', 'class':options.get('class')}).inject(document.body);
        new Element('div', {'class':'utilLoadingText', 'html':'loading...'}).inject(this.utilLoading);
        var barWrapper = new Element('div', {'class' : 'utilLoadingBarWrapper'}).inject(this.utilLoading);
        new Element('div', {'class':'utilLoadingBar'}).inject(barWrapper);
      }

      this.utilLoading.removeClasses($H(op).get('class'));
      this.utilLoading.addClass(options.get('class'));
      this.utilLoading.position({relativeTo : element, offset:options.get('offset')});

      if($type(element) == 'boolean'){
        this.utilLoading.destroy();
        this.utilLoading = false;
        return;
      }

      var t = this.utilLoading.getElement('.utilLoadingText');
      var b = this.utilLoading.getElement('.utilLoadingBar');
      var w = this.utilLoading.getElement('.utilLoadingBarWrapper');

      if(!t || !b || !w) return;
      var wsize   = w.getDimensions().width;
      var wpart   = wsize / total;
      var percent = ((loaded / total) * 100).toInt();

      t.set('html', percent + '%');
      b.setStyle('width', wpart*loaded);
    },

    utilGetExt : function(file){
      return file.split('.').getLast();
    },

    utilRemoveExt : function(file){
      file = this.utilGetFile(file);
      return file.substr(0, file.length - (this.utilGetExt(file).length + 1) );
    },

    utilGetFile : function(file){
      return file.split('/').getLast();
    },

    domReady : function(){
      this.options.container = $(this.options.container);
      this.guiLoading();
      this.setNavigation();
      this.guiStart();
      this.LangInit();
    }
 });

//  var planeta = new Planeta();