/* krzysztof@kluczek.net @ aprill 2011 */

// Cross-browser implementation of node.addEventListener()
// Use: listen('event name', node, function);
function listen(evnt, node, func) {
    if (node.addEventListener) // W3C DOM
		return node.addEventListener(evnt, func, false);
    else // IE DOM
    	return (node.attachEvent) ? node.attachEvent('on' + evnt, func) : false;
}

if (!Array.indexOf) {
	Array.prototype.indexOf = function(obj) {
		for (var i=0; i < this.length; i++)
			if (this[i] == obj)
				return i;
		return -1;
	}
}

// taken from MooTools Core, modyfied by me
function addClass(element, className) {
	if (element.className.indexOf(className) == -1) {
		var c = (element.className + ' ' + className).replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '');
		element.className = c;
		element.setAttribute('class', c);
	}
	return element;
};

function removeClass(element, className) {
	var c = element.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1');
	element.className = c;
	element.setAttribute('class', c);
	return element;
};


/////////////////////////////////

var placeholder = function() {

	this.nativeCompatible = function() {
		var hasPlaceholder = 'placeholder' in document.createElement('input');
		return (hasPlaceholder) ? true : false;
	};

	this.switchType = function(inp) {

		var types = (inp.getAttribute('type') == 'password') ? ['password', 'text'] : ['text', 'password'];

		// Our lovely IE doesn't allow change 'type' property :/
		// … so do the trick ;)
		try {
			inp.setAttribute('type', types[1]);
		}
		catch(e) {

			var attrs = ['type', 	'id',			'class',
						'name',		'readonly', 	'disabled',
						'value',	'placeholder',	'tabindex',
						'maxlength','style', 		'title'];
					
			var newNode = document.createElement('input');

			for (var i=0; i < inp.attributes.length; i++) {

				var attrName = inp.attributes[i].nodeName;
				var attrValue = inp.attributes[i].nodeValue;

				if (attrs.indexOf(inp.attributes[i].nodeName) > -1) {

					switch (inp.attributes[i].nodeName) {
						case 'type':
							newNode.setAttribute('type', types[1]);
							break;
						case 'class':
							newNode.className = attrValue;
							newNode.setAttribute('class', attrValue);					
							break;
						case 'style':					// again buggy IE is not able to set style correctly
							try {							
								newNode.style.setAttribute('cssText', inp.style['cssText'], 0);
							}
							catch(e) {
								newNode.setAttribute(attrName, attrValue);
							}
							break;
						default:
							newNode.setAttribute(attrName, attrValue);
							break;
					}			
				}
			}

			inp.parentNode.replaceChild(newNode, inp);
			inp = newNode;
		} // end of IE magic

		return inp;
	};
	
	this.onfocus = function(e) {

		var target = (!e.target) ? e.srcElement : e.target;

		if (target.getAttribute('placeholder') == target.value) {
		
			target.setAttribute('value', ''); // fix for Fx 3.*
			target.value = '';				
			removeClass(target, 'placeholder');
			
			if (target.getAttribute('class').indexOf('password') != -1) {
				target = _placeholder.switchType(target);
				listen('blur', target, _placeholder.onblur);
				target.select(); // .focus() seems to doesn't work on IE with replaced node, select() do the work ;)
			}
		}
	};
	
	this.onblur = function(e) {
	
		var target = (!e.target) ? e.srcElement : e.target;
		
		var value = target.value;
		var type = target.getAttribute('type') ? target.getAttribute('type') : null;
		var placeholder = target.getAttribute('placeholder') ? target.getAttribute('placeholder') : null;
		
		if (value == '') {

			if (target.nodeName.toLowerCase() == 'textarea') {
				target.value = placeholder;
			}
			else {
			
				if (type == 'password') {
					target = _placeholder.switchType(target);
					addClass(target, 'password');
					listen('focus', target, _placeholder.onfocus);
				}
			//	target.setAttribute('value', placeholder);
				target.value = placeholder;
			}

			addClass(target, 'placeholder');
		}	
	};
	
	this.onsubmit = function(e) {
		e.preventDefault ? e.preventDefault() : e.returnValue = false;

		var target = (!e.target) ? e.srcElement : e.target;
		
		var inputs = target.getElementsByTagName('input'), textareas = target.getElementsByTagName('textarea');
		    
		for (var i=0; i < inputs.length + textareas.length; i++) {
			var node = (inputs[i]) ? inputs[i] : textareas[i - inputs.length];
			
			if (node.getAttribute('placeholder') && node.getAttribute('placeholder') == node.value) {
				node.setAttribute('value', ''); // fix for Fx 3.*
				node.value = '';
			}
		}
		
		target.submit();
	};
	
	this.init = function() {

		if (this.nativeCompatible())
			return; // we don't need any magic ;)))

		var inputs = document.getElementsByTagName('input');
		var txtareas = document.getElementsByTagName('textarea');
		var forms = [];

		for (var i=0; i < txtareas.length; i++) {

			var txtarea = txtareas[i];
			var value = (txtarea.textContent) ? txtarea.textContent : txtarea.value;
			var placeholder = txtarea.getAttribute('placeholder') ? txtarea.getAttribute('placeholder') : null;

			if (placeholder && value == '') {
				addClass(txtarea, 'placeholder');
				txtarea.value = txtarea.getAttribute('placeholder');
			}
			
			listen('focus', txtarea, _placeholder.onfocus);
			listen('blur', txtarea, _placeholder.onblur);
			
			if (forms.indexOf(txtarea.form) == -1)
				forms.push(txtarea.form);
		}

		for (var i=0; i < inputs.length; i++) {

			var inp = inputs[i];
			var type = inp.getAttribute('type') ? inp.getAttribute('type') : null;
			var value = inp.value;
			var placeholder = inp.getAttribute('placeholder') ? inp.getAttribute('placeholder') : null;

			if (placeholder && (type == 'text' || type == 'password')) {

				if (!value) {
					if (type == 'password') {
						inp = this.switchType(inp);
						addClass(inp, 'password');
					}
					addClass(inp, 'placeholder').setAttribute('value', inp.getAttribute('placeholder'));
				}

				listen('focus', inp, _placeholder.onfocus);
				listen('blur', inp, _placeholder.onblur);

				if (forms.indexOf(inp.form) == -1)
					forms.push(inp.form);
			}
		}
		
		for (var i=0; i < forms.length; i++) {
			listen('submit', forms[i], _placeholder.onsubmit);
		}
	};
}

window.onload = function() {
	_placeholder = new placeholder();
	_placeholder.init();
}
