var App = window.App||{};
var UI = window.UI||{};

function when(obj, fn) {
  if (Object.isString(obj)) obj = /^[\w-]+$/.test(obj) ? $(obj) : $(document.body).down(obj)
  if (Object.isArray(obj) && !obj.length) return
  if (obj) fn(obj)
}

(function(){
  var id = 0, head = $$('head')[0], global = this;
  global.getJSON = function(url, callback) {
    var script = document.createElement('script'), token = '__jsonp' + id;
    global[token] = callback;
    script.src = url.replace(/\?(&|$)/, '__jsonp' + id + '$1');
    script.onload = function() {
      script.remove();
      script = null;
      delete global[token];
    };
    head.appendChild(script);
    id++;
  }
})();

(function(){
  function wheel(event){
    var delta;
    // normalize the delta
    if(event.wheelDelta) // IE & Opera
      delta = event.wheelDelta / 120;
    else if (event.detail) // W3C
      delta =- event.detail / 3;
    if(!delta)
      return;
    var custom_event = event.element().fire('mouse:wheel',{
      delta: delta
    });
    if(custom_event.stopped){
      event.stop();
      return false;
    }
  }
  document.observe('mousewheel',wheel);
  document.observe('DOMMouseScroll',wheel);
})();

App.Lightbox = function(){
  var current;
  var groups = $H({});
  var Lightbox = {};
  var selects;

  var Group = Class.create(Enumerable, {
    initialize : function(nodes){
      this.length = 0;
      this.first = null;
      this.last = null;
      $A(nodes).each(function(node){
        this.append({
          data : node,
          prev : null,
          next : null
        });
      }, this);
    },
    append : function(node){
      if(this.first === null){
        this.first = node;
        this.last = node;
      }else{
        node.prev = this.last;
        this.last.next = node;
        this.last = node;
      }
      this.length++;
    },
    _each : function(iterator){
      var node = this.first, n = this.length;
      for (var i = 0; i < n; i++) {
        iterator(node, i);
        node = node.next;
      }
    }
  });

  function get_group(group){
    return groups.get(group)||groups.set(group, new Group());
  }

  function add_image(image){
    var group = get_group(image.rel||'default');
    group.append({
      data : {
        url : image.href
      },
      prev : null,
      next : null
    });
    image.observe('click', show);
  }

  function show(e){
    var image = Event.findElement(e, 'a.lightbox');
    if(image){
      Event.stop(e);
      var object = get_group(image.rel||'default').find(function(_image){
        return _image.data.url == image.href;
      });

      Lightbox.controlsOuter.setStyle({
        width: "auto"
      });

      Lightbox.element.setStyle({
        opacity: 1
      });
      Lightbox.controls.hide();
      Lightbox.img.hide();

      var viewport = document.viewport.getDimensions();
      var scroll = document.viewport.getScrollOffsets();

      Lightbox.image.setStyle({
        height: '200px',
        width: '200px',
        overflow: 'hidden'
      });

      Lightbox.element.show();

      var size = $(Lightbox.element).getDimensions();
      var _size = $(Lightbox.image).getDimensions();

      var left = (viewport.width/2)-(size.width/2);

      var top = Math.max(10, (viewport.height/2)-(size.height/2)+scroll.top);

      Lightbox.element.setStyle({
        left : left+"px",
        top : top+"px"
      });
      load(object);
    }
  }

  function next(e){
    Event.stop(e);
    if(current.next){
      load(current.next);
    }
  }

  function prev(e){
    Event.stop(e);
    if(current.prev){
      load(current.prev);
    }
  }

  function close(e){
    Event.stop(e);
    new Effect.Opacity(Lightbox.element, {
      duration: 0.5,
      from: 1,
      to: 0,
      afterFinish : function(){
        Lightbox.element.hide();
      }.bind(this)
    });
  }

  function load(object){
    Lightbox.close.hide();
    Lightbox.title.hide();

    new Effect.BlindUp(Lightbox.controls, {
      duration: 0.5,
      afterFinish : function(){
        new Effect.Opacity(Lightbox.img, {
          duration: 0.5,
          from: 1, to :0,
          afterFinish : function(){
            Lightbox.img.hide();
            var img = new Image();
            img.onload = onload.curry(object);
            img.src = object.data.url;
          }
        });
      }
    });
  }

  function onload(object){
    var viewport = document.viewport.getDimensions();
    var scroll = document.viewport.getScrollOffsets();

    var size = $(Lightbox.element).getDimensions();
    var _size = $(Lightbox.image).getDimensions();

    var left = (viewport.width/2)-((size.width-_size.width+this.width)/2);
    var top = Math.max(10, (viewport.height/2)-((size.height-_size.height+this.height)/2)+scroll.top);

    var str = "left:"+left+"px;top:"+top+"px;";
    var _str = "width:"+this.width+"px;height:"+this.height+"px;";

    new Effect.Parallel([new Effect.Morph(Lightbox.element, {style : str}), new Effect.Morph(Lightbox.image, {style: _str})],
        {
          afterFinish : function(){
            Lightbox.controlsOuter.setStyle({
              width: this.width+"px"
            });

            Lightbox.close.show();
            (object.prev) ? Lightbox.prev.show() : Lightbox.prev.hide();
            (object.next) ? Lightbox.next.show() : Lightbox.next.hide();
            Lightbox.img.src = object.data.url;
            Lightbox.img.show();
            new Effect.Opacity(Lightbox.img, {
              duration: 0.5,
              from: 0,
              to: 1,
              afterFinish : function(){
                new Effect.BlindDown(Lightbox.controls, {
                  duration: 0.5
                });
              }
            });
            current = object;
          }.bind(this)
        }
    );
  }

  function hideSelects(){
    if(Prototype.Browser.IE){
      selects.invoke('hide');
    }
  }

  function showSelects(){
    if(Prototype.Browser.IE){
      selects.invoke('show');
    }
  }

  function build(){
    //var lightbox = new Element('div', {className: 'lightbox'}).update('<div class="lightbox_inner"><div class="image"><div class="image_inner"><div class="loader"></div><img /></div></div><div class="controls_outer"><div class="controls"><a href="#" class="prev">Previous</a><a href="#" class="next">Next</a></div></div><div class="title">Title</div><div class="close"><a href="#" class="close">Close</a></div></div>');

    var lightbox = new Element('div', {className: 'view-modal clearfix shadow'}).update('<div class="view-modal-top"><div></div></div><div class="view-modal-inner-1"><div class="view-modal-inner-2"><div class="view-modal-inner-3"><div class="view-modal-inner-4"><div class="view-modal-content"><div class="image_inner"><div class="loader"></div><img /></div></div><div class="controls_outer"><div class="controls"><a href="#" class="prev">Previous</a><a href="#" class="next">Next</a></div></div><div class="title">Title</div><div class="close"><a href="#" class="close">Close</a></div></div></div></div></div><div class="view-modal-bottom"><div></div></div>');


    Lightbox.element = lightbox;
    Lightbox.img = lightbox.down('img');
    Lightbox.image = lightbox.down('div.image_inner');
    Lightbox.loader = lightbox.down('div.loader');
    Lightbox.controls = lightbox.down('div.controls');
    Lightbox.controlsOuter = lightbox.down('div.controls_outer');
    Lightbox.title = lightbox.down('div.title');
    Lightbox.next = lightbox.down('a.next');
    Lightbox.prev = lightbox.down('a.prev');
    Lightbox.close = lightbox.down('a.close');

    Lightbox.next.observe('click', next);
    Lightbox.prev.observe('click', prev);
    Lightbox.close.observe('click', close);

    lightbox.hide();
    document.body.appendChild(lightbox);
  }

  return {
    initialize : function(){
      var selects = $A(document.getElementsByTagName('select'));
      this.add_images($$('a.lightbox'));
      build();
    },
    add_images : function(links){
      $A(links).each(function(link){
        add_image(link);
      });
    }
  }
}();


Element.addMethods({
  makeInvisible : function(element){
    return $(element).setStyle({
      'visibility' : 'hidden'
    });
  },
  makeVisible : function(element){
    return $(element).setStyle({
      'visibility' : ''
    });
  }
});

UI.Modal = Class.create({
  initialize : function(options){
    this.options = Object.extend({
      className : 'ui-modal',
      minHeight: 200,
      minWidth : 200,
      offset : 50,
      rootElement : $$('body').first()
    }, options||{});

    this.build();
  },
  build : function(){
    this.modal = new Element('div', {className: this.options.className}).setStyle({
      'overflow' : 'visible',
      'position' : 'absolute',
      'zIndex' : 500
    }).hide();
    this.content = new Element('div', {className: 'ui-modal-content'});
    this.modal.insert(this.content);
    this.close = new Element('a', {href: '#', className: 'ui-modal-close'}).update('Close');
    this.modal.insert(this.close);
    this.options.rootElement.insert(this.modal);
    this.close.observe('click', this.hide.bindAsEventListener(this));
  },
  position : function(){
    //this.resize(this.modal.getDimensions());
  },
  getDimensions : function(dimensions){
    var viewport = document.viewport.getDimensions();
    var scroll = document.viewport.getScrollOffsets();
    var style = this.modal.style;

    var width = Math.min((viewport.width-(this.options.offset*2)), Math.max(dimensions.width, this.options.minWidth));
    style.width = width+'px';
    var height = Math.min((viewport.height-(this.options.offset*2)), Math.max(dimensions.height, this.options.minHeight));

    style.height = height+'px';

    var top = Math.max((this.options.offset+scroll.top), (scroll.top+(viewport.height/2)-(height/2)));
    style.top = top+'px';
    var left = Math.max((this.options.offset+scroll.left), (scroll.left+(viewport.width/2)-(width/2)));
    style.left = left+'px';

    var d = {
      height: height+'px',
      left: left+'px',
      top: top+'px',
      width: width+'px'
    };

    if(!this.d){
      var h = this.options.minHeight;
      var w = this.options.minWidth;
      var t = Math.max((this.options.offset+scroll.top), (scroll.top+(viewport.height/2)-(h/2)));
      var l = Math.max((this.options.offset+scroll.left), (scroll.left+(viewport.width/2)-(w/2)));
      style.width = w+'px';
      style.height = h+'px';
      style.top = t+'px';
      style.left = l+'px';
    }else{
      this.modal.setStyle(this.d);
      this._d = this.d;
    }

    this.d = d;
    return d;
  },
  show : function(){
    this.modal.makeInvisible().show();
    this.position();
    this.modal.makeVisible();
  },
  hide : function(){

  }
});

UI.Lightbox = Class.create(UI.Modal, {
  initialize : function($super, selector, options){
    $super(options);

    this.overlay = new Element('div', {className: 'ui-overlay'}).setStyle({
      background: '#000000',
      opacity: 0.5,
      display: 'none'
    });
    this.modal.insert({before:this.overlay});


    this.wrapper = new Element('div', {className:'lightbox'}).update('<div class="t"><div class="tl"></div><div class="tr"></div></div><div class="l"><div class="r"></div></div><div class="f"><div class="fl"></div><div class="fr"></div></div>');
    this.content.insert(this.wrapper);
    this.el = this.wrapper.down('div.r');

    this.selector = selector;
    document.observe('click', this.onclick.bindAsEventListener(this));
    this.setup();
  },
  setup : function(){
    this._slideshow = Class.create(UI.Slideshow, {
      initialize : function($super, element, slides, options){
        $super(element, slides, options);
      },
      onLoad : function(image){
        var slideshow = this.slideshow;

        slideshow.element.makeInvisible();
        slideshow.image1.src = image.src;
        slideshow.div2.hide();
        slideshow.status.update(slideshow.options.statusText.interpolate({
          index: slideshow.index+1,
          count: slideshow.slides.size()
        }));

        var d = this.getDimensions({
          height: image.height+76,
          width: image.width+30
        });


        if(d){

          var _d = {
            width : image.width+'px',
            height : image.height+31+'px'
          };

          slideshow.div1.hide();
          slideshow.element.makeVisible();

          if(slideshow.image2.src){
            slideshow.div2.show();
            new Effect.Fade(slideshow.div2, {
              queue: 'end'
            });
          }


          if(Object.toQueryString(d)!=Object.toQueryString(this._d)){
            new Effect.Parallel([
              new Effect.Morph(this.modal, {
                style : d,
                sync: true
              }),
              new Effect.Morph(slideshow.element, {
                style : _d,
                sync: true
              })
            ], {
              queue: 'end'
            });
          }

          new Effect.Appear(slideshow.div1, {
            queue: 'end',
            afterFinish : function(){
              this.element.setStyle({
                height: _d.height,
                width : _d.width
              });
              this.image2.src = this.image1.src;
              if(this.playing){
                this._play();
              }
              this.controls.makeVisible();
            }.bind(slideshow)
          });

        }
      }.bind(this)
    });
  },
  onclick : function(e){

    var element = e.findElement(this.selector), index = 0, slides = $A();

    if(element){
      e.stop();

      var h = document.body.clientHeight;

      this.overlay.setStyle({
        top: 0,
        height: h+'px',
        left: 0,
        position: 'absolute',
        width: '100%',
        zIndex: 400,
        opacity: 0
      }).show();

      new Effect.Fade(this.overlay, {
        from: 0,
        to: 0.5,
        queue: 'end'
      });

      if(rel = element.rel){
        $$(this.selector+'[rel='+rel+']').each(function(slide, i){
          slides.push([slide.href, slide.title]);
          if(slide==element){
            index = i;
          }
        });
        this.show();
        this.slideshow = new this._slideshow(this.el, slides, {
          index: index
        });
        this.slideshow.element.setStyle({
          height: '124px',
          width: '170px'
        });
        this.slideshow.show();
      }else{
        this.load(element.href, element.title);
      }
    }
  },
  load : function(src, title){
    var image = new Image();
    image.onload = this.onLoad.bind(this, image);
    image.src = src;
  },
  onLoad : function(image){
    this.el.update(image);

    var d = this.getDimensions({
      height: image.height+45,
      width: image.width+30
    });

    this.modal.setStyle(d);

    new Effect.Appear(this.modal);
  },
  hide : function(e){
    if(e){
      e.stop();
    }
    new Effect.Fade(this.modal, {
      afterFinish : function(){
        if(this.slideshow){
          this.slideshow.destroy();
        }
        this.d = this._d = {};
      }.bind(this),
      queue : 'end'
    });
    new Effect.Fade(this.overlay, {
      from: 0.5,
      to: 0,
      queue: 'end'
    });
  }
});


UI.Videobox = Class.create(UI.Lightbox, {
  initialize : function($super, selector, options){
    $super(selector, options);
  },
  setup : function(){

  },
  onclick : function(e){
    var element = e.findElement(this.selector);

    if(element){
      e.stop();

      var h = document.body.clientHeight;

      this.overlay.setStyle({
        top: 0,
        height: h+'px',
        left: 0,
        position: 'absolute',
        width: '100%',
        zIndex: 400,
        opacity: 0
      }).show();

      new Effect.Fade(this.overlay, {
        from: 0,
        to: 0.5,
        queue: 'end'
      });

      var video = '<div style="background:#eeece4;"><object width="640" height="385"></param><param name="movie" value="#{src}"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><param name="rel" value="0"><embed src="#{src}" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385" rel="0"></embed></object></div>'.interpolate({
        src : element.href
      });

      this.el.update(video);

      this.modal.setStyle(this.getDimensions({
        height: 405,
        width: 685
      }));

      new Effect.Appear(this.modal);

    }

  }
});

UI.Slideshow = Class.create({
  initialize : function(element, slides, options){
    this.slides = slides;
    this.root = $(element);

    this.options = Object.extend({
      className : 'ui-slideshow',
      controlsClassName : 'ui-slideshow-controls',
      delay : 5,
      index: 0,
      onLoad : Prototype.emptyFunction,
      onPause : Prototype.emptyFunction,
      onPlay : Prototype.emptyFunction,
      nextClassName : 'ui-slideshow-next',
      nextText : 'Next',
      pauseClassName : 'ui-slideshow-pause',
      pauseText : 'Pause',
      playClassName : 'ui-slideshow-play',
      playText : 'Play',
      previousClassName : 'ui-slideshow-previous',
      previousText : 'Previous',
      statusClassName : 'ui-slideshow-status',
      statusText : 'Image #{index} of #{count}'
    }, options||{});

    this.index = this.options.index;

    this.build();
    //this.show();
  },
  build : function(){
    this.element = new Element('div', {className: this.options.className}).update('<div><div><img /></div><div><img /></div></div><div class="ui-slideshow-controls"><ul class="ui-slideshow-player-controls"><li class="#{playClassName}"><a href="#">#{playText}</a></li><li class="#{pauseClassName}"><a href="#">#{pauseText}</a></li></ul><ul class="ui-slideshow-manual-controls"><li class="#{previousClassName}"><a href="#">#{previousText}</a></li><li class="#{nextClassName}"><a href="#">#{nextText}</a></li></ul><p class="#{statusClassName}"></p></div>'.interpolate(this.options));
    this.element.identify();
    this.wrapper = this.element.down('div').setStyle({position: 'relative', width: '100%'});

    this.div1 = this.wrapper.down('div');
    this.div2 = this.div1.next().setStyle({'position' : 'absolute', 'top' : 0, 'left' : 0});

    this.image1 = this.div1.down('img').setStyle({'display' : 'block'});
    this.image2 = this.div2.down('img').setStyle({'display': 'block'});

    this.status = this.element.down('.'+this.options.statusClassName);
    this.previousLink = this.element.down('.'+this.options.previousClassName);
    this.nextLink = this.element.down('.'+this.options.nextClassName);
    this.playLink = this.element.down('.'+this.options.playClassName);
    this.pauseLink = this.element.down('.'+this.options.pauseClassName).hide();
    this.controls = this.element.down('.'+this.options.controlsClassName);
    this.root.insert(this.element);
    this.element.observe('click', this.onClick.bindAsEventListener(this));

    if(this.options.height && this.options.width){
      this.wrapper.setStyle({
        height: this.options.height+'px',
        width: this.options.width+'px',
        overflow : 'hidden'
      })
    }

  },
  show : function(i){
    if(i) this.index = i;
    this.controls.makeInvisible();
    this.nextLink[(this.index+1==this.slides.size()) ? 'hide' : 'show']();
    this.previousLink[(this.index==0) ? 'hide' : 'show']();

    var image = new Image();
    image.onload = this.onLoad.bind(this, image);
    image.src = this.slides[this.index][0];
  },
  onLoad : function(image){

    // var animations = [
    //   new Effect.Appear(this.div1, {
    //     sync : true
    //   })
    // ];

    var animations = [];

    if(this.image2.src){
      this.div2.show();
      animations.push(new Effect.Fade(this.div2, {
        sync : true
      }));
    }

    this.image1.src = image.src;
    this.status.update(this.options.statusText.interpolate({
      index: this.index+1,
      count: this.slides.size()
    }));


    new Effect.Parallel(animations, {
      afterFinish : function(){
        this.image2.src = this.image1.src;
        if(this.playing){
          this._play();
        }
        this.controls.makeVisible();
      }.bind(this)
    });

  },
  onClick : function(e){
    if(e.findElement('.'+this.options.nextClassName)){
      e.stop();
      this._pause();
      this.navigate(1);
    }else if(e.findElement('.'+this.options.previousClassName)){
      e.stop();
      this._pause();
      this.navigate(-1);
    }else if(e.findElement('.'+this.options.playClassName)){
      e.stop();
      this._pause();
      this.play();
    }else if(e.findElement('.'+this.options.pauseClassName)){
      e.stop();
      this.pause();
    }
  },
  navigate : function(i){
    this.index += i||0;
    if(this.index == this.slides.size()) this.index = 0;
    if(this.index == -1) this.index = this.slides.size()-1;
    this.show();
  },
  play : function(){
    this._play();
    this.playLink.hide();
    this.pauseLink.show();
    this.options.onPlay();
  },
  _play : function(){
    this.playing = true;
    this.player = this.navigate.bind(this, 1).delay(this.options.delay);
  },
  pause : function(){
    this._pause();
    this.playLink.show();
    this.pauseLink.hide();
    this.options.onPause();
  },
  _pause : function(){
    window.clearTimeout(this.player);
    this.player = this.playing = false;
  },
  destroy : function(){
    if(this.playing){
      this._pause();
    }
    this.element.stopObserving();
    this.element.remove();
  }
});


App.ContactPanel = function(){
  var c = 0, element, t = 0, page, timeout, wrapper;

  function addEvents(){
    Event.observe(window, 'scroll', scroll);
  }

  function scroll(){
    if(timeout){
      window.clearTimeout(timeout);
      timeout = null;
    }
    timeout = window.setTimeout(function(){
      var height = page.getHeight();
      var offset = document.viewport.getScrollOffsets().top;
      var top = wrapper.positionedOffset().top;

      t = Math.max(0, offset-top);
      var h = height-210-element.getHeight()-top;
      t = Math.min(t, h);

      if(t!=c){
        new Effect.Morph(element, {
          style: 'top: '+t+'px',
          duration: 0.25
        });
        c=t;
      }
    }, 200);
  }

  return {
    initialize : function(){
      element = $('sidebar-contact-us');
      wrapper = $('home-contact-us-wrapper');
      if(element && wrapper){
        page = element.getOffsetParent();
        addEvents();
      }
    }
  }
}();


document.observe("dom:loaded", function(){
  // App.Lightbox.initialize();

  new UI.Lightbox('a.lightbox');
  new UI.Videobox('a.videobox');

  App.ContactPanel.initialize();

  when('home-flash', function(element){
    swfobject.embedSWF("/img/site/flash/home.swf", element.identify(), "640", "375", "8.0.0", null, {}, {wmode: 'transparent'}, {});
  });

  Event.observe('newsletter-subscription', 'submit', function(event) {
    if (!$('newsletter-email').value.match(/\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/)) {
      alert('Please enter a valid email address');
      event.stop();
    }
  });

});
