
var FrollopGallery = Class.create();
FrollopGallery.prototype = {
	options:{},
	currentCat:null,
	currentPhoto:null,
	lastPhoto:null,
	maxPhoto:null,
	timer:null,
	thumbTimer:null,
	photos:{},
	preload:{},
	tpreload:{},
	nodes:{},
	tnodes:{},
	thumbsProcessed:null,
	numThumbs:null,

	initialize: function(options) {
	 this.options = Object.extend({
			fadeDuration: 0.5,  // in seconds
			thumbFadeDuration: 0.20,  // in seconds
			clickDelay: 500,    // in milliseconds
			loadingContainer: "loading",
			photoContainer: "window",
			galleryContainer: "windowPhotos",
			photoDetails: "Details",
			photoTitle: "photoTitle",
			photoContent: "photoContent",
			photoDescription: "photoDescription",
			shotDate: "shotDate",
			thumbContent: "thumb_content",
			categories: []
    }, options);
		this.currentCat = -1;
		this.currentPhoto = 0;
		this.lastPhoto = -1;
		this.maxPhoto = 0;
		this.timer = null;
		this.thumbTimer = null;
		this.photos = [];
		this.preload = [];
		this.tpreload = [];
		this.nodes = [];
		this.tnodes = [];
		this.thumbEffects = [];
  },

  // if not loaded clear current photo, set interval to show next photo
  showPhoto: function(photo_id) {
    var _this = this;
    if (!this.checkLoaded(photo_id)) {
      this.lastPhoto = -1;
      Element.setOpacity(this.nodes[this.currentPhoto], 0);
      this.timer = setInterval(function(){_this.checkLoaded(photo_id);}, 250);
    }
  },

  // show loading if not loaded
  // if loaded change the photo
  checkLoaded: function(photo_id) {
    if (!this.preload || this.preload.length < this.photo_id-1) {
      clearInterval(this.timer);
      this.timer = null;
      return false;
    }
    if (!this.preload[photo_id].complete) {
      Element.hide(this.options.photoContainer);
      Element.show(this.options.loadingContainer);
      return false;
    }
    clearInterval(this.timer);
    this.timer = null;
    var _this = this;
    setTimeout(function(){_this.changePhoto(photo_id);}, 500);
    return true;
  },

  nextPhoto: function() {
		nextPhoto = this.currentPhoto+1;
		if (nextPhoto >= this.maxPhotos) { nextPhoto = 0; }
		this.showPhoto(nextPhoto);
  },

  prevPhoto: function() {
		nextPhoto = this.currentPhoto-1;
		if (nextPhoto <= -1) { nextPhoto = this.maxPhotos - 1; }
		this.showPhoto(nextPhoto);
  },

  changePhoto: function(photo_id) {
    var npost, post;
    Element.show(this.options.photoContainer);
    Element.hide(this.options.loadingContainer);
    if (this.currentPhoto != photo_id || this.lastPhoto == -1)
    {
      // hide comments and comment form
      this.hideComments();
      this.hideCommentForm();

      // change the photo_id on the comment form
      $('commentForm').photo_id.value = this.photos[photo_id][0];

      for(i=0;i<this.maxPhotos;i++)
      {
        if ((i != this.currentPhoto)) { Element.setOpacity(this.nodes[i], 0); }
      }

      npost = 'landscape';
      post = 'portrait';
      if (this.photos[photo_id][6] == 1) {
        post = 'landscape';
        npost = 'portrait';
      }

      $(npost+this.options.photoDetails).style.display = 'none';
      Element.update(this.options.photoTitle+npost, '');
      Element.update(this.options.photoContent+npost, '');
      Element.update(this.options.photoDescription+npost, '');
      Element.update(this.options.shotDate+npost, '');

      // clear comment count
      Element.update('commentCountportrait', '');
      Element.update('commentCountlandscape', '');

      // from landscape to portrait
      if ((this.lastPhoto == -1 &&
          this.photos[photo_id][9] > 550 && this.photos[photo_id][9] < 650)
           ||
          (this.photos[this.currentPhoto][9] > 350 && this.photos[this.currentPhoto][9] < 450 &&
           this.photos[photo_id][9] > 550 && this.photos[photo_id][9] < 650)) {
        $(this.options.galleryContainer).style.height = parseInt(this.photos[photo_id][9], 10)+'px';
      }

      // moving forward
      this.nodes[photo_id].setOpacity(0);
      this.nodes[photo_id].style.display = 'block';
      if (photo_id >= this.currentPhoto) {
        // if we're not showing the first image on the page fade the previous one
        if (this.lastPhoto >= 0) {
          eff1 = new Effect.Opacity(this.nodes[this.currentPhoto],
                             {duration:this.options.fadeDuration,
                              from:1.0, to:0.0,
                              afterFinish: this.displayHidePhoto.bind(this)
                             });
        }
        eff2 = new Effect.Opacity(this.nodes[photo_id],
                           {duration:this.options.fadeDuration,
                            from:0.0, to:1.0
                           });
      }
      // moving backwards
      else
      {
        eff1 = new Effect.Opacity(this.nodes[photo_id],
                           {duration:this.options.fadeDuration,
                            from:0.0, to:1.0
                           });
        eff2 = new Effect.Opacity(this.nodes[this.currentPhoto],
                          {duration:this.options.fadeDuration,
                           from:1.0, to:0.0,
                           afterFinish: this.displayHidePhoto.bind(this)
                          });
      }
      // from portrait to landscape
      if ((this.lastPhoto == -1 &&
          this.photos[photo_id][9] > 350 && this.photos[photo_id][9] < 450)
           ||
           (this.photos[this.currentPhoto][9] > 550 && this.photos[this.currentPhoto][9] < 650 &&
          this.photos[photo_id][9] > 350 && this.photos[photo_id][9] < 450)) {
        $(this.options.galleryContainer).style.height = this.photos[photo_id][9]+'px';
      }

      // set content of relevant div info
      Element.update(this.options.photoTitle+post,this.photos[photo_id][1]);
      Element.update(this.options.photoContent+post, this.photos[photo_id][2]);
      Element.update(this.options.photoDescription+post, this.photos[photo_id][3]);
      Element.update(this.options.shotDate+post, this.photos[photo_id][7]);
      $(post+this.options.photoDetails).style.display = 'block';

      this.lastPhoto = this.currentPhoto;
      this.currentPhoto = photo_id;
      this.loadComments(this.photos[photo_id][0]);
    }
  },

  loadPhotos: function (category_id) {
    // if we are already on this category do nothing
    if (this.currentCat != category_id) {
      this.currentCat = category_id;
      // clear the timers
      clearInterval(this.thumbTimer);
      this.thumbTimer = null;
      clearInterval(this.timer);
      this.timer = null;
      var queue = Effect.Queues.get('global');
      if (queue) { queue.each(function(e) { e.cancel() }); }

      this.currentPhoto = 0;
      this.lastPhoto = -1;
      this.preload = [];
      this.tpreload = [];
      this.nodes = [];
      this.tnodes = [];

      // make sure that loading window is shown
      Element.hide(this.options.photoContainer);
      Element.show(this.options.loadingContainer);

      // clear thumb divs
//      this.updateSubMenu(this.options.categories[category_id]);
      Element.update(this.options.galleryContainer, '');
      Element.update(this.options.thumbContent, 'Loading thumbnails');

      // load the data for this category
      opts = { method : 'post',
               onComplete: this.photoDataLoaded.bind(this)
             };
      req = new Ajax.Request('photos/'+this.options.categories[category_id], opts);
    }
  },

  photoDataLoaded: function(originalRequest) {
    eval("this.photos = "+originalRequest.responseText);
    /* photos { 0 => photo id
     *          1 => photo title
     *          2 => photo content
     *          3 => photo description
     *          4 => filename of main image
     *          5 => filename of thumbnail
     *          6 => 1 if landscape 0 if portrait
     *          7 => date photo was shot
     *        }
     */
    // start preloading the images
    var str = '';
    var divStyle = ''; 
    var _this;
	 this.maxPhotos = this.photos.length;
	 	 
    // preload thumbnails
    this.thumbsProcessed = 0;
    this.numThumbs = this.photos.length;
    for (i=0; i<this.maxPhotos; i++) {
      this.tpreload[i] = new Image();
      this.tpreload[i].onerror = function () { this.numThumbs--; };
      this.tpreload[i].src = 'images/collection/'+this.photos[i][5];

      divStyle = 'display:inline;opacity:0.0;margin:0px;padding:0px';
      this.tnodes[i] = Builder.node('div', {className: 'thumbElement', style: divStyle},
                         [Builder.node('a', {href: '#', onclick: 'frollopGallery.showPhoto('+i+')'},
                           [Builder.node('img', {src: 'images/collection/'+this.photos[i][5]})]
                         )
                       ]);
    }
	 
    for (i=0; i<this.maxPhotos; i++) {
      this.preload[i] = new Image();
      this.preload[i].src = 'images/collection/'+this.photos[i][4];
      divStyle = 'position:absolute;'+
                 'left:0px;'+
        				 'width:600px;'+
        				 'height:'+this.photos[i][9]+'px;'+
        				 'margin:0px;'+
        				 'padding:0px;'+
        				 'background-image:url(\'images/collection/'+this.photos[i][4]+'\');'+
        				 'background-position:top right;'+
        				 'background-repeat: no-repeat;'+
        				 'z-index: 3;'+
        				 'display: none;'+
        				 'opacity:0.0';
      this.nodes[i] = Builder.node('div', {className: 'photoElement', style: divStyle} );
      $(this.options.galleryContainer).appendChild(this.nodes[i]);
    }

    if (this.preload.length > 0) {
      Element.setOpacity(this.nodes[0], 0);
      this.showPhoto(0);
      _this = this;
      this.thumbTimer = setInterval(function(){_this.checkThumbsLoaded();}, 500);
    }
  },

  updateSubMenu: function (category_id) {
    $('subMenuTitle').innerHTML = $('subMenu_'+category_id).innerHTML;
    als = $('menuSubMenu').getElementsByTagName('a');
    for (i=0; i<als.length ; i++) {
      als[i].className = 'unselected';
    }
    $('subMenu_'+category_id).className='selected';
  },

  showThumbs: function() {
    var _this = this;
    $(this.options.thumbContent).innerHTML = '';
    var i = 0;
    for (i = 0; i < this.maxPhotos; i++) {
      $(this.options.thumbContent).appendChild(this.tnodes[i]);
      this.thumbEffects[i] = new Effect.Opacity(this.tnodes[i], {duration:this.options.thumbFadeDuration, from:0.0, to:1.0, queue: 'end'});
    }
  },

  checkThumbsLoaded: function() {
    var thumbCount = 0;
    var i = 0;   
    if (this.tpreload && this.tpreload.length >= this.maxPhotos) {
       for (i=0; i<this.maxPhotos; i++) {          
         if (this.tpreload[i].complete) {
           thumbCount++;
         }
       }
    }
    if (this.numThumbs === 0) {
      clearInterval(this.thumbTimer);
      this.thumbTimer = null;
    }
    else if (thumbCount >= this.numThumbs) {
      clearInterval(this.thumbTimer);
      this.thumbTimer = null;
      this.showThumbs();
    }
  },

  displayHidePhoto : function() {
    this.nodes[this.lastPhoto].style.display = 'none';
  },

  loadComments : function(photo_id) {
    $('commentsContainer').innerHTML = '';
    $('commentsContainerNone').style.display = 'block';
    var opt = {
      method: 'get',
      onComplete: this.commentsLoaded.bind(this)
    };
    req = new Ajax.Request('comments/'+photo_id, opt);
  },

  commentsLoaded : function(originalRequest) {
    var ctext;
    this.resetFormMessage();
    this.resetFormError();
    eval("result = "+originalRequest.responseText);
    if (result[0]) {
    }
    else {
      for (i = 0; i < result[1].length; i++) {
        this.insertComment(result[1][i]);
      }
      ctext = result[1].length;
      $('commentCountportrait').innerHTML = ctext;
      $('commentCountlandscape').innerHTML = ctext;
    }
  },

  toggleComments : function() {
    if (Element.visible('commentContainer')) {
      this.hideComments();
    }
    else {
      this.showComments();
    }
  },

  hideComments : function() {
    if (Element.visible('commentContainer')) {
      effc = new Effect.BlindUp('commentContainer');
      this.hideCommentForm();
      this.resetFormMessage();
    }
  },

  showComments : function() {
    if (!Element.visible('commentContainer')) {
      $('commentContainer').style.display = 'block';
//      new Effect.BlindDown('commentContainer');
    }
    effs = new Effect.ScrollTo('commentContainer');
  },

  showCommentForm : function() {
    if (!Element.visible('commentFormContainer')) {
      Recaptcha.destroy();
      Recaptcha.create("6LdofAAAAAAAAFp2cP1nU0ki7Nq3A--lIx2wsqCB",
      "recaptcha", {
         theme: "red",
         tabindex: 0
      });
      effcf = new Effect.BlindDown('commentFormContainer');
    }
    effst = new Effect.ScrollTo('commentFormContainer', {offset:-50});
  },

  hideCommentForm : function() {
    if (Element.visible('commentFormContainer')) {
      effh = new Effect.BlindUp('commentFormContainer', {afterFinish: function() {Recaptcha.destroy();} });
      this.resetFormError();
    }
  },

  clearCommentForm : function() {
    var formObj = $('commentForm');
    formObj.name.value = '';
    formObj.email.value = '';
    formObj.website.value = 'http://';
    formObj.comment.value = '';
    formObj.recaptcha_response_field.value = '';
  },

  postComment: function (formObj) {
    var opt;
    this.resetFormMessage();
    this.resetFormError();
    // validate input
    photo_id = formObj.photo_id.value;
    name = formObj.name.value;
    email = formObj.email.value;
    website = formObj.website.value;
    if (website == 'http://') {
      website = '';
      formObj.website.value = '';
    }
    comment = formObj.comment.value;

    reresponse = formObj.recaptcha_response_field.value;
    rechallenge = formObj.recaptcha_challenge_field.value;

    why = "";
    if (name.length === 0) {
      why = "Please enter your Name";
    }
    else if (name.length > 100) {
      why = "Name should be under 100 characters";
    }
    else if (email.length > 100) {
      why = "Email should be under 100 characters";
    }
    else if (email.length > 0 && checkEmail(email,'')) {
      why = "Email is not in valid format";
    }
    else if (website.length > 100) {
      why = "Website should be under 100 characters";
    }
    else if (website.length > 0 && checkUrl(website,'')) {
      why = "Website is not in valid format";
    }
    else if (comment.length === 0) {
      why = "Please enter a comment";
    }
    else if (reresponse.length === 0) {
      why = "Please enter the image text";
    }

    if (why) {
      // if invalid show error message
      this.setFormError(why);
    }
    else {
      // send input to server
      opt = {
        method: 'post',
        parameters: Form.serialize(formObj),
        onSuccess: this.postedComment.bind(this),
        on404: function(t) {
            this.setFormError('An error occurred while posting this comment, try again later');
        },
        onFailure: function(t) {
            this.setFormError('An error occurred while posting this comment, try again later');
        }
      };
      req = new Ajax.Request('postcomment/'+photo_id, opt);
      // show processing message
      this.setFormMessage('Processing Comment...');
    }

  },

  postedComment : function(originalRequest) {
    this.resetFormMessage();
    this.resetFormError();
    var result = [];
    eval("result = "+originalRequest.responseText);
    if (result[0]) {
      this.setFormError(result[0]);
      Recaptcha.destroy();
      Recaptcha.create("6LdofAAAAAAAAFp2cP1nU0ki7Nq3A--lIx2wsqCB",
      "recaptcha", {
         theme: "red",
         tabindex: 0,
         callback: Recaptcha.focus_response_field
      });
    }
    else {
      // show success message
      this.setFormMessage('Comment successfully inserted');
      this.hideCommentForm();
      this.clearCommentForm();

      // insert comment into list of comments
      this.insertComment(result[1]);
      new_count = parseInt($('commentCountportrait').innerHTML, 10)+1;
      Element.update('commentCountportrait', new_count);
      Element.update('commentCountlandscape', new_count);
    }

  },

  insertComment : function (dat) {
    poster = dat[0];
    if (dat[1]) {
      poster =Builder.node('a', {href: dat[1]}, dat[0]);
    }
    // insert container div
    commentNode = Builder.node('div', {className: 'commentItem'},[
                   Builder.node('div', {className: 'commentDetails'}, [
                    Builder.node('b', [poster])
                   ]),
                   Builder.node('div', {className: 'commentDate'}, dat[2]),
                   Builder.node('div', {className: 'commentContent'}, dat[3])
                 ]);
    var cc = $('commentsContainer');
    var fc = cc.firstChild;
    if (fc) {
      cc.insertBefore(commentNode, fc);
    }
    else {
      cc.appendChild(commentNode);
    }
    $('commentsContainerNone').style.display = 'none';
  },

  resetFormMessage : function() {
    $('commentFormMessage').style.display = 'none';
    $('commentFormMessage').style.backgroundColor = '#FFF';
    $('commentFormMessage').innerHTML = '';
  },
  resetFormError : function() {
    $('commentFormError').style.display = 'none';
    $('commentFormError').innerHTML = '';
    $('commentFormError').style.backgroundColor = '#FFF';
  },

  setFormMessage : function (msg) {
    $('commentFormMessage').style.display = 'block';
    $('commentFormMessage').innerHTML = msg;
    efff = new Effect.Highlight($('commentFormMessage'),{startcolor:'#fffdb3', endcolor:'#fffeef', restorecolor:'#fffeef', duration: 3});
  },

  setFormError : function (error) {
    $('commentFormError').style.display = 'block';
    $('commentFormError').innerHTML = error;
    effe = new Effect.Highlight($('commentFormError'),{startcolor:'#ffb3b3', endcolor:'#fee7e7', restorecolor:'#fee7e7', duration: 3});
  }
};


function callInProgress (xmlhttp) {
  switch (xmlhttp.readyState) {
    case 1: case 2: case 3:
      return true;
      break;
    // Case 4 and 0
    default:
      return false;
      break;
  }
}
