/*
 * Fancyform - jQuery Plugin
 * Simple and fancy form styling alternative
 *
 * Examples and documentation at: http://www.lutrasoft.nl/jQuery/fancyform/
 * 
 * Copyright (c) 2010 - Lutrasoft
 * 
 * Version: 1.0.7 (23/03/2011)
 * Requires: jQuery v1.3+
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */
(function($) {
    $.fn.extend({
		/*
			Get the caret on an textarea
		*/
		caret: function (start, end) {
			var elem = this[0];

			if (elem) {							
				// get caret range
				if (typeof start == "undefined") {
					if (elem.selectionStart) {
						start = elem.selectionStart;
						end = elem.selectionEnd;
					}
					else if (document.selection) {
						var val = this.val();
						var range = document.selection.createRange().duplicate();
						range.moveEnd("character", val.length)
						start = (range.text == "" ? val.length : val.lastIndexOf(range.text));

						range = document.selection.createRange().duplicate();
						range.moveStart("character", -val.length);
						end = range.text.length;
					}
				}
				// set caret range
				else {
					var val = this.val();

					if (typeof start != "number") start = -1;
					if (typeof end != "number") end = -1;
					if (start < 0) start = 0;
					if (end > val.length) end = val.length;
					if (end < start) end = start;
					if (start > end) start = end;

					elem.focus();

					if (elem.selectionStart) {
						elem.selectionStart = start;
						elem.selectionEnd = end;
					}
					else if (document.selection) {
						var range = elem.createTextRange();
						range.collapse(true);
						range.moveStart("character", start);
						range.moveEnd("character", end - start);
						range.select();
					}
				}

				return {start:start, end:end};
			}
		},
			
		/*
			Replace radio buttons with images
		*/
       transformRadio: function(options) {

            var defaults = {
            	checked : "img/content/radio_checked.gif",
				unchecked : "img/content/radio.gif"
            };

            var options = $.extend(defaults, options);

            return this.each(function() {
				
				// Radio hide
				$(this).hide();
				
				// Afbeelding
				if($(this).is(":checked"))
				{
					$(this).after("<img src='" + options.checked + "' />");	
				}
				else
				{
					$(this).after("<img src='" + options.unchecked + "' />");	
				}
				
				$(this).next("img").first().click(function(){
					// Afbeelding switchen
					$(this).attr("src", options.checked);
					$(this).siblings("img").attr("src", options.unchecked);
					
					// Radio button checkedn
					$(this).prev("input:radio").attr("checked", "checked");
				});
			});
	   },
	   /*
	   		Replace checkboxes with images
	   */
	   transformCheckbox: function(settings) {

            var defaults = {
            	checked : "images/content/filterBoxCheckboxChecked.jpg",
				unchecked : "images/content/filterBoxCheckbox.jpg"
            };

            var options = $.extend(defaults, settings);
            
            var method = {
                uncheck : function()
                {
                    // Afbeelding switchen
				    $(this).attr("src", options.unchecked);
					
				    // Radio button checkedn
				    $(this).prev("input:checkbox").removeAttr("checked");
                },
                check : function()
                {
                     // Afbeelding switchen
				    $(this).attr("src", options.checked);
					
				    // Radio button checkedn
				    $(this).prev("input:checkbox").attr("checked", "checked");
                }
            }

            return this.each(function() {
			    if(typeof(settings) == "string")
			    {
			        method[settings].call($(this).next("img"));
			    }
			    else
			    {	
				    // Radio hide
				    $(this).hide();
    				
				    // Afbeelding
				    if($(this).is(":checked"))
				    {
					    $(this).after("<img src='" + options.checked + "' />");	
				    }
				    else
				    {
					    $(this).after("<img src='" + options.unchecked + "' />");	
				    }
    				
				    $(this).next("img").click(function(){
					    if($(this).prev().is(":checked"))
					    {
						    method.uncheck.call(this);
					    }
					    else
					    {
						    method.check.call(this);
					    }
				    });
				}
			});
	   },
	   /*
	   		Replace select with list
	   		=========================
	   		HTML will look like
			<ul>
				<li><span>Selected value</span>
					<ul>
						<li><span>Option</span></li>
						<li><span>Option</span></li>
					</ul>
				</li>
			</ul>
	   */
	   transformSelect: function(options) {
			var defaults = {
				selectedContainer	: "span",
				dropDownClass		: "transformSelect"
			};
			
			var vars = {me : null};
			var options = $.extend(defaults, options);
	
			return this.each(function() {
				// Zet mezelf als var
				vars.me = $(this);
				
				// Hide mezelf
				$(this).hide();
				
				// Generate HTML
				var selectedIndex = -1;
				if( $(this).find("option:selected").length > 0 )
					selectedIndex = $(this).find("option").index($(this).find("option:selected"));
				else
					selectedIndex = 0;	
				
				// Maak een ul aan
				var $ul = $("<ul/>").addClass(options.dropDownClass).addClass("trans-element");
				var $li = $("<li />");
				var $span = $("<span />");
				
				// span vullen met geselecteerde waarde
				$span.html($(this).find("option").eq(selectedIndex).text());
				$li.append($span);
				$ul.append($li);
				$li.append("<ul />");
				
				var $drop = $li.find("ul");
				$drop.hide();
				// Door loop de items (option)
				$(this).find("option").each(function(){
					// Maak een LI voor de options
					var $li = $("<li />");	
					$li.append("<span />")
					$li.find("span").html($(this).text());
					$drop.append($li);
					
					// Als er wordt geklikt op een nieuwe waarde
					$li.click(selectNewValue);
				});
				$(this).after($ul);
				
				
				//$(this).find(options.selectedContainer).click(openDrop);
				$("html").click(closeDropDowns);
				$span.click(openDrop);
				return this;
			});
	
			function selectNewValue()
			{
				var index = $(this).parent().find("li").index($(this));	
				var $ul = $(this).closest("." + options.dropDownClass);
				$ul.prev("select").get(0).selectedIndex = index;
				$("." + options.dropDownClass).find("ul").hide();
				$ul.find("span:eq(0)").html($(this).text());
				// Trigger onchange
				$(this).parent().parent().parent().prev("select").trigger("change");
			}
			
			function openDrop()
			{
				$(this).parent().find("ul").css({'z-index' : 100}).parent().css({'z-index' : 100});
				$(this).parent().find("ul").show();

				// Hide elements with the same class
				var elIndex = $("body").find("*").index($(this).parent());
				
				$("body").find("." + options.dropDownClass + ", ul.trans-element").each(function(){
				    if(elIndex - 1 != $("body").find("*").index($(this)))
				    {
				        $(this).find("ul").hide().css({'z-index' : 0}).parent().css({'z-index' : 0});
				    }
				});
			}
			function closeDropDowns(e)
			{
				var $el = $("." + options.dropDownClass).find("ul");
				if($(e.target).closest("." + options.dropDownClass).length == 0)
					$("." + options.dropDownClass).find("ul").hide();	
			}
			
		},
		/*
			Transform a input:file to your own layout
			============================================
			Basic CSS:
				<style>
					div.fileinputs {
						position: relative;
					}
					
					div.fakefile {
						position: absolute;
						top: 0px;
						left: 0px;
						z-index: 1;
					}
					
					input.file {
						position: relative;
						text-align: right;
						height:28px;
						-moz-opacity:0 ;
						filter:alpha(opacity: 0);
						opacity: 0;
						z-index: 2;
					}
				</style>
		*/
		transformFile : function(options) {
			var defaults = {
				defaultValue : "Browse",
				buttonClass	 : "fileButton",
				inputClass	 : "fileInput"
			};
			
			var vars = {me : null};
			var options = $.extend(defaults, options);
	
			return this.each(function(i) {
				var label = $(this).attr('title'); //get title attribut for languagesettings
				if(label == ''){
					label = options.defaultValue;
				}
				  
				var uploadbutton = $('<input type="button" value="' + label + '" />')
										.addClass(options.buttonClass);
				
				$(this).wrap('<div class="fileinputs"></div>');
				
				$(this).addClass('file').css('opacity', 0); //set to invisible
				
				var input = $('<input type="text" />')
								.attr('id', i +  '__fake')
								.addClass(options.inputClass);
								
				var fakefile = $('<div class="fakefile" />')
									.append(input)
									.append(uploadbutton);
									
				$(this).parent().append(fakefile);
				 
				$(this).bind('change', function() {
					$('#' + i +  '__fake').val($(this).val());
				});
				
				$(this).bind('mouseout', function() {
					$('#' + i +  '__fake').val($(this).val());
				});
				
				$(this).width(fakefile.innerWidth());

				return this;
		    });
		},
		/*
	   		Replace a textarea
	   */
		transformTextarea : function(options, arg1){
			var defaults = {
				hiddenTextareaClass : "hiddenTextarea"
			};
	
			var settings = $.extend(defaults, options);
			
			method = {
				// Init the module
				init : function()
				{
					
					// This only happens in IE
					if($(this).css("line-height") == "normal")
					{
						$(this).css("line-height", "12px");
					}
					
					// Set the CSS
					var CSS = {
						'line-height' 	: $(this).css("line-height"),
						'font-family'	: $(this).css("font-family"),
						'font-size' 	: $(this).css("font-size"),
						"border"		: "1px solid black",
						"width"			: $(this).width(),
						"letter-spacing": $(this).css("letter-spacing"),
						"text-indent"	: $(this).css("text-indent"),
						"padding"		: $(this).css("padding"),
						"overflow"		: "hidden",
						"white-space"	: $(this).css("white-space")
					};
					
					$(this)
						// Add a new textarea
							.css(CSS)
							.keyup(method.keyup)
						// Append a div
						.after($("<div />"))
							.next()
							.addClass(settings.hiddenTextareaClass)
							.css(CSS)
							.css("width", $(this).width() - 5)	// Minus 5 because there is some none typeable padding?
							.hide()
							;
				},
				
				// Used to scroll 
				keyup : function(e)
				{	
					// Check if it has to scroll
					// Arrow keys down have to scroll down / up (only if to far)
					/*
						Keys:
						37, 38, 39, 40  = Arrow keys (L,U,R,D)
						13				= Enter
					*/
					var ignore = [37,38,39,40];
					if($.inArray(e.which, ignore) != -1)
					{
						method.checkCaretScroll.call(this);
					}
					else
					{
						method.checkScroll.call(this);
					}
				},
				/*
					Check cursor position to scroll
				*/
				checkCaretScroll : function()
				{
					var src = $(this);
					var caretStart = src.caret().start;
					var textBefore = src.val().substr(0, caretStart);
					var tar = src.next("." + settings.hiddenTextareaClass);	
					var vScroll = null;
					
					// First or last element (don't do anything)
					if(!caretStart || caretStart == 0)
						return false;
					
					// Also pick the first char of a row
					if(src.val().substr(caretStart - 1, 1) == '\n')
					{
						textBefore = src.val().substr(0, caretStart + 1);
					}
							
					method.toDiv.call(this, false, textBefore);
					
					// If you go through the bottom
					if(tar.height() > (src.height() + src.scrollTop()))
					{
						vScroll = src.scrollTop() + parseInt(src.css("line-height"));
					}
					// if you go through the top
					else if(tar.height() <= src.scrollTop())
					{
						vScroll = src.scrollTop() - parseInt(src.css("line-height"));	
					}
					
					
					// Scroll the px
					if(vScroll)
						method.scrollToPx.call(this, 
									method.roundToLineHeight.call(
																this, 
																vScroll
																)
											);
				},
				
				// Check the old and new height if it needs to scroll
				checkScroll : function()
				{
					// Put into the div to check new height
					method.toDiv.call(this, true);
					
					// Scroll if needed
					var src = $(this);
					var tar = $(this).next("." + settings.hiddenTextareaClass);
					
					// Scroll if needed
					if(tar.data("old-height") != tar.data("new-height"))
					{
						var scrollDiff = tar.data("new-height") - tar.data("old-height");
						method.scrollToPx.call(this, src.scrollTop() + scrollDiff);
					}
				},
				
				// Place the value of the textarea into the DIV
				toDiv : function(setHeight, html)
				{
					var src = $(this);
					var tar = $(this).next("." + settings.hiddenTextareaClass);	
					var regEnter = /\n/g;
					var regSpace = /\s\s/g;
					var res = src.val();
					if(html)
						res = html;
					
					// Set old and new height + set the content
					if(setHeight)
						tar.data("old-height", tar.height());
					res = res.replace(regEnter,"<br>"); // No space or it will be replaced by the function below
					res = res.replace(regSpace,"&nbsp; ");
					res = res.replace(regSpace,"&nbsp; "); // 2x because 1x can result in: &nbsp;(space)(space) and that is not seen within the div
					tar.html(res);
					if(setHeight)
						tar.data("new-height", tar.height());
				},
				
				// Is the textarea max scrolled?
				/*
				isMaxScrolled : function()
				{
					var src = $(this);
					var tar = $(this).next();	
					var maxScroll = tar.height() - src.height();
					
					// if not max scroll
					if(src.scrollTop() < maxScroll)
						return false;
						
					return true;
				},
				*/
				
				// Scroll to a given percentage
				scrollToPercentage : function(perc)
				{
					// Between 0 and 100
					if(perc < 0 || perc > 100)
						return this;
					
					var src = $(this);
					var tar = $(this).next("." + settings.hiddenTextareaClass);	
					
					var maxScroll = tar.height() - src.height();
					var scrollT = maxScroll * perc / 100;

					// Round on a row
					method.scrollToPx.call(this, scrollT);
				},
				
				// Scroll to given PX
				scrollToPx : function(px)
				{
					var src = $(this);
					var scrollT = method.roundToLineHeight.call(this, px);

					// Round on a row
					src.scrollTop(scrollT);
				},
				
				// Round to line height
				roundToLineHeight : function(num)
				{
					var src = $(this);
					return Math.floor(num / parseInt(src.css("line-height"))) * parseInt(src.css("line-height"));
				},
				
				// Reset to default
				remove	: function()
				{
					$(this)
						.unbind("keyup")
						.css({
							overflow 	: "auto",
							border		: ""
						})
					.next()
						.remove();	
				}
			};
			
			if(typeof(options) == "string")
			{
				method[options].call(this, arg1);
				return this;	
			}
			return this.each(function(){
				if(!$(this).next().hasClass(settings.hiddenTextareaClass))
				{
					method.init.call(this);
					method.toDiv.call(this, true);
				}
			});	
		}
    });

})(jQuery);




