function TextInputCounter(input,max){
  this.input = $(input);
  this.max = max;
  this.total = $('<span>'+this.count()+'</span>');
  this.message = $('<p class="character-count">/'+this.max+' characters</p>');
  this.message.prepend(this.total);
  this.input.after(this.message);
  var _this = this;
  this.input.keyup(function(){
              _this.updateCount();
            }).blur(function(){
              _this.cutOff();
              _this.updateCount();
            }).keydown(function(ev){
              _this.prevent(ev);
            });
}

TextInputCounter.prototype.count = function(){
  return this.input.val().length;
}
TextInputCounter.prototype.updateCount = function(){
  var count = this.count(); 
  this.total.text(count);
}
TextInputCounter.prototype.prevent = function(ev){
  if(this.input.val().length >= this.max && $.inArray(ev.keyCode,[8,9,13,37,38,39,40,46])==-1){
    ev.preventDefault();
  }
}
TextInputCounter.prototype.cutOff = function(){
  this.input.val(this.input.val().slice(0,this.max));
}

Cookie = {
  create:function(name,value,days){
   if (days) {
     var date = new Date();
     date.setTime(date.getTime()+(days*24*60*60*1000));
     var expires = "; expires="+date.toGMTString();
   }
   else var expires = "";
   document.cookie = name+"="+value+expires+"; path=/";
  },
  deleteIt:function(name){
    this.create(name,"",-1);
  }
};

function CookieAccount(cookieName,fieldset){
  this.fieldset = $(fieldset);
  this.cookieName = cookieName;
  this.lis = this.fieldset.find('li');
  this.firstLi = this.lis.filter(':first');
  this.username = this.firstLi.find('input').val();
  this.lis = this.lis.filter(':gt(0)');
  this.message = $("<p class='not-user'>Not "+this.username+"? </p>");
  this.link = $("<a href='#'>Click here to enter new information.</a>");
  if(this.fieldset.length > 0 && this.lis.length > 0 && this.message.length > 0 && this.link.length > 0){
    this.init();
  }
}

CookieAccount.prototype.init = function(){
  var _this = this;
  this.firstLi.append(this.message.append(this.link)).find('input').attr('disabled','disabled');
  this.lis.hide();
  this.link.click(function(){
    _this.logout();
    return false;
  })
}

CookieAccount.prototype.logout = function(){
  Cookie.deleteIt(this.cookieName);
  this.fieldset.find('input').each(function(){
    $(this).val('').removeAttr('disabled').change();
  }).end().find('select').each(function(){
    this.selectedIndex = 0;
    $(this).change();
  })
  this.message.remove();
  this.lis.fadeIn();
  this.firstLi.focus();
}

function InfiniteSandwich(list,pagination,url,maxPages){
  this.list = $(list);
  this.pagination = $(pagination);
   this.pagination.hide();
  this.maxPages = maxPages;
  this.nextPage = 2;
  this.nextCall = 3000;
  this.url = url;
  this.checking = false;
  if(this.list.length==1 && this.maxPages && this.url){
    this.offset = this.findOffset(this.list[0]);
    this.updateScroll();
    if(typeof this.scroll == "number"){
      this.messages = {
        mouse:$('<li id="mouse" style="display:none;">Stop holding the mouse button down and you can have some more layers!</li>'),
        loading:$('<li id="loading" style="display:none;">Loading more layers</li>'),
        error:$('<li id="error" style="display:none;">Something went wrong, please refresh and try again</li>')
      }
      var _this = this;
      $(window)
        .scroll(function(){ _this.updateScroll.call(_this); })
        .mousedown(function(){_this.mouseDownObserver.call(_this);})
        .mouseup(function(){_this.mouseUpObserver.call(_this);})
        .ajaxSend(function(){
          _this.showMessage(_this.messages.loading);
        }).ajaxComplete(function(){
          _this.hideMessage(_this.messages.loading);
        }).ajaxError(function(){
          _this.showMessage(_this.messages.error);
          $(window).unbind('mousedown').unbind('mouseup');
        });
      this.startChecker();
    }
  }
}

InfiniteSandwich.prototype.showMessage = function(message){
  this.list.append(message);
  message.show();
}
InfiniteSandwich.prototype.hideMessage = function(message){
  message.hide().queue(function(){ $(this).remove(); $(this).dequeue(); });
}

InfiniteSandwich.prototype.mouseDownObserver = function(ev){
  if(this.nextPage < this.maxPages+1){
    this.stopChecker()
    this.showMessage(this.messages.mouse);
  }
}
InfiniteSandwich.prototype.mouseUpObserver = function(){
  this.hideMessage(this.messages.mouse);
  if (!this.checking){
    this.startChecker();
  }
}

InfiniteSandwich.prototype.findOffset = function(obj) {
	var curtop = 0;
  if (obj.offsetParent) {
    do {
			curtop += obj.offsetTop;
    } while (obj = obj.offsetParent);
    return curtop;
  }
}

InfiniteSandwich.prototype.updateScroll = function(){
  this.height = this.list.height();
  this.scroll = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
}

InfiniteSandwich.prototype.check = function(){
  this.updateScroll();
  if((this.height + this.offset) - this.scroll < this.nextCall){
    this.stopChecker();
    this.act();
    this.nextPage += 1;
  }
}

InfiniteSandwich.prototype.startChecker = function(){
  if(this.nextPage < this.maxPages+1){
    var _this = this;
    this.checking = true;
    this.checker = setInterval(function(){ _this.check.call(_this) },500);
  }
}
InfiniteSandwich.prototype.stopChecker = function(){
  this.checking = false;
  this.checker = clearInterval(this.checker);
}

InfiniteSandwich.prototype.act = function(){
  var _this = this;
  $.get(this.url+'/'+this.nextPage+'.js',function(data){ eval(data);_this.startChecker(); });
}

function ColorSelector(li,type){
  this.li = $(li);
  this.type = type;
  this.input = this.li.find('input');
  this.input.hide();
  this.link = $('<a href="#" id="'+this.li[0].id+'-link" class="picker">Select colour</a>');
  this.li.append(this.link);
  changecss('#'+this.link[0].id,'backgroundColor',this.input.val(),'hex',false,this.input[0].id);
  this.updateLivePreview();
  this.initPicker();
}

ColorSelector.prototype.updateLivePreview = function(){
  if(this.type=='background'){
    changecss('div.layer','backgroundColor',this.input.val(),'hex',false,this.input[0].id);
  } else if(this.type=='text'){
    changecss('div.layer','color',this.input.val(),'hex',false,this.input[0].id);
  }
}

ColorSelector.prototype.initPicker = function(){
  var _this=this;
  var selector = '#' + this.li[0].id + ' a'
  this.link.click(function(){
    if(_this.type=='background'){
      pickcolor(selector+';div.layer', 'backgroundColor', false, _this.input[0].id, this);
    } else if(_this.type=='text'){
      pickcolor(selector+';div.layer', 'backgroundColor;color', false, _this.input[0].id, this);      
    }
    return false;
  })
}

function LivePreview(form){
  this.form = $(form);
  this.previewContainer = $('<div id="live-preview" style="display:none;"><div class="layer"><p class="filling"></p><p class="meta"></p></div></div>');
  this.form.prepend(this.previewContainer);
  this.visible = false;
  this.items = {
    filling:{input:$('#filling input'), updater:this.textUpdater},
    name:{input:$('#name input'), updater:this.textUpdater, order:0},
    county:{input:$('#county select'), updater:this.selectUpdater, order:4},
    job:{input:$('#job input'), updater:this.textUpdater, order:1},
    company:{input:$('#company input'), updater:this.textUpdater, order:2},
    background:{input:$('#background input'), receiver:$('div.layer'), updater:this.textUpdater, type:"backgroundColor"},
    text:{input:$('#text input'), receiver:$('div.layer'), updater:this.textUpdater, type:"color"},
    age:{input:$('#age select'), updater:this.ageUpdater, order:3}
  }
  for (var item in this.items){
    this.setObserver(item,this.items[item])
    this.items[item].input.change();
  }
}

LivePreview.prototype.setObserver = function(key,obj){
  var _this = this;
  obj.input.keyup(function(){
    _this.update(key);
  }).change(function(){
    _this.update(key);
  });
}

LivePreview.prototype.update = function(item){
  var item = this.items[item]
  item.updater.call(this,item);
}

LivePreview.prototype.textUpdater = function(item){
  item.value = item.input.val();
  this.drawPreview();
}

LivePreview.prototype.selectUpdater = function(item){
  if (item.input.val().indexOf('--')==-1){
    item.value = item.input.val();
  } else {
    item.value = "";
  }
  this.drawPreview();
}

LivePreview.prototype.ageUpdater = function(item){
  var year = item.input.filter('#dob_year').val();
  var month = item.input.filter('#dob_month').val();
  var day = item.input.filter('#dob_day').val();
  if(year=='-- year --'||month=='-- month --'||day=='-- day --'){
    item.value = '';
  } else {
    var today = new Date();
    today.setHours(0);today.setMinutes(0);today.setSeconds(0);today.setMilliseconds(0);
    var dob = new Date(month+'/'+day+'/'+year);
    var diff  = new Date();
    diff.setTime(Math.abs(today.getTime() - dob.getTime()));
    item.value = Math.floor(diff.getTime() / (1000 * 60 * 60 * 24 * 365.25));
  }
  this.drawPreview();
}

LivePreview.prototype.drawPreview = function(){
  if(!this.visible){
    this.previewContainer.fadeIn(500);
    this.visible = true;
  }
  var meta = [];
  for(var item in this.items){
    var obj = this.items[item];
    if(obj.value){
      if(item=='filling'){
        this.previewContainer.find('p.filling').text(obj.value);
      } else if(obj.type && obj.receiver){
        // obj.receiver.css(obj.type,"#"+obj.value);
      } else if(item=='county' && !(typeof obj.order == 'undefined')){
        meta[obj.order] = ' from '+obj.value;
      } else if(item=='company' && !(typeof obj.order == 'undefined')){
          meta[obj.order] = ' at '+obj.value;
      } else if(!(typeof obj.order == 'undefined')) {
      meta[obj.order] = obj.value;
      }
    }
  }
  meta.clean();
  this.previewContainer.find('p.meta').text(meta.join(', '));
}

Array.prototype.clean = function() {
  for (var i = 0; i < this.length; i++) {
    if (typeof this[i] == 'undefined' || this[i] === '') {         
      this.splice(i, 1);
      i--;
    }
  }
  return this;
};

$(function(){
  $('li.color').each(function(){
    new ColorSelector(this, this.id);
  });

  new LivePreview($('form')[0]);
});