var TextInput = Class.create({
MinHeight: 15,
MinWidth: 150,
GrowReserve: 15,

initialize: function(input) {
	this.input = $(input);
	this.div=$('WRAP_'+input);
	this.dragger=$('DRAG_'+input);
	this.corner=$('CORNER_'+input);

	this.fitWidth=(this.corner ? false : true);

	if (this.fitWidth) {
		if (this.div) this.div.setStyle({ width: '98%' });
		this.input.setStyle({ width: '100%' });
		if (this.dragger) this.dragger.setStyle({ width: '100%' });
	}
	else {
		if (this.dragger) this.dragger.addClassName('textInputResizeDownLeft');
	}

	this.autoGrow = this.input.readAttribute('auto-grow');
	this.input.observe('keyup', this.Grow.bind(this));
	this.input.observe('mouseover', this.Grow.bind(this));

	if (this.autoGrow) {
		this.prevHeight = this.input.offsetHeight;

// 		this.input.setStyle({
// 			overflowY: 'hidden'
// 		});
	}

	this.ID_ = this.input.readAttribute('id');
	this.input.JSControl=this;
	this.input.observe('change', this.OnChange.bind(this));
	BindKeyDown(this.input, this.OnInput.bind(this));

	if (this.corner) this.corner.observe('mousedown', this.OnDraggerDown.bind(this, false));

	if (this.dragger) {
		this.dragger.observe('mousedown', this.OnDraggerDown.bind(this, true));
		this.dragger.observe('drag', function() { return false; });
		this.dragger.observe('dblclick', this.OnDraggerDoubleClick.bind(this));
//		Event.observe(window, 'resize', this.ResizeDragger.bind(this));
		this.dragUpHandler = this.OnDraggerUp.bind(this);
		this.dragMoveHandler = this.OnDraggerMove.bind(this);
	}
	this.SetAttribute('visibility', this.input.readAttribute('visibility'));
//	if (this.dragger) this.ResizeDragger();

	this.parent = input.parentNode;
	this.parentWindow = AControl.GetParentWindow(this.ID());
},
ResizeDragger: function() {
	var w = this.input.offsetWidth - (this.dragger.offsetWidth - this.dragger.clientWidth);
	if (this.fitWidth) {
		this.dragger.setStyle({ width: w + 'px' });
	}
	else {
		this.dragger.setStyle({ width: w - this.corner.offsetWidth + 'px' });
	}
},
ResizeParentWindow: function() { // very experimental
	// TODO: put calls to this function in resize routines
	if (this.parentWindow) this.parentWindow.OnResize();
},
OnDraggerDown: function(verticalOnly, evt) {
	if (!evt.isLeftClick()) return;

	if (!this.drag) {
		var oldW = this.input.clientWidth;
		if (oldW < this.MinWidth) this.MinWidth = oldW;

		$(document).observe('mouseup', this.dragUpHandler)
		$(document).observe('mousemove', this.dragMoveHandler);
		this.dragX = evt.pointerX();
		this.dragY = evt.pointerY();
		this.startY = this.input.offsetHeight;
		this.startX = (verticalOnly ? undefined : this.input.offsetWidth);
		this.drag = true;
		this.autoGrow = false;
//		this.input.setStyle({ overflowY: '' });
	}
	evt.stop();
},
OnDraggerDoubleClick: function(evt) {
	this.autoGrow = false;

	this.input.setStyle({
		height: this.MinHeight + 'px'
	});
	this.input.setStyle({
		height: this.input.scrollHeight + 'px'
	});
	this.ResizeParentWindow();
},
OnDraggerMove: function(evt) {
	var newX = evt.pointerX();
	var newY = evt.pointerY();

	var newH = this.startY + newY - this.dragY;
	if (newH < this.MinHeight) newH = this.MinHeight;

	var newW = this.startX + newX - this.dragX;
	if (newW < this.MinWidth) newW = this.MinWidth;

	if (this.startX !== undefined) {
		this.input.setStyle({ height: newH + 'px' })
		this.input.setStyle({ width: newW + 'px' });
	}
	else {
		this.input.setStyle({ height: newH + 'px' });
	}
//	this.ResizeDragger();
	this.prevHeight = newH;
},
OnDraggerUp: function(evt) {
	if (!evt.isLeftClick()) return;

	this.drag = false;

	$(document).stopObserving('mousemove', this.dragMoveHandler);
	$(document).stopObserving('mouseup', this.dragUpHandler);
},
OnChange: function(evt) {
	if (this.autoGrow) {
		this.Grow();
	}

	this.input.isNotNull = (this.input.isNotNull || !!(this.input.value));
	new AEvent("CHANGE", {}, this);
},
OnInput: function(evt) {
	var fn = function () {
		new AEvent("INPUT", {}, this);
	};

	this.input.isNotNull = (this.input.isNotNull || !!(this.input.value));
	fn.bind(this).defer();
},
Grow: function() {
	if (!this.autoGrow) return;

	while (this.prevHeight < this.input.scrollHeight) {
		this.prevHeight = this.input.scrollHeight + this.GrowReserve;
		this.input.setStyle({
			height: this.prevHeight + 'px'
		});
	}
},

SetValue: function(value) {
	var v = (typeof value == "undefined" || value === null || !value.Value) ? null : value.Value();
	if(!v) v=null;
	if (v===null) {
		this.input.isNotNull=false;
		v='';
	} else {
		this.input.isNotNull=true;
	}
	this.input.value=v;
	this.Grow();
},

Value: function() {
	if (!this.input.isNotNull || this.input.value===undefined) return null;
	return optional(this.input.value.toString());
},

SetAttribute: function(sName, sValue) {
	if (sName == 'disabled') return;
	if (sName == 'visibility') {
		if (sValue == 'vo' || sValue == 'ro' || sValue == 'link') {
			this.disabled = true;
			this.input.writeAttribute('tabindex', -1);
			this.input.writeAttribute('readonly', 'yes');
			this.div.addClassName('TextInputReadonly');
			this.input.blur();
		}
		else if (this.div) this.div.removeClassName('TextInputReadonly');

	}

	if (sName == "style") {
		var h = (Prototype.Browser.Opera) ? this.input.style.height : this.input.getStyle("height");
		var w = (Prototype.Browser.Opera) ? this.input.style.width : this.input.getStyle("width");
		this.input.writeAttribute(sName, sValue);
		this.input.setStyle({
			width: w,
			height: h
		});
//		this.ResizeDragger();
	}
	else this.input.writeAttribute(sName, sValue);
},

SetTabOrder: function(ntabbase) {
	if(this.disabled) {
		this.input.writeAttribute('tabindex', -1);
		this.input.blur();
	}
	else {
		this.input.writeAttribute('tabindex', ntabbase);
	}
	return ++ntabbase;
},

Focus: function() {
	this.input.focus();
},

ID: function() { return this.ID_; }

});

