/* *
 * Javascript Pack
 * Basic Method
 * Author Deo 2010.01.05
 * */

if (typeof jpack == "undefined" || !jpack) { var jpack = {}; }
jpack.namespace = function() {
    var a = arguments, o = null, i, j, d;
    for (i = 0; i < a.length; i = i + 1) {
        d = ("" + a[i]).split("."); 
        o = jpack;
		
        for (j = (d[0] === "jpack") ? 1 : 0; j < d.length; j = j + 1) {
            o[d[j]] = o[d[j]] || {};
            o = o[d[j]];
        }
    }
    return o;
};
jpack.namespace("jpack.structure", "jpack");
jpack.structure = (function(){
	var ERR = {
		// Get Gradient
		gg: {
			0: 'ERROR: Required "vertical" or "horizontal"'
		}
	};
							
	var userAgent = navigator.userAgent.toLowerCase();
	
	// Get current style
	function GetCurrentStyle( obj, cssproperty, csspropertyNS ) {
		if(obj.style[cssproperty]){  
			return obj.style[cssproperty];  
		}  
		if (obj.currentStyle) {// IE5+ 
			return obj.currentStyle[cssproperty];  
		} else if (document.defaultView.getComputedStyle(obj, null)) {// FF/Mozilla  
			var currentStyle = document.defaultView.getComputedStyle(obj, null);  
			var value = currentStyle.getPropertyValue(csspropertyNS);  
			if(!value){//try this method  
				value = currentStyle[cssproperty];  
			} 
			return value;  
		}else if (window.getComputedStyle) {// NS6+  
			var currentStyle = window.getComputedStyle(obj, "");  
			return currentStyle.getPropertyValue(csspropertyNS);  
		}
	}
	
	/* *
	 * Create Gradient
	 * Selector key:
	 * Required:
	 * 	'horizontal' or 'vertical'
	 *	'width' and 'height' and 'background'
	 * Options:
	 *	'left' and 'top'
	 * */	
	function GetGradient( selector ) {
		
		var // Gradient object
			gradient = document.createElement('div'), 
			
			sr = selector, start, end, temp, arr = [], grad_width, width, height;
		
		// Vertical
		if( sr.vertical ) {
			start = sr.vertical == '<'? 0: sr.height * -1;
			end = sr.vertical == '<'? sr.height: 0;
			
			grad_width = width = sr.width;
			height = 1;
		}
		
		// Horizontal
		if( sr.horizontal ) {
			start = sr.horizontal == '<'? 0: sr.width * -1;
			end = sr.horizontal == '<'? sr.width: 0;
			
			width = 1;
			grad_width = height = sr.height;
		}
		
		if( !sr.vertical && !sr.horizontal ) {
			alert( ERR.gg[0] );
			return null;
		}
		
		jpack.css( gradient, {
			'width'		: grad_width +'px',
			'position'	: 'absolute', 
			'z-index'	: 99999
		});
		
		if( sr.top ) jpack.css( gradient, {'top': sr.top +'px'});
		if( sr.left ) jpack.css( gradient, {'left': sr.left +'px'});
		
		var temp = '<div style="display:inline-block;width:'+ width +'px;height:'+ height +'px;background:'+ sr.background +';opacity:*;filter:alpha(opacity=**)"></div>';
		
		for( var i = start; i < end; i ++ ) {
			var add_zero = '', value = end != 0? ( Math.round( i / end * 100 ) / 100 ): ( Math.round( i / start * 100 ) / 100 );
			
			if( new String( value ).length > 1 )
				for( var j = 0; j < 4 - new String( value ).length; j ++ )
					add_zero += '0';
			
			// Delete the first zero and point
			value = ( value + add_zero ).replace( /\d\./, '' );
			
			// Replace value 1 to 100
			value = ( value == 1 && value.length == 1 )? 100: value;
			
			arr[arr.length] = temp.replace( /\*/, value / 100 ).replace( /\*\*/, value );
		}
		
		gradient.innerHTML = arr.join('');
		
		return gradient;
	}
	
	return {
		// Figure out what browser is being used
		browser: {
			version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
			safari: /webkit/.test( userAgent ),
			opera: /opera/.test( userAgent ),
			msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
			mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
		}	
		
		,$: function( id ) { return document.getElementById( id ); }
		
		,extend: function( destination, source ){
			for( var property in source )
				destination[ property ] = source[ property ];
		}
		
		,each: function(arr, func) {
			var i = 0, len = arr.length;
			for (; i < len; i ++) {
				if (func && typeof func == 'function') {
					var a = arr[ i ];
					func(a, i);
				}
			}
		}
		
		// whether a string contains a certain word
		,instring: function(str, matcher) {
			var strArr = str.split(/\s+/);
			for (var i = 0; i < strArr.length; i ++)
				if (strArr[i] == matcher) return true;
			return false;
		}
		
		,bind: function( obj, eventType, handler ) {
			if (obj.addEventListener) {
				obj.addEventListener(eventType, handler, false);
			} else if (obj.attachEvnet) {
				obj.attachEvent('on'+eventType, handler)			
			} else {
				obj['on'+eventType] = handler;
			}
		}
	
		// Operate element's className
		,classEvent: function( elem ) {
			var arr = [], map = {}, isClass = false;
			
			function eachClass( elem, className ) {
				var hasClass = elem.className.split(/\s+/);
				for (var i = 0; i < hasClass.length; i ++) {
					if (hasClass[i] != className) { map[ hasClass[i] ] = hasClass[i]; }
					else { isClass = true; }
					arr.push( hasClass[i] );
				}
			}
			
			return {
				add: function( className ) {
					eachClass( elem, className );
					
					if ( !isClass ) { arr.push( className ); }
					elem.className = arr.join(" ").replace(/^\s*|\s*$/g,'');
				},
				remove: function( className ) {
					eachClass( elem, className );
					
					arr = []; for (var key in map) { arr.push( key ); }
					elem.className = arr.join(" ").replace(/^\s*|\s*$/g,'');
				}
			}
		}
		
		// Set element's style
		,css: function(obj, options) {
			var arr = [];
			if (typeof obj == 'object' && options && typeof options == 'object') {
				if ( obj.length != undefined ) arr = obj;
				else arr.push( obj );
				
				for ( var i = 0; i < arr.length; i ++ ) {				
					for( var name in options ){
						var nameCase = name.replace(/\-(\w)/g, function($2, $1){
							return $1.toUpperCase();
						});
						
						arr[ i ].style[nameCase] = options[name];
						if( document.all && name == 'opacity' )
							arr[ i ].style.filter = 'alpha(opacity='+options["opacity"]*100+')';
					}
				}
			}
		}
		
		// Get current style
		,getCurrentStyle: function( obj, csspropertyNS ) {
			// eg: padding-left
			var cssproperty = csspropertyNS.replace( /-\w/, function( $1 ) { 
				return $1.replace('-', '').toUpperCase(); 
			});
			
			return GetCurrentStyle( obj, cssproperty, csspropertyNS );
		}
		
		// Add newEl to targetEl
		,insertAfter: function( newEl, targetEl ) {
			var parentEl = targetEl.parentNode;
			
			if( parentEl.lastChild == targetEl ) {
				parentEl.appendChild( newEl );
			} else {
				parentEl.insertBefore( newEl, targetEl.nextSibling );
			}            
		}
		
		,trim: function( str ) {
			return str.replace(/^\s*|\s*$/g, '');
		}
		
		,trimAll: function( str ) {	
			return str.replace(/\s*/g, ''); 
		}
		
		// Replace Chinese words
		,replaceChineseWords: function( str, re ){
			// Check charCode: unicode
			var newstr = '';
			for( var i = 0; i < str.length; i ++ ) {
				var letter = str.charAt( i );
				
				// Replace Chinese words
				if( str.charCodeAt( i ) > 128 ) {
					letter = re;
				}
				
				newstr += letter;
			}
			
			return newstr;
		}
		
		// Get the string word after blank
		// String abbreviate
		,getEngWordsAbbrev: function( str ) {
			// Add blank after the uppercase letter
			str = str.replace( /[A-Z]/g, function( $1 ) { return ' '+ $1; } );
			
			// Get New string
			str = this.trim( str );
			
			// To Do
			var splitArr = str.split( /\s+/ ), strArr = [];
			
			for( var i = 0; i < splitArr.length; i ++ ) {
				var word = splitArr[ i ], w_len = word.length;
				if( typeof word == 'string' || typeof word == 'number' ) {
					strArr.push( this.trim( word.charAt( 0 ) ) );
				}
			}
			
			return splitArr.length > 1? strArr: str;
		}
		
		// JSON
		,JSON: function( data ) {
			
			return {
				// Check Json array whether null
				isNull: function() {
					for ( var key in data ) { return false; }
					return true;
				},
				
				// Get 'start' to ( start + view number - 1 ) number form Json array
				getStartToEnd: function( start, viewNum ) {
					var count = 0, end = start + viewNum, temp = {};
					for ( var key in data ) {
						if ( count >= start && count < end ) {
							temp[ key ] = data[ key ];
						}
						count ++;
					}
					return temp;
				},
				
				// Get Json size
				getSize: function() {
					var count = 0;
					for ( var key in data ) { count ++; }
					return count;
				},
				
				// Get first data form Json
				getFirst: function() {
					for ( var key in data ) { 
						return {
							key: key,
							value: data[ key ]
						}
					};
					return null;
				}
			}
		},
		
		getGradient: function( selector ) {
			return GetGradient( selector );
		}
	};
})();
jpack = jpack.structure;
