/*  Cookie  */
var Cookie = {
	set: function(name,value,seconds){
		if(seconds){
			d = new Date();
			d.setTime(d.getTime() + (seconds * 1000));
			expiry = '; expires=' + d.toGMTString();
		}else
			expiry = '';
		document.cookie = name + "=" + value + expiry + "; path=/";
	},
	get: function(name){
		nameEQ = name + "=";
		ca = document.cookie.split(';');
		for(i = 0; i < ca.length; i++){
			c = ca[i];
			while(c.charAt(0) == ' ')
				c = c.substring(1,c.length);
			if(c.indexOf(nameEQ) == 0)
				return c.substring(nameEQ.length,c.length);
		}
		return null
	},
	unset: function(name){
		Cookie.set(name,'',-1);
	}
}
// String.capitalize (pass in true to capitalize all words)
String.prototype.capitalize = String.prototype.capitalize.wrap( 
  function(proceed, eachWord) { 
    if (eachWord && this.include(" ")) {
      // capitalize each word in the string
      return this.split(" ").invoke("capitalize").join(" ");
    } else {
      	// proceed using the original function
      	return proceed(); 
    }
  }
);
String.prototype.trim = function() {
    a = this.replace(/^\s+/, '');
    return a.replace(/\s+$/, '');
};

Element.addMethods({
	addHoverClassName: function(element, className){
      return $(element)
        .observe('mouseover', Element.addClassName.curry(element, className))
        .observe('mouseout', Element.removeClassName.curry(element, className));
    },
	replaceClassName:function(element,original,replacement){
		element = $(element);
		if(element.hasClassName(original)){
			element.removeClassName(original);
		}
		if(!element.hasClassName(replacement)){
			element.addClassName(replacement);
		}
		return element;
	}
});
Object.extend(Date.prototype, {
  /**
   * @param format {String} The string used to format the date.
   * Example:  new Date().strftime("%A %I:%M %p")
   */
  strftime: function(format) {
    var day = this.getUTCDay(), month = this.getUTCMonth();
    var hours = this.getUTCHours(), minutes = this.getUTCMinutes();
    function pad(num) { return num.toPaddedString(2); };

    return format.gsub(/\%([aAbBcdDHiImMpSwyY])/, function(part) {
      switch(part[1]) {
        case 'a': return $w("Sun Mon Tue Wed Thu Fri Sat")[day]; break;
        case 'A': return $w("Sunday Monday Tuesday Wednesday Thursday Friday Saturday")[day]; break;
        case 'b': return $w("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")[month]; break;
        case 'B': return $w("January February March April May June July August September October November December")[month]; break;
        case 'c': return this.toString(); break;
        case 'd': return this.getUTCDate(); break;
        case 'D': return pad(this.getUTCDate()); break;
        case 'H': return pad(hours); break;
        case 'i': return (hours === 12 || hours === 0) ? 12 : (hours + 12) % 12; break;
        case 'I': return pad((hours === 12 || hours === 0) ? 12 : (hours + 12) % 12); break;
        case 'm': return pad(month + 1); break;
        case 'M': return pad(minutes); break;
        case 'p': return hours > 11 ? 'PM' : 'AM'; break;
        case 'S': return pad(this.getUTCSeconds()); break;
        case 'w': return day; break;
        case 'y': return pad(this.getUTCFullYear() % 100); break;
        case 'Y': return this.getUTCFullYear().toString(); break;
      }
    }.bind(this));
  }
});
Object.extend(String.prototype, {
  _each: function()
  {
    return Array.prototype._each.apply($w(String(this)), arguments);
  },
	getExt: function()
  {
    var match = this.match(/^(.*)(\.)(.*)$/);
    
    if (match != null) return match.last();
    
    return '';
  },
	pad: function(length, chr, type)
  {
    if (typeof chr == 'undefined') chr = ' ';
    if (typeof type == 'undefined') type = 0;
    
    if (length == this.length) return this;
    
    var l = (length - this.length);
    var c = String(chr).times(l);
    
    if (type == 0) return c + this;
    else return this + c;
  },
  
  padLeft: function(length, chr)
  {
    return this.pad(length, chr, 0);
  },
  
  padRight: function(length, chr)
  {
    return this.pad(length, chr, 1);
  }
});
Object.extend(String.prototype, Enumerable);
var Proto={};
Proto.TableMethods = {
  elements: ['TABLE', 'THEAD', 'TBODY', 'TFOOT'],
  methods: {
 	/* $('table').down('tbody').addRow({
          cells: [
            { innerHTML: 'Cell 1 Content', className: 'cell1Class' },
            { innerHTML: 'Cell 2 Content' },
            { innerHTML: 'Cell 3 Content' }
          ]});*/
    addRow: function(element, options)
    {
      this.options = {
        index: -1, // Append
        cells: $A()
      };
      Object.extend(this.options, options || { });
      
      element = $(element);
  
      // First, add the row to the table.
      var row = $(element.insertRow(this.options.index));
      
      this.options.cells.each(function(cell, index)
      {
        var rowCell = $(row.insertCell(index));
  
        $H(cell).each(function(attribute) 
        {
          switch (attribute[0])
          {
            case 'innerHTML':
  	          rowCell.update(attribute[1]);
              break;
            case 'className':
  	          rowCell.addClassName(attribute[1]);
              break;
            default:
              rowCell.writeAttribute(attribute[0], attribute[1]);          
          }
        });
      });  
      return row;
    }    
  }
};

Element.addMethods(['INPUT', 'TEXTAREA'], {
  getSelection: function(element){
    element = $(element);    
    /* Mozilla/DOM 3.0 */
    if ('selectionStart' in element){
      var length = element.selectionEnd - element.selectionStart;      
      return {
        start: element.selectionStart,
        end: element.selectionEnd,
        length: length,
        text: element.value.substr(element.selectionStart, length)
      };
    }
    /* IE */
    if (document.selection){
      element.focus();
      var r = document.selection.createRange();
      if (r == null) return { start: 0, end: element.value.length, length: 0 };
      var re = element.createTextRange();
      var rc = re.duplicate();
      re.moveToBookmark(r.getBookmark());
      rc.setEndPoint('EndToStart', re);
      return {
        start: rc.text.length,
        end: rc.text.length + r.text.length,
        length: r.text.length,
        text: r.text
      };
    }
    return { start: 0, end: e.value.length, length: 0 };
  },
  setSelection: function(element, start, end){
    element = $(element);
    if (typeof end == 'undefined') end = start;
    /* Mozilla/DOM 3.0 */
    if ('selectionStart' in element){
      element.focus();
      element.setSelectionRange(start, end);
    }
    /* IE */
    if (document.selection){
      element.focus();
      var r = document.selection.createRange();
      if (r == null) return { start: 0, end: element.value.length, length: 0 };
      var tr = element.createTextRange();
      tr.collapse(true);
      tr.moveEnd('character', end);
      tr.moveStart('character', start);
      tr.select();
    }
    return element.getSelection();
  },
  replaceSelection: function(element, text){
    element = $(element); 
    if (typeof text == 'undefined') text = '';
    /* Mozilla/DOM 3.0 */
    if ('selectionStart' in element){
      element.value = element.value.substr(0, element.selectionStart) + text + element.value.substr(element.selectionEnd, element.value.length);
      return element;
    }
    /* IE */
    if (document.selection){
      element.focus();
      document.selection.createRange().text = text;
      return element;
    }
    element.value += text;
    return element;
  }
});
Element.addMethods(Proto.TableMethods.elements, Proto.TableMethods.methods);
Effect.BlindLeft = function(element) {
  element = $(element);
  element.makeClipping();
  return new Effect.Scale(element, 0,
    Object.extend({ scaleContent: false, 
      scaleY: false,                     
      restoreAfterFinish: true,
      afterFinishInternal: function(effect) {
        effect.element.hide().undoClipping();
      } 
    }, arguments[1] || {})
  );
}
Effect.BlindRight = function(element) {
  element = $(element);
    var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, 100, Object.extend({ 
    scaleContent: false, 
    scaleY: false,
    scaleFrom: 0,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makeClipping().setStyle({width: '0px'}).show(); 
    },  
    afterFinishInternal: function(effect) {
      effect.element.undoClipping();
    }
  }, arguments[1] || {}));
}
Effect.Nod = function(element) {
  element = $(element);
  var oldStyle = {
    top: Element.getStyle(element, 'top'),
    left: Element.getStyle(element, 'left') };
      return new Effect.Move(element, 
        { x:  0, y: 20, duration: 0.05, afterFinishInternal: function(effect) {
      new Effect.Move(effect.element,
        { x: 0, y: -40, duration: 0.1,  afterFinishInternal: function(effect) {
      new Effect.Move(effect.element,
        { x:  0, y: 40, duration: 0.1,  afterFinishInternal: function(effect) {
      new Effect.Move(effect.element,
        { x: 0, y: -40, duration: 0.1,  afterFinishInternal: function(effect) {
      new Effect.Move(effect.element,
        { x:  0, y: 40, duration: 0.1,  afterFinishInternal: function(effect) {
      new Effect.Move(effect.element,
        { x: 0, y: -20, duration: 0.05, afterFinishInternal: function(effect) { with(Element) {
        undoPositioned(effect.element);
        setStyle(effect.element, oldStyle);
  }}}) }}) }}) }}) }}) }});
}
Effect.SmoothScroll = Class.create();
Object.extend(Object.extend(Effect.SmoothScroll.prototype, Effect.Base.prototype), {
	initialize: function (element) {
		this.element = $(element);
		var options = Object.extend({ x: 0, y: 0, mode: 'absolute' } , arguments[1] || {});
		this.start(options);
		},
	setup: function () {
		if (this.options.continuous && !this.element._ext ) {
			this.element.cleanWhitespace();
			this.element._ext = true;
			this.element.appendChild(this.element.firstChild);
			}   
		this.originalLeft = this.element.scrollLeft;
		this.originalTop = this.element.scrollTop;
		if (this.options.mode == 'absolute') {
			this.options.x -= this.originalLeft;
			this.options.y -= this.originalTop;
			}
		},
	update: function (position) {   
		this.element.scrollLeft = this.options.x * position + this.originalLeft;
		this.element.scrollTop  = this.options.y * position + this.originalTop;
		}
});
Effect.Transitions.exponential = function(pos) {
  return 1-Math.pow(1-pos,2);
}
Effect.Transitions.Elastic = function(pos) {
    return -1*Math.pow(4,-8*pos) * Math.sin((pos*6-1)*(2*Math.PI)/2) + 1;
};
Effect.Transitions.SwingFromTo = function(pos) {
    var s = 1.70158;
    if ((pos/=0.5) < 1) return 0.5*(pos*pos*(((s*=(1.525))+1)*pos - s));
    return 0.5*((pos-=2)*pos*(((s*=(1.525))+1)*pos + s) + 2);
};
Effect.Transitions.SwingFrom = function(pos) {
    var s = 1.70158;
    return pos*pos*((s+1)*pos - s);
};
Effect.Transitions.SwingTo = function(pos) {
    var s = 1.70158;
    return (pos-=1)*pos*((s+1)*pos + s) + 1;
};
Effect.Transitions.Bounce = function(pos) {
    if (pos < (1/2.75)) {
        return (7.5625*pos*pos);
    } else if (pos < (2/2.75)) {
        return (7.5625*(pos-=(1.5/2.75))*pos + .75);
    } else if (pos < (2.5/2.75)) {
        return (7.5625*(pos-=(2.25/2.75))*pos + .9375);
    } else {
        return (7.5625*(pos-=(2.625/2.75))*pos + .984375);
    }
};
Effect.Transitions.BouncePast = function(pos) {
    if (pos < (1/2.75)) {
        return (7.5625*pos*pos);
    } else if (pos < (2/2.75)) {
        return 2 - (7.5625*(pos-=(1.5/2.75))*pos + .75);
    } else if (pos < (2.5/2.75)) {
        return 2 - (7.5625*(pos-=(2.25/2.75))*pos + .9375);
    } else {
        return 2 - (7.5625*(pos-=(2.625/2.75))*pos + .984375);
    }
};
Effect.Transitions.EaseFromTo = function(pos) {
    if ((pos/=0.5) < 1) return 0.5*Math.pow(pos,4);
    return -0.5 * ((pos-=2)*Math.pow(pos,3) - 2);    
};
Effect.Transitions.EaseFrom = function(pos) {
    return Math.pow(pos,4);
};
Effect.Transitions.EaseTo = function(pos) {
    return Math.pow(pos,0.25);
};
var transition = {
	sin: Effect.Transitions.sinoidal,
	line: Effect.Transitions.linear,
	rev: Effect.Transitions.reverse,
	wobble: Effect.Transitions.wobble,
	flicker: Effect.Transitions.flicker,
	exp: Effect.Transitions.exponential,
	elastic: Effect.Transitions.Elastic,
	swingboth: Effect.Transitions.SwingFromTo,
	swingstart: Effect.Transitions.SwingFrom,
	swingend: Effect.Transitions.SwingTo,
	bounce: Effect.Transitions.Bounce,
	bouncepast: Effect.Transitions.BouncePast,
	easeboth: Effect.Transitions.EaseFromTo,
	easestart: Effect.Transitions.EaseFrom,
	easeend: Effect.Transitions.EaseTo
};  