nemantis = {}

// All elements must be positioned absolute!
//
// Tested in: Firefox 3.5
//
// TODO:
// - Validation support

nemantis.forms={
	'append':function(element, text) {
		var form=$(element).parent();
	    var i=0;

	    // find form
	    while(!form.is('form')) {
	        form=form.parent();
	        if(i++>100) {
	        		alert('Check whether you have forgotten the form tag!');
	        		break;
	        }
	      }

	    // append replacement
	    form.append(text);
	}
};

// CHECKBOX
// Usage: nemantis.forms.checkbox('rueckruf',{param:val});
// TODO: appendTo Option

nemantis.forms.checkbox = function(id,options) {
	var cb = {
			'init': function(id,options){
				var that=this;
				this.replacement='#nem-cb-replacement-'+id;
				var top=$('#'+id).css('top');
				var left=$('#'+id).css('left');

				// hide checkbox
				$('#'+id).css('opacity','0').css('left','-1000px');

				// append replacement
				nemantis.forms.append('#'+id,"<div id=\"nem-cb-replacement-"+id+"\" class=\"nem-cb\" style=\"position:absolute;top:"+top+";left:"+left+";\"></div>");

				// check state
				if($('#'+id).is(':checked')) {
					this.checked=1;
					$(this.replacement).addClass('checked');
				}

				// add event handlers
				$('#'+id).bind('focus', function(){that.focus();});
				$('#'+id).bind('blur', function(){that.blur();});
				$(this.replacement).bind('click',function(){that.click()});
				$(document).bind('keypress', function(e) {
					if(that.focused) {
						//alert(e.keyCode+' '+e.which);
						if(e.keyCode===0 && e.which===32) {
							that.click();
						}
					}
				});
			},
			'checked':0,
			'focused':0,
			'replacement':'',
			'focus': function() {
				this.focused=1;
				$(this.replacement).addClass('focused');
			},
			'blur':function() {
				this.focused=0;
				$(this.replacement).removeClass('focused');
			},
			'click':function() {
				$('#'+id).focus();
				if(this.checked==1) {
					this.checked=0;
					$('#'+id).removeAttr('checked');
					$(this.replacement).removeClass('checked');
				} else {
					this.checked=1;
					$('#'+id).attr('checked','checked');
					$(this.replacement).addClass('checked');
				}
			}
	};

	cb.init(id,options);
	return cb;
}

// RADIO
// Usage: nemantis.forms.radio('name',{param:val});
// TODO: appendTo Option

nemantis.forms.radio = function(id,options) {
	var radio = {
			'init': function(id,options){
				var that=this;
				this.replacement='#nem-radio-replacement-'+id;
				this.element='#'+id;
				this.name=$('#'+id).attr('name');
				var top=$('#'+id).css('top');
				var left=$('#'+id).css('left');

				// hide checkbox
				$('#'+id).css('opacity','0').css('left','-1000px');

				// append replacement
				nemantis.forms.append('#'+id,"<div id=\"nem-radio-replacement-"+id+"\" class=\"nem-radio\" style=\"position:absolute;top:"+top+";left:"+left+";\"></div>");

				// check state
				this.recheckState();

				// add event handlers
				$('#'+id).bind('focus', function(){that.focus();});
				$('#'+id).bind('blur', function(){that.blur();});
				$('#'+id).bind('change', function() {
					that.recheckState();
				});
				$(this.replacement).bind('click',function(){that.click()});
			},
			'recheckState':function() {
				if($(this.element).is(':checked')) {
					var old=this.checked;
					this.checked=1;

					if(old===0) {
						$('input[name='+this.name+']').change();
					}
					$(this.replacement).addClass('checked');
				} else {
					var old=this.checked;
					this.checked=0;

					if(old===1) {
						$('input[name='+this.name+']').change();
					}
					$(this.replacement).removeClass('checked');
				}
			},
			'name':undefined,
			'element':undefined,
			'checked':0,
			'focused':0,
			'replacement':'',
			'focus': function() {
				this.focused=1;
				$(this.replacement).addClass('focused');
				this.recheckState();
			},
			'blur':function() {
				this.focused=0;
				$(this.replacement).removeClass('focused');
			},
			'click':function() {
				$(this.replacement).addClass('checked');
				$(this.element).attr('checked','checked');
				this.recheckState();
				$('#'+id).focus();
			}
	};

	radio.init(id,options);
	return radio;
}

// SELECT
// Usage: nemantis.forms.select('rueckruf',{param:val});

/* Options:
 */
nemantis.forms.select = function(id,options) {
	var select = {
			'element':null,
			'init': function(id,options){
	  			var that=this;
	  			var osel=$('#'+id);
	  			this.element=osel;

	  			var val=osel.val();
	  			var top=osel.css('top');
	  			var left=osel.css('left');

	  			// hide selection
	  			$('#'+id).css('opacity','0').css('left','-1000px');

	  			// append replacement
	  			var val=osel.val();

	  			nemantis.forms.append('#'+id,"<div id=\"nem-select-replacement-"+id+"\" class=\"nem-sel\" style=\"position:absolute;top:"+top+";left:"+left+";\">Bitte wählen</div>");
	  			this.replacement='#nem-select-replacement-'+id;

	  			// get options
	  			var options=[];
	  			that=this;
	  			$($('#'+id)).find('option').each(function(e) {
	  				options.push({'text':$(this).html(),
	  							'value':$(this).attr('value')
	  				});

	  				if($(this).attr('value')===val) {
	  					$(that.replacement).html($(this).html());
	  				}
	  			});

	  			// create selection div
	  			var seltop=parseInt($(this.replacement).css('top'))+parseInt($(this.replacement).css('height'));

	  			var select='<div class="nem-sel-selection" id="nem-select-selection-'+id+'" style=\"display:none;position:absolute;top:'+seltop+'px;left:'+left+';\">';

	  			for ( var k in options) {
	  				select+='<div class="option" data-value="'+options[k]['value']+'">'+options[k]['text']+'</div>';
				}
	  			select+="</div>";

	  			nemantis.forms.append('#'+id,select);
	  			this.selection='#nem-select-selection-'+id;

	  			// check status
	  			if($('#'+id).hasClass('error')) {
	  				this.setError(1);
	  			}

	  			// bind event handlers
	  			$('#'+id).bind('focus', function(){that.focus();});
				$('#'+id).bind('blur', function(){that.blur();});
				$(this.replacement).bind('click', function(){that.showSelection();$('#'+id).focus();});
				$(this.selection).bind('click',function(e){that.click(e)});
			},
			'replacement':'',
			'selection':'',
			'focused':0,
			'error':0,
			'setError':function(val) {
				if(val) {
					$(this.replacement).addClass('error');
					this.error=true;
				} else {
					$(this.replacement).removeClass('error');
					this.error=false;
				}
			},
			'removeSelection': function() {
				$(this.selection).find('div.option').removeClass('selected');
			},
			'keyPress': function(event,that) {
				var val=$(that.replacement).html();
				var selected=null;

				var options=$(that.selection).find('div.option').each(function() {
					if($(this).html()===val) {
						selected=$(this);
					}
				});

				if(event.keyCode==38) { // up
					if(selected && selected.prev() && selected.prev().html()) {
						$(that.replacement).html(selected.prev().html());
						that.removeSelection();
						selected.prev().addClass('selected');
						$(that.element).val(selected.prev().attr('data-value'));
					}
				}
				if(event.keyCode==40) { // down
					if(selected && selected.next() && selected.next().html()) {
						$(that.replacement).html(selected.next().html());
						that.removeSelection();
						selected.next().addClass('selected');
						$(that.element).val(selected.next().attr('data-value'));
					}
				}

				if(event.keyCode==13) { // enter
					if(this.selectionVisible()) {
						this.hideSelection();
					} else {
						this.showSelection();
					}
				}
			},
			'selectionVisible':function() {
				if($(this.selection).css('opacity')==='1' && $(this.selection).css('display')==='block') {
					return true;
				} else {
					return false;
				}
			},
			'focus':function() {
				var val=$(this.replacement).html();
				var selected=null;

				var options=$(this.selection).find('div.option').each(function() {
					if($(this).html()===val) {
						selected=$(this);
					}
				});

				selected.addClass('selected');

				this.focused=1;
				$(this.replacement).addClass('focused');
				var that=this;
				this.kp=function(e) { that.keyPress(e,that); };
				$(document).bind('keypress',this.kp);
			},
			'blur':function() {
				this.focused=0;
				$(this.replacement).removeClass('focused');
				this.removeSelection();
				this.hideSelection();
				$(document).unbind('keypress',this.kp);
			},
			'showSelection': function() {
				$(this.selection).css('opacity','1');
				$(this.selection).css('display','block');
				clearTimeout(this.timeout);
			},'hideSelection': function() {
				that=this;
				$(this.selection).css('opacity','0');
				this.timeout=setTimeout(function() {$(that.selection).css('display','none')},500); // prevents that clicks trigger blur before click is handled*/
			},
			'timeout':null,
			'click': function (e) {
				$(this.replacement).html($(e.target).html());
				$(this.element).val($(e.target).attr('data-value'));
			}

  }

  select.init(id,options);

  return select;
}


// Button
// Usage: nemantis.forms.button('speichern',{param:val});

/* Options:
*/
nemantis.forms.button = function(id,options) {
	var button = {
			'element':null,
			'init': function(id,options){
	  			var that=this;
	  			var el=$('#'+id);
	  			this.element=el;

	  			var top=el.css('top');
	  			var left=el.css('left');

	  			// hide selection
	  			$('#'+id).css('opacity','0').css('left','-1000px');

 	  			nemantis.forms.append('#'+id,"<div id=\"nem-button-replacement-"+id+"\" class=\"nem-button\" style=\"position:absolute;top:"+top+";left:"+left+";\">"+$(el).val()+"</div>");
	  			this.replacement='#nem-button-replacement-'+id;

	  			// bind event handlers
	  			$('#'+id).bind('focus', function(){that.focus();});
				$('#'+id).bind('blur', function(){that.blur();});
				$(this.replacement).bind('mousedown', function(){that.mousedown();});
				$(this.replacement).bind('click', function(){that.click();});
			},
			'replacement':'',
			'focused':0,
			'focus':function() {
				this.focused=1;
				$(this.replacement).addClass('focused');
			},
			'blur':function() {
				this.focused=0;
				$(this.replacement).removeClass('focused');
			},
			'mousedown': function(e) {
				$(this.replacement).addClass('focused');
			},
			'click': function (e) {
				$(this.replacement).removeClass('focused');
				$(this.element).click();
			}
}

button.init(id,options);

return button;
}
