//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2009 Aaron Newton <http://clientcide.com/>, Valerio Proietti <http://mad4milk.net> & the MooTools team <http://mootools.net/developers>, MIT Style License.

MooTools.More = {
	'version': '1.2.3.1'
};

/*
Script: Element.Forms.js
	Extends the Element native object to include methods useful in managing inputs.

	License:
		MIT-style license.

	Authors:
		Aaron Newton

*/

Element.implement({

	tidy: function(){
		this.set('value', this.get('value').tidy());
	},

	getTextInRange: function(start, end){
		return this.get('value').substring(start, end);
	},

	getSelectedText: function(){
		if (this.setSelectionRange) return this.getTextInRange(this.getSelectionStart(), this.getSelectionEnd());
		return document.selection.createRange().text;
	},

	getSelectedRange: function() {
		if ($defined(this.selectionStart)) return {start: this.selectionStart, end: this.selectionEnd};
		var pos = {start: 0, end: 0};
		var range = this.getDocument().selection.createRange();
		if (!range || range.parentElement() != this) return pos;
		var dup = range.duplicate();
		if (this.type == 'text') {
			pos.start = 0 - dup.moveStart('character', -100000);
			pos.end = pos.start + range.text.length;
		} else {
			var value = this.get('value');
			var offset = value.length - value.match(/[\n\r]*$/)[0].length;
			dup.moveToElementText(this);
			dup.setEndPoint('StartToEnd', range);
			pos.end = offset - dup.text.length;
			dup.setEndPoint('StartToStart', range);
			pos.start = offset - dup.text.length;
		}
		return pos;
	},

	getSelectionStart: function(){
		return this.getSelectedRange().start;
	},

	getSelectionEnd: function(){
		return this.getSelectedRange().end;
	},

	setCaretPosition: function(pos){
		if (pos == 'end') pos = this.get('value').length;
		this.selectRange(pos, pos);
		return this;
	},

	getCaretPosition: function(){
		return this.getSelectedRange().start;
	},

	selectRange: function(start, end){
		if (this.setSelectionRange) {
			this.focus();
			this.setSelectionRange(start, end);
		} else {
			var value = this.get('value');
			var diff = value.substr(start, end - start).replace(/\r/g, '').length;
			start = value.substr(0, start).replace(/\r/g, '').length;
			var range = this.createTextRange();
			range.collapse(true);
			range.moveEnd('character', start + diff);
			range.moveStart('character', start);
			range.select();
		}
		return this;
	},

	insertAtCursor: function(value, select){
		var pos = this.getSelectedRange();
		var text = this.get('value');
		this.set('value', text.substring(0, pos.start) + value + text.substring(pos.end, text.length));
		if ($pick(select, true)) this.selectRange(pos.start, pos.start + value.length);
		else this.setCaretPosition(pos.start + value.length);
		return this;
	},

	insertAroundCursor: function(options, select){
		options = $extend({
			before: '',
			defaultMiddle: '',
			after: ''
		}, options);
		var value = this.getSelectedText() || options.defaultMiddle;
		var pos = this.getSelectedRange();
		var text = this.get('value');
		if (pos.start == pos.end){
			this.set('value', text.substring(0, pos.start) + options.before + value + options.after + text.substring(pos.end, text.length));
			this.selectRange(pos.start + options.before.length, pos.end + options.before.length + value.length);
		} else {
			var current = text.substring(pos.start, pos.end);
			this.set('value', text.substring(0, pos.start) + options.before + current + options.after + text.substring(pos.end, text.length));
			var selStart = pos.start + options.before.length;
			if ($pick(select, true)) this.selectRange(selStart, selStart + current.length);
			else this.setCaretPosition(selStart + text.length);
		}
		return this;
	}

});


Fx.Tween.Toggle = new Class({
	
	Extends: Fx.Tween,
	
		options: {
			/*
			onToggle: $empty,
			onToggleIn: $empty,
			onToggleOut: $empty,
			*/
			toggleIn: [0,1],
			toggleOut: [1,0]
		},
		
	initialize: function(element,options){
		this.parent(element,options);
	},
	
	toggle: function(event){
		if(event) event.stop();
		(this.toggled) ? this.toggleOut() : this.toggleIn();
		this.fireEvent('onToggle');
		return this;
	},
	
	toggleIn: function(){
		this.toggled = true;
		this.start(this.options.toggleIn[0],this.options.toggleIn[1]);
		this.fireEvent('onToggleIn');
		return this;
	},
	
	toggleOut: function(){
		this.toggled = false;
		this.start(this.options.toggleOut[0],this.options.toggleOut[1]);
		this.fireEvent('onToggleOut');
		return this;
	},
	
	setIn: function(){
		this.toggled = true
		this.set(this.options.toggleIn[1]);
		return this;
	},
	
	setOut: function(){
		this.toggled = false;
		this.set(this.options.toggleOut[1]);
		return this;
	}
	
});

var Toggler = new Class({
  
  Extends: Fx.Tween.Toggle,
  
    options: {
			toggledClass: 'toggled'
    },

  initialize: function(element,toggler,options){
    this.parent(element,options);
    this.toggler = document.id(toggler);
		this.bound = this.toggle.bind(this);
    this.attach();
  },
  
  toggleIn: function(){
    this.parent();
    this.toggler.addClass(this.options.toggledClass);
  },
  
  toggleOut: function(){
    this.parent();
    this.toggler.removeClass(this.options.toggledClass);
  },
  
  setIn: function(){
    this.parent();
		this.toggler.addClass(this.options.toggledClass);
  },
  
  setOut: function(){
    this.parent();
    this.toggler.removeClass(this.options.toggledClass);
  },
  
  attach: function(){
		this.toggler.addEvent('click',this.bound);
		return this;
	},
	
	detach: function(){
		this.toggler.removeEvent('click',this.bound);
		return this;
	}
  
});

var Placeholder = new Class({
  
  Implements: Options,  // dependecncies: Element.Forms
    options: {
      attr: 'alt',
      className: 'placeholder'
    },
    
  initialize: function(input,options){
    this.setOptions(options);
    this.input = document.id(input);
    this.bound = {
      focus: this.focus.bind(this),
      blur: this.blur.bind(this),
      keydown: this.keydown.bind(this),
      keyup: this.keyup.bind(this)
    };
    this.attach();
  },
  
  attach: function(){
    this.input.addEvents({
      'focus': this.bound.focus,
      'blur': this.bound.blur,
      'keydown': this.bound.keydown,
      'keyup': this.bound.keyup
    }).addClass(this.options.className);
  },
  
  unchanged: function(){
    return this.input.value == this.input.get(this.options.attr);
  },
  
  focus: function(){
    if(this.unchanged()) this.setCaret();
  },
  
  blur: function(){
    if(this.unchanged() || this.input.value == '') this.reset();
  },
  
  keydown: function(){
    if(this.unchanged()) this.input.removeClass(this.options.className).value = '';
  },
  
  keyup: function(){
    if(this.input.value=='') {
      this.reset();
      this.setCaret();
    }
  },
  
  reset: function(){
    this.input.addClass(this.options.className).value = this.input.get(this.options.attr);
  },
  
  setCaret: function(){
    (function() { this.input.setCaretPosition(0)}.bind(this)).delay(1);
  }
  
});

Number.implement({
  
  toDollarString: function(){
    var string = this.toString().split('.');
		if(string.length > 1){
			if(string[1].length==1){
				string[1] = string[1] + '0';
			}
		}
		else {
			string[1] = '00';
		}    
    return '$' + string.join('.');
  }
  
});

var Ticker = new Class({
	
	Implements: [Options,Events],
	
		options:{
		  /* 
		  onShow: $empty(index), 
		  onBeforeShow: $empty(index),
		  */
			delay: 6000
		},
		
	initialize: function(selector,options){
		this.setOptions(options);
		this.elements=$$(selector);
		this.container=this.elements[0].getParent();
		if(this.container.getStyle('position')!='absolute') this.container.setStyle('position','relative');
		this.elements.each(function(el){
			el.fade('hide');
			el.setStyles({
				'position':'absolute',
				'left':0,
				'top':0
			})
		});
		this.timer=null;
		this.current=0;
		this.show(0);
	},
	
	show: function(index){
	  this.pause();
	  this.fireEvent('onBeforeShow',this.current);
	  this.elements[this.current].fade('out');
	  this.current = index;
	  this.elements[this.current].fade('in');
	  this.fireEvent('onShow',this.current);
	  this.resume();
	},
	
	next: function(){
    var index = (this.current + 1 >= this.elements.length) ? 0 : this.current+1;
    this.show(index);
    return this;
	},
	
	previous: function(){
		var index = (this.current - 1 == -1) ? this.elements.length-1 : this.current -1;
	  this.show(index);
	  return this;
	},
	
	pause: function() {
		this.paused = true;
	  $clear(this.timer);
	  this.timer = null;
	  return this;
	},
	
	resume: function() {
	  if (this.timer == null) this.timer = this.next.bind(this).delay(this.options.delay);
		this.paused = false;
	},
	
	attach: function(){
		this.container.addEvents({
			'click': this.next.bind(this)
		})
	}
	
});

/*
Script: Request.JSON.Form.js
	Adds Request.JSON functionality to a form by posting via xhr.

	License:
		MIT-style license.

	Author:
		Ryan Florence

*/

Request.JSON.Form = new Class({
	
	Extends: Request.JSON,
		
	initialize: function(form,options){
		this.parent(options);
		this.form = document.id(form);
		this.options.url = this.form.get('action');
		this.boundHandler = this.submit.bind(this);
		this.attach();
	},
	
	attach: function(){
		this.form.addEvent('submit',this.boundHandler);
		return this;
	},

	detach: function(){
		this.form.removeEvent('submit',this.boundHandler);
		return this;
	},

	submit: function(event){
		event.stop();
		this.post(this.form);
	}

});
