/** copyright 2009 -2011  Detlef Hahn
 * ==================================
 *  sorry in den scripten befindet sich teilweise noch alter unbenutzer Code.
 *  unsbesondere werden unterschiedliche Formen von Evenhandler verwendet, da 
 *  ich damit noch experimentiere
 *  
 */

/**
 *   Erweiterung der Klasse String um einige Funktionen, die häufig benötigt werden
 * 
 */
if (typeof(String.prototype.trim) === "undefined") {
String.prototype.trim 	= function() { return this.replace(/^\s+|\s+$/g,""); };
}
if (typeof(String.prototype.ltrim) === "undefined") {
String.prototype.ltrim 	= function() { return this.replace(/^\s+/,""); } ;
}
if (typeof(String.prototype.rtrim) === "undefined") {
String.prototype.rtrim 	= function() { 	return this.replace(/\s+$/,""); };
}
if (typeof(String.prototype.strpos) === "undefined") {
String.prototype.strpos	= function( str, such, offset){
    var i = (str+'').indexOf(such, (offset ? offset : 0));
    return i === -1 ? false : i;
};
}
  var jsfile="basis.js";
  var about_js=[];
  var jetzt = new Date();
  about_js.push((jetzt.getTime()/1000)+" &nbsp; "+jsfile+"= 1.1 \tBuilddate=30.12.10 15:40");
  
  function  showAbout(id){ 
	  var jetzt = new Date();
	  toggleDiv(id);
	  var html="<br><p class=\"center\">  &nbsp; Copyright &copy;  2005 - "+jetzt.getFullYear()+" Detlef Hahn <br></p>\n";
	  for(var i=0;i<about.length;i++){
		  html+=" &nbsp;  "+about[i].substr(7)+"<br>\n";
	  }  
	  for(var i=0;i<about_js.length;i++){
		  html+=" &nbsp;  "+about_js[i].substr(7)+"<br>\n";
	  }
	  html+="<br>";;
	  document.getElementById("aboutText").innerHTML=html;
  	}
 
    /**
	*  entspricht etwa dem shell-command basename
	*  liefert den Programmnamen  zurück
	*  die Extension kann hier jedoch nicht mit abgeschnitten werden
	*  wandelt Backslash   \  (Windoof) in slash /
	*  @param  path		Pfad in Linux oder Windowsformat
  	*/
	function basename(path) {
	    return path.replace(/\\/g,'/').replace( /.*\//, '' );
	}
	
	 
	/**
	*  entspricht dem shell-command dirname
	*  liefert Verzeichnisname ohne abschliessenden / zurück
	*  wandelt Backslash   \  (Windof) in slash /
	*  @param  path		Pfad in Linux oder Windowsformat
  	*/
	function dirname(path) {
	    return path.replace(/\\/g,'/').replace(/\/[^\/]*$/, '');
	}

    /**
     * Entfern die File-Extension
     * @param 	fln
     * @return
     */
	function drop_ext(fln){
		return fln.replace(/\..*$/,"");
	}

	function IsNumeric(input){
	    var RE = /^-{0,1}\d*\.{0,1}\d+$/;
	    return (RE.test(input));
	}
	/**
	 * fügt einen neuen Knoten ein
	 * @param parent
	 * @param node
	 * @param referenceNode
	 * @return
	 */
	function insertAfter(parent, node, referenceNode) {
		parent.insertBefore(node, referenceNode.nextSibling);
	}
	
	/**
	 * liefert die angefragten Klassenelement zurück
	 * 
	 * @param searchClass	erforderlich
	 * @param node			optional
	 * @param tag			optional
	 * @return
	 */
	function getElementsByClass(searchClass,node,tag) {
		var classElements = new Array();
		if ( node == null )
			node = document;
		if ( tag == null )
			tag = '*';
		var els = node.getElementsByTagName(tag);
		var elsLen = els.length;
		var pattern = new RegExp('(^|\\\\s)'+searchClass+'(\\\\s|$)');
		for (i = 0, j = 0; i < elsLen; i++) {
			if ( pattern.test(els[i].className) ) {
				classElements[j] = els[i];
				j++;
			}
		}
		return classElements;
	}

	/**
	 *  sucht Position von suchstr in str,  (analog PHP)
	 *  ist als einfache Funktion ausgelegt, kein Prototype von String
	 *  
	 * @param suchstr
	 * @param str
	 * @param offset
	 * @return
	 */
	function strpos ( suchstr, str, offset) {
	    // suche die Position von suchstr in str (beachte Offset)  
		var i = (str+'').indexOf(suchstr, (offset ? offset : 0));
		return i === -1 ? false : i;
	}
	
	/**
	 * ermittelt Stringlänge (analog zu PHP)
	 * @param str
	 * @return
	 */
	function strlen(str){
	   return str.length;
	}
	
	/**
	 * 
	 * @param search
	 * @param replace
	 * @param subject
	 * @return
	 */
	function str_replace (search, replace, subject)
	{
	  var result = "";
	  var  oldi = 0;
	  for (i = subject.indexOf (search) ; i > -1 ; i = subject.indexOf (search, i))
	  {
	    result += subject.substring (oldi, i);
	    result += replace;
	    i += search.length;
	    oldi = i;
	  }
	  return result + subject.substring (oldi, subject.length);
	}

	/** ===============================================================================
	 *  
	 *  
	 ** ===============================================================================
	 */
	var shortcut={
		'all_shortcuts':{},//All the shortcuts are stored in this array
		'add': function(shortcut_combination,callback,opt) {
			//Provide a set of default options
			var default_options = {
				'type':'keydown',
				'propagate':false,
				'disable_in_input':false,
				'target':document,
				'keycode':false
			}
			if(!opt) opt = default_options;
			else {
				for(var dfo in default_options) {
					if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
				}
			}

			var ele = opt.target;
			if(typeof opt.target == 'string') ele = document.getElementById(opt.target);
			var ths = this;
			shortcut_combination = shortcut_combination.toLowerCase();

			//The function to be called at keypress
			var func = function(e) {
				e = e || window.event;
				
				if(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
					var element;
					if(e.target) element=e.target;
					else if(e.srcElement) element=e.srcElement;
					if(element.nodeType==3) element=element.parentNode;

					if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return null;
				}
		
				//Find Which key is pressed
				if (e.keyCode) code = e.keyCode;
				else if (e.which) code = e.which;
				var character = String.fromCharCode(code).toLowerCase();
				
				if(code == 188) character=","; //If the user presses , when the type is onkeydown
				if(code == 190) character="."; //If the user presses , when the type is onkeydown

				var keys = shortcut_combination.split("+");
				//Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
				var kp = 0;
				
				//Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
				var shift_nums = {
					"`":"~",
					"1":"!",
					"2":"@",
					"3":"#",
					"4":"$",
					"5":"%",
					"6":"^",
					"7":"&",
					"8":"*",
					"9":"(",
					"0":")",
					"-":"_",
					"=":"+",
					";":":",
					"'":"\"",
					",":"<",
					".":">",
					"/":"?",
					"\\":"|"
				}
				//Special Keys - and their codes
				var special_keys = {
					'esc':27,
					'escape':27,
					'tab':9,
					'space':32,
					'return':13,
					'enter':13,
					'backspace':8,
		
					'scrolllock':145,
					'scroll_lock':145,
					'scroll':145,
					'capslock':20,
					'caps_lock':20,
					'caps':20,
					'numlock':144,
					'num_lock':144,
					'num':144,
					
					'pause':19,
					'break':19,
					
					'insert':45,
					'home':36,
					'delete':46,
					'end':35,
					
					'pageup':33,
					'page_up':33,
					'pu':33,
		
					'pagedown':34,
					'page_down':34,
					'pd':34,
		
					'left':37,
					'up':38,
					'right':39,
					'down':40,
		
					'f1':112,
					'f2':113,
					'f3':114,
					'f4':115,
					'f5':116,
					'f6':117,
					'f7':118,
					'f8':119,
					'f9':120,
					'f10':121,
					'f11':122,
					'f12':123
				}
		
				var modifiers = { 
					shift: { wanted:false, pressed:false},
					ctrl : { wanted:false, pressed:false},
					alt  : { wanted:false, pressed:false},
					meta : { wanted:false, pressed:false}	//Meta is Mac specific
				};
	                        
				if(e.ctrlKey)	modifiers.ctrl.pressed = true;
				if(e.shiftKey)	modifiers.shift.pressed = true;
				if(e.altKey)	modifiers.alt.pressed = true;
				if(e.metaKey)   modifiers.meta.pressed = true;
	                        
				for(var i=0; k=keys[i],i<keys.length; i++) {
					//Modifiers
					if(k == 'ctrl' || k == 'control') {
						kp++;
						modifiers.ctrl.wanted = true;

					} else if(k == 'shift') {
						kp++;
						modifiers.shift.wanted = true;

					} else if(k == 'alt') {
						kp++;
						modifiers.alt.wanted = true;
					} else if(k == 'meta') {
						kp++;
						modifiers.meta.wanted = true;
					} else if(k.length > 1) { //If it is a special key
						if(special_keys[k] == code) kp++;
						
					} else if(opt['keycode']) {
						if(opt['keycode'] == code) kp++;

					} else { //The special keys did not match
						if(character == k) kp++;
						else {
							if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
								character = shift_nums[character]; 
								if(character == k) kp++;
							}
						}
					}
				}
				
				if(kp == keys.length && 
							modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
							modifiers.shift.pressed == modifiers.shift.wanted &&
							modifiers.alt.pressed == modifiers.alt.wanted &&
							modifiers.meta.pressed == modifiers.meta.wanted) {
					callback(e);
		
					if(!opt['propagate']) { //Stop the event
						//e.cancelBubble is supported by IE - this will kill the bubbling process.
						e.cancelBubble = true;
						e.returnValue = false;
		
						//e.stopPropagation works in Firefox.
						if (e.stopPropagation) {
							e.stopPropagation();
							e.preventDefault();
						}
						return false;
					}
				}
				return false;
			}
			this.all_shortcuts[shortcut_combination] = {
				'callback':func, 
				'target':ele, 
				'event': opt['type']
			};
			//Attach the function with the event
			if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
			else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
			else ele['on'+opt['type']] = func;
		},

		//Remove the shortcut - just specify the shortcut and I will remove the binding
		'remove':function(shortcut_combination) {
			shortcut_combination = shortcut_combination.toLowerCase();
			var binding = this.all_shortcuts[shortcut_combination];
			delete(this.all_shortcuts[shortcut_combination])
			if(!binding) return;
			var type = binding['event'];
			var ele = binding['target'];
			var callback = binding['callback'];

			if(ele.detachEvent) ele.detachEvent('on'+type, callback);
			else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
			else ele['on'+type] = false;
		},
		
		// Remove all shutcuts in Liste
		'removeAll': function() {
			for(x in this.all_shortcuts) {
				this.remove(x);
			}
		} 
	}  // Ende shortcut
	
	function dump(arr,level) {
		var dumped_text = "";
		if(!level) level = 0;
		
		//The padding given at the beginning of the line.
		var level_padding = "";
		for(var j=0;j<level+1;j++) level_padding += "    ";
		
		if(typeof(arr) == 'object') { //Array/Hashes/Objects 
			for(var item in arr) {
				var value = arr[item];
				
				if(typeof(value) == 'object') { //If it is an array,
					dumped_text += level_padding + "'" + item + "' ...\n";
					dumped_text += dump(value,level+1);
				} else {
					dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
				}
			}
		} else { //Stings/Chars/Numbers etc.
			dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
		}
		return dumped_text;
	}
	/**
	 *  Zeigt Div in jedem Fall an
	 */
	if(typeof show_div != 'function')
	 function show_div(id){
		 var div_el = document.getElementById(id);
	 	 if (div_el.style.display != 'block')
	       {  div_el.style.display='block';
	         var img_el = document.getElementById('img'+(id));
	         if(img_el != null) {img_el.src = '/common_classes/img/hide.png';}
	      }
	  }
	
	/** 
	 * ist auch in klasse menu
	*  erwarte die ID und setzt die CSS-Display-Eigenschaft auf none/block
	*  ersetzt scr des image damit + - erscheint 
	*  @param  id		id des Images
	*/
	if(typeof toggleDiv != 'function') 
		function toggleDiv(id)
     {    
	     var div_el = document.getElementById(id);
         var img_el = null;
         img_el=document.getElementById('img'+(id));
         
         if (div_el.style.display != 'none')
         {  div_el.style.display='none';
            if(img_el !=null){ img_el.src = '/common_classes/img/show.png'; }
         }
         else
         {  div_el.style.display='block';
         if(img_el !=null){ img_el.src = '/common_classes/img/hide.png'; }
         }
     } 
// ================================================================================

	// https://developer.mozilla.org/en/DOM/element.classList
	// elementClasses is a DOMTokenList representing the class attribute of elementNodeReference.  
	// If the class attribute was not set or is empty elementClasses.length returns 0. 
	// element.classList is read-only.
	
	// Since other browser vendors have not yet implemented the HTML5 classList API, 
	// you still need fallback code. You can use this sample code as fallback.
	// http://demos.hacks.mozilla.org/openweb/classList/classList.js
	
	// Fallback für Classlist
	var containsClass = function (elm, className) {
	    if (document.documentElement.classList) {
	        containsClass = function (elm, className) {
	            return elm.classList.contains(className);
	        }
	    } else {
	        containsClass = function (elm, className) {
	            if (!elm || !elm.className) {
	                return false;
	            }
	            var re = new RegExp('(^|\\s)' + className + '(\\s|$)');
	            return elm.className.match(re);
	        }
	    }
	    return containsClass(elm, className);
	}

	var addClass = function (elm, className) {
	    if (document.documentElement.classList) {
	        addClass = function (elm, className) {
	            elm.classList.add(className);
	        }
	    } else {
	        addClass = function (elm, className) {
	            if (!elm) {
	                return false;
	            }
	            if (!containsClass(elm, className)) {
	                elm.className += (elm.className ? " " : "") + className;
	            }
	            return true;   // eingefügt wg returnwert
	        }
	    }
	    addClass(elm, className);
	    return true;              // hinzugefügt
	}

	var removeClass = function (elm, className) {
	    if (document.documentElement.classList) {
	        removeClass = function (elm, className) {
	            elm.classList.remove(className);
	        }
	    } else {
	        removeClass = function (elm, className) {
	            if (!elm || !elm.className) {
	                return false;
	            }
	            var regexp = new RegExp("(^|\\s)" + className + "(\\s|$)", "g");
	            elm.className = elm.className.replace(regexp, "$2");
	            return true; // eingefügt wg returnwert
	        }
	    }
	    removeClass(elm, className);
	    return true;		// hinzugefügt
	}

	var toggleClass = function (elm, className)
	{
	    if (document.documentElement.classList) {
	        toggleClass = function (elm, className) {
	            return elm.classList.toggle(className);
	        }
	    } else {
	        toggleClass = function (elm, className) {
	            if (containsClass(elm, className))
	            {
	                removeClass(elm, className);
	                return false;
	            } else {
	                addClass(elm, className);
	                return true;
	            }
	        }
	    }
	    return toggleClass(elm, className);
	}
