/*


Kinetics ajax/dhtml framework funcitons
Copyright® Kinetics Multimedia (www.kinetics.com.br)

*/
function print_r( input, _indent )
{
     // Recuo
     
     var indent            =    ( typeof( _indent ) == 'string' ) ? _indent + '    ' : '    '
     var parent_indent    =    ( typeof( _indent ) == 'string' ) ? _indent : '';
     
     var output            =    '';
     
     // Tipo de Elemento do Array
     
     switch( typeof( input ) )
     {
         case 'string':
             output        =    "'" + input + "'";
         break;
         
         case 'number':
             output        =    input + "";
         break;
                 
         case 'boolean':
             output        =    ( input ? 'true' : 'false' ) + "";
         break;
         
         case 'object':
             output        =    ( ( input.reverse ) ? 'Array ' : 'Object' ) + "";
     
             output       +=    parent_indent + "(";
             
             for( var i in input )
             {
                 output +=    indent + '[' + i + '] => ' + print_r( input[ i ], indent );
             }
             
             output       +=    parent_indent + " )"
         break;
     }
     
     return output;
}
function urlencode( str ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Philip Peterson
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: AJ
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Brett Zamir
    // %          note: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
    // *     example 1: urlencode('Kevin van Zonneveld!');
    // *     returns 1: 'Kevin+van+Zonneveld%21'
    // *     example 2: urlencode('http://kevin.vanzonneveld.net/');
    // *     returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F'
    // *     example 3: urlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a');
    // *     returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a'
                             
    var histogram = {}, tmp_arr = [];
    var ret = str.toString();
    
    var replacer = function(search, replace, str) {
        var tmp_arr = [];
        tmp_arr = str.split(search);
        return tmp_arr.join(replace);
    };
    
    // The histogram is identical to the one in urldecode.
    histogram["'"]   = '%27';
    histogram['(']   = '%28';
    histogram[')']   = '%29';
    histogram['*']   = '%2A';
    histogram['~']   = '%7E';
    histogram['!']   = '%21';
    histogram['%20'] = '+';
    
    // Begin with encodeURIComponent, which most resembles PHP's encoding functions
    ret = encodeURIComponent(ret);
    
    for (search in histogram) {
        replace = histogram[search];
        ret = replacer(search, replace, ret) // Custom replace. No regexing
    }
    
    // Uppercase for full PHP compatibility
    return ret.replace(/(\%([a-z0-9]{2}))/g, function(full, m1, m2) {
        return "%"+m2.toUpperCase();
    });
    
    return ret;
}
function urldecode( str ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Philip Peterson
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: AJ
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Brett Zamir
    // %          note: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
    // *     example 1: urldecode('Kevin+van+Zonneveld%21');
    // *     returns 1: 'Kevin van Zonneveld!'
    // *     example 2: urldecode('http%3A%2F%2Fkevin.vanzonneveld.net%2F');
    // *     returns 2: 'http://kevin.vanzonneveld.net/'
    // *     example 3: urldecode('http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a');
    // *     returns 3: 'http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'
    
    var histogram = {};
    var ret = str.toString();
    
    var replacer = function(search, replace, str) {
        var tmp_arr = [];
        tmp_arr = str.split(search);
        return tmp_arr.join(replace);
    };
    
    // The histogram is identical to the one in urlencode.
    histogram["'"]   = '%27';
    histogram['(']   = '%28';
    histogram[')']   = '%29';
    histogram['*']   = '%2A';
    histogram['~']   = '%7E';
    histogram['!']   = '%21';
    histogram['%20'] = '+';
 
    for (replace in histogram) {
        search = histogram[replace]; // Switch order when decoding
        ret = replacer(search, replace, ret) // Custom replace. No regexing   
    }
    
    // End with decodeURIComponent, which most resembles PHP's encoding functions
    ret = decodeURIComponent(ret);
 
    return ret;
}
function fademessage(str)
{
	debug(str);
}
function warning(str)
{
	alert(str);
}
function is_array( mixed_var ) 
{
    return ( mixed_var instanceof Array );
}
function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}
/**
* Esta função simula a função print_r do PHP
*
*
* @param {Array} input Array ou objeto 
* @param {string} _indent Variável de sistema, usada pala própria função
* @return {String} Uma String que simula a função print_r do PHP
*/
function print_r( input, _indent )
{
     // Recuo
     
     var indent            =    ( typeof( _indent ) == 'string' ) ? _indent + '    ' : '    '
     var parent_indent    =    ( typeof( _indent ) == 'string' ) ? _indent : '';
     
     var output            =    '';
     
     // Tipo de Elemento do Array
     
     switch( typeof( input ) )
     {
         case 'string':
             output        =    "'" + input + "'";
         break;
         
         case 'number':
             output        =    input + "";
         break;
                 
         case 'boolean':
             output        =    ( input ? 'true' : 'false' ) + "";
         break;
         
         case 'object':
             output        =    ( ( input.reverse ) ? 'Array ' : 'Object' ) + "";
     
             output       +=    parent_indent + "(";
             
             for( var i in input )
             {
                 output +=    indent + '[' + i + '] => ' + print_r( input[ i ], indent );
             }
             
             output       +=    parent_indent + " )"
         break;
     }
     
     return output;
}
/**
* Esta função simula a função serialize do PHP
*<br>Retornando dados neste padrão. Facilita a integração Javascript->PHP, já que o PHP consegue receber os dados a partir da função unserialize.
*
*
* @param {Array} a Array ou objeto 
* @return {String} Uma String que simula a função serialize do PHP
*/
function serialize(a)
{
	var serializedString = '';
	var arrayLength = 0;
	for(var aKey in a)
	{
		//key definition
		if(aKey * 1 == aKey) //is_numeric?
		{
			//integer keys look like i:key
			serializedString += 'i:' + aKey + ';';	
		}
		else
		{
			//string keys look like s:key_length:key;
			serializedString += 's:' + aKey.length + ':"' + aKey + '";';
		}
		
		//value definition
		if(a[aKey] * 1 == a[aKey])
		{
			//integer value look like i:value
			serializedString += 'i:' + a[aKey] + ';';	
		}
		else if(typeof(a[aKey]) == "string")
		{
			//string value look like s:key_length:value;
			serializedString += 's:' + a[aKey].length + ':"' + a[aKey] + '";';
		}
		else if(a[aKey] instanceof Array)
		{
			serializedString += serialize(a[aKey]);
		}
		arrayLength++;
	}
	serializedString = 'a:' + arrayLength + ':{' + serializedString + '}';
	
	return serializedString;
}
/**Função que converte um valor do formato monetário para um valor float
*
*
* @param {String} moeda Valor em formato monetário
* @return {float} Valor em Float
*/
function moeda2float(moeda)
{
	moeda = moeda.replace(/\./g,"");
	moeda = moeda.replace(",",".");
	return parseFloat(moeda);
}
/**Função que converte um valor float para um valor em formato monetário
*
*
* @param {float} num Valor em Float
* @return {String} Valor em formato monetário
*/
function float2moeda(num)
{

	x = 0;

	if(num<0) {
	num = Math.abs(num);
	x = 1;
	} if(isNaN(num)) num = "0";
	cents = Math.floor((num*100+0.5)%100);

	num = Math.floor((num*100+0.5)/100).toString();

	if(cents < 10) cents = "0" + cents;
	for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
	num = num.substring(0,num.length-(4*i+3))+','
	+num.substring(num.length-(4*i+3)); ret = num + '.' + cents; if (x == 1) ret = ' - ' + ret;return ret;

}
 
var isdrag=false;
var x,y;
var dobj;

var ie=document.all;
var ff=!ie;

function utf8(wide) {
  var c, s;
  var enc = "";
  var i = 0;
  while(i<wide.length) {
    c= wide.charCodeAt(i++);
    // handle UTF-16 surrogates
    if (c>=0xDC00 && c<0xE000) continue;
    if (c>=0xD800 && c<0xDC00) {
      if (i>=wide.length) continue;
      s= wide.charCodeAt(i++);
      if (s<0xDC00 || c>=0xDE00) continue;
      c= ((c-0xD800)<<10)+(s-0xDC00)+0x10000;
    }
    // output value
    if (c<0x80) enc += String.fromCharCode(c);
    else if (c<0x800) enc += String.fromCharCode(0xC0+(c>>6),0x80+(c&0x3F));
    else if (c<0x10000) enc += String.fromCharCode(0xE0+(c>>12),0x80+(c>>6&0x3F),0x80+(c&0x3F));
    else enc += String.fromCharCode(0xF0+(c>>18),0x80+(c>>12&0x3F),0x80+(c>>6&0x3F),0x80+(c&0x3F));
  }
  return enc;
}


function clearloads()
{
	abort_all_ajax_requests();
	if( ckidle_timer ) clearTimeout( ckidle_timer );
}

// shortname to getElementById
function $( s ) { return document.getElementById( s ); }

// shortname to createElement
function ce( t ) { return document.createElement( t ); }

// void function
function v(){};

// insert node AFTER some dom element
function insertAfter(node, referenceNode)
{
  referenceNode.parentNode.insertBefore(node, referenceNode.nextSibling);
}
function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}
function isfunction(variable)
{
    return (typeof(variable) == "function")?  true: false;
}

function isdefined( variable)
{
    return (typeof(variable) == "undefined")?  false: true;
}

function isobject( variable)
{
    return (typeof(variable) == "object")?  false: true;
}

function isnumber( variable)
{
    return (typeof(variable) == "number")?  false: true;
}

// Returns the value of a string
function val( o )
{
	var vo = o*1;
	return vo+'' == 'NaN' ? 0 : vo;
}

// sprintf
function sprintf()
{
   if (!arguments || arguments.length < 1 || !RegExp)
   {
      return;
   }
   var str = arguments[0];
   var re = /([^%]*)%('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X)(.*)/;
   var a = b = [], numSubstitutions = 0, numMatches = 0;
   while (a = re.exec(str))
   {
      var leftpart = a[1], pPad = a[2], pJustify = a[3], pMinLength = a[4];
      var pPrecision = a[5], pType = a[6], rightPart = a[7];

      numMatches++;
      if (pType == '%')
      {
         subst = '%';
      }
      else
      {
         numSubstitutions++;
         if (numSubstitutions >= arguments.length)
         {
            alert('Error! Not enough function arguments (' + (arguments.length - 1)
               + ', excluding the string)\n'
               + 'for the number of substitution parameters in string ('
               + numSubstitutions + ' so far).');
         }
         var param = arguments[numSubstitutions];
         var pad = '';
                if (pPad && pPad.substr(0,1) == "'") pad = leftpart.substr(1,1);
           else if (pPad) pad = pPad;
         var justifyRight = true;
                if (pJustify && pJustify === "-") justifyRight = false;
         var minLength = -1;
                if (pMinLength) minLength = parseInt(pMinLength);
         var precision = -1;
                if (pPrecision && pType == 'f')
                   precision = parseInt(pPrecision.substring(1));
         var subst = param;
         switch (pType)
         {
         case 'b':
            subst = parseInt(param).toString(2);
            break;
         case 'c':
            subst = String.fromCharCode(parseInt(param));
            break;
         case 'd':
            subst = parseInt(param) ? parseInt(param) : 0;
            break;
         case 'u':
            subst = Math.abs(param);
            break;
         case 'f':
			if( precision > -1 )
			 {
				subst = Math.round(parseFloat(param) * Math.pow(10, precision)) + '';
				if( subst == '0' )	for( var i = 0 ; i < precision ; i++ ) subst += '0'; 
				subst  = subst.substr( 0, subst.length-2 ) + '.' + subst.substr( subst.length-2, 1000 );
			 }
			 else
				 subst = parseFloat(param);
            break;
         case 'o':
            subst = parseInt(param).toString(8);
            break;
         case 's':
            subst = param;
            break;
         case 'x':
            subst = ('' + parseInt(param).toString(16)).toLowerCase();
            break;
         case 'X':
            subst = ('' + parseInt(param).toString(16)).toUpperCase();
            break;
         }
         var padLeft = minLength - subst.toString().length;
         if (padLeft > 0)
         {
            var arrTmp = new Array(padLeft+1);
            var padding = arrTmp.join(pad?pad:" ");
         }
         else
         {
            var padding = "";
         }
      }
      str = leftpart + padding + subst + rightPart;
   }
   return str;
}


// Inspect function will open a new window with all variables/object contained by any object
function inspect_old( dobj )
{
	win = window.open( '', 'inspectwindow' );
	for (var i in dobj)	
	{ 
		var j = eval( 'dobj.' + i );
		win.document.write( i + ', ' + typeof( j )+ ', ' +  j + '<br>' );
//		debug( i, typeof( j ), j );
	}
}


// Inspect function will open a new window with all variables/object contained by any object
var inspectObjList = [];
function inspect( dobj )
{
//	win = window.open( '', 'inspectwindow' );
	debugclose();
	inspectObjList = [];
	for (var i in dobj)	
	{ 
		try
		{
			var j = eval( 'dobj.' + i );
		}
		catch( e )
		{
			try
			{
				var j = eval( 'dobj[' + i + ']' );
			}
			catch( e )
			{
				continue;
			}
		}
		s = j + '';
		s = s.replace( /</g, '&lt;' );
		s = s.replace( />/g, '&gt;' );
		if( typeof( j ) == 'object' )
		{
			var idx = inspectObjList.length;
			inspectObjList.push( j );
			s = '<a href="#" onclick="inspect(inspectObjList[' + idx + '])"><b>' + s + '</b></a>';
		}

//		win.document.write( i + ', ' + typeof( j )+ ', ' +  j + '<br>' );
		debug( i, typeof( j ), s );
	}
}


// write a floating DHTML debug window with variable parameters
function debug()
{
	var i;
	var list = [];

	if( $('log') == null )
	{
		log = ce( 'div' );
		log.id = 'log';
		log.className = 'debug';
		log.innerHTML = '<nobr><b>Debug Window</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="javascript:debugclose()">close</a></nobr>';
		document.body.appendChild( log );
	}

	for( i = 0 ; i < arguments.length ; i++ )
	{
		list[i] = arguments[i];
	}
	$('log').innerHTML += '<br>' + list.join( ', ' );
	$('log').style.zIndex = 1000000;
	$('log').style.top = document.body.scrollTop + 10;
}


// close debug window
function debugclose()
{
	var _log = $('log');
	if( _log == null ) return;
	_log.parentNode.removeChild( _log );
	_log = null;
}

function imgmaxrectcenter( img, width, height )
{
	if( !isdefined( width ) ) return;
	if( !isdefined( height ) ) return;
	if( !isdefined( img.tim ) ) img.tim = 0;
	if( img.tim < 10 && img.width == 0 && img.height== 0 )
	{
		img.tim++;
		setTimeout( function() { imgmaxrectcenter( img, width, height ); }, 1000 );
		return;
	}
	imgmaxrect( img, width, height );
	img.style.position = 'relative';
	img.style.left = Math.floor( (width-img.clientWidth)/2 );
	img.style.top = Math.floor( (height-img.clientHeight)/2 );
}

function imgmaxrect(img, width, height)
{
	if( !isdefined( width ) ) return;
	if( !isdefined( height ) ) return
	if( !isdefined( img.tim ) ) img.tim = 0;
	if( img.tim < 10 && img.width <= 28  && img.height <= 28 )
	{
		
		img.tim++;
		setTimeout( function() { imgmaxrect( img, width, height ); }, 1000 );
		return;
	}
	var r = 1;
	if( !isdefined( img.nheight ) )
	{
		img.nheight = img.height;
		img.nwidth = img.width;
	}
	var w = img.nwidth;
	var h = img.nheight;
	
	if( w == -1 )
	{
		debug( 'reload', img.width );
		setTimeout( function() { imgmaxrect( img, width, height ) }, 1000 );
		return;
	}

	if (width<w || height<h)
	{
		var mh= height/h;
		var mw= width/w;
		if(mh>mw)  r=mw; else  r=mh;
	}

	img.style.width = w = Math.floor( w*r );
	img.style.height = h = Math.floor( h*r );

	img.style.marginLeft = 0;
	img.style.marginTop = 0;
	var o = img.parentNode;
	if( typeof( o ) == 'Object' )
	{
		while( o != document.body && o.parentNode != null && o.onmouseover == null ) o = o.parentNode;
		if( isdefined( o.onmouseover ) ) o.title = img.title;
	}
	img.isloaded = true;
}
function loadurl( url, obj )
{
	obj.innerHTML = '<div class="loading"></div>';
	watch_animate( obj );
	ajaxrequest( url, 'resultform', obj, 0 );
}

// recise and center vert/horiz one image to max
function imgmaxdimmiddle( img, max )
{
	if( !isdefined( max ) ) return;
	if( !isdefined( img.tim ) ) img.tim = 0;
	if( img.tim < 10 && img.width == 0 )
	{
		img.tim++;
		setTimeout( function() { imgmaxdimmiddle( img, max ); }, 1000 );
		return;
	}
	imgmaxdim( img, max );
	img.style.position = 'relative';
	img.style.left = Math.floor( (max-img.clientWidth)/2 );
}

// recise and center horiz one image to max
function imgmaxdimcenter( img, max )
{
	if( !isdefined( max ) ) return;
	if( !isdefined( img.tim ) ) img.tim = 0;
	if( img.tim < 10 && img.width == 0 )
	{
		img.tim++;
		setTimeout( function() { imgmaxdimcenter( img, max ); }, 1000 );
		return;
	}
	imgmaxdim( img, max );
	img.style.position = 'relative';
	img.style.left = Math.floor( (max-img.clientWidth)/2 );
	img.style.top = Math.floor( (max-img.clientHeight)/2 );
}

var imgdebug = false;
// recise one image to max
function imgmaxdim(img, max)
{
	if( !isdefined( max ) ) return;
	if( !isdefined( img.tim ) ) img.tim = 0;
	if( img.tim < 10 && img.width <= 28 )
	{
		img.tim++;
		setTimeout( function() { imgmaxdim( img, max ); }, 1000 );
		return;
	}
	var r = 1;
	if( !isdefined( img.nheight ) )
	{
		img.nheight = img.height;
		img.nwidth = img.width;
	}
	var w = img.nwidth;
	var h = img.nheight;
	if( w == -1 )
	{
		debug( 'reload', img.width );
		setTimeout( function() { imgmaxdim( img, max ) }, 1000 );
		return;
	}
	var w = img.nwidth;
	var h = img.nheight;
	var m = w > h ? w : h;
	if( m > max ) r = max/m;

	img.style.width = w = Math.floor( w*r );
	img.style.height = h = Math.floor( h*r );

	img.style.marginLeft = 0;
	img.style.marginTop = 0;
	var o = img.parentNode;
	if( typeof( o ) == 'Object' )
	{
		while( o != document.body && o.parentNode != null && o.onmouseover == null ) o = o.parentNode;
		if( isdefined( o.onmouseover ) ) o.title = img.title;
	}
	img.isloaded = true;
}

// frame a image to fit in a square with 'min' pixels
function imgsquare( img, min )
{
	if( !isdefined( min ) ) return;
	if( !isdefined( img.tim ) ) img.tim = 0;
	if( img.tim < 10 && img.width <= 28 && img.height <= 28 )
	{
		img.tim++;
		setTimeout( function() { imgsquare( img, min ); }, 1000 );
		return;
	}
	var r = 1;
	if( !isdefined( img.nheight ) )
	{
		img.nheight = img.height;
		img.nwidth = img.width;
	}
	var w = img.nwidth;
	var h = img.nheight;
	var m = w < h ? w : h;
	if( m > min ) r = min/m;

	img.style.width = w = Math.floor( w*r );
	img.style.height = h = Math.floor( h*r );


	var left;
	var top;
	if( w > min )
	{
		left = -Math.floor( (w - min)/2 );
		top = Math.floor( (min - h)/2 ); 
	}
	else if( h > min )
	{
		top = -Math.floor( (h - min)/2 );
		left = Math.floor( (min - w)/2 ); 
	}
	else
	{
		top = Math.floor( (min - h)/2 ); 
		left = Math.floor( (min - w)/2 ); 
	}
	img.style.marginLeft = left;
	img.style.marginTop = top;
//	debug( '<img style="border: 1px solid black" src="' + img.src + '">', img.clientWidth, img.clientHeight, img.style.left, img.style.top );
	var o = img.parentNode;

	if( typeof( o ) == 'Object' )
	{
		while( o != document.body && o.parentNode != null && o.onmouseover == null ) o = o.parentNode;
		if( isdefined( o.onmouseover ) ) o.title = img.title;
	}
	img.isloaded = true;
}



// adds a random parameter to a URL to avoid AJAX caching
function nocache( url )
{
	var ret;
	if( url.indexOf('?') > 0 )
		ret = url + '&rpar=' + Math.random();
	else
		ret = url + '?rpar=' + Math.random();
	return ret;
}

// get obj top position on document
function getTop(obj)
{
	var top = obj.offsetTop;
	while((obj = obj.offsetParent) != null && typeof( obj ) == 'object' && obj.tagName!='BODY')
	{
		top += obj.offsetTop - obj.scrollTop;
	}
	return top;
}



// get obj left position on document
function getLeft(obj)
{
	var left = obj.offsetLeft;
	while((obj = obj.offsetParent) != null && typeof( obj ) == 'object' && obj.tagName!='BODY')
		left += obj.offsetLeft - obj.scrollLeft;
	return left;
}

// make an AJAX request and cancel any other unfinished previous AJAX request
var uniqueajaxreq = -1;
function uniqueajax(url, callback_function, callback_param, return_xml )
{
	if( uniqueajaxreq >= 0 ) 
	{
		var uar = ajaxrequests[uniqueajaxreq];
		var ucancel = ajaxcancels[uniqueajaxreq];
		
		if( uar.readyState != 4 )
		{
			if( !ie ) uar.aborted = true;
			uar.abort();
			if( isdefined( ucancel ) ) ucancel();
			if( ckidle_timer ) clearTimeout( ckidle_timer );
//			debug( 'abort ajax', uniqueajaxreq.cancelfunc );
		}
	}
	uniqueajaxreq = ajaxrequest(url, callback_function, callback_param, return_xml );
	return uniqueajaxreq;
}

// set the 
function selectset( o, v )
{
	for( i = 0 ; i < o.options.length ; i++ )
	{
		if( o.options[i].text == v || o.options[i].value == v ) 
		{
			o.selectedIndex = i;
			return;
		}
	}
}



// bubble functions
var bubble_zidx = 1000;
var bubblecnt = 0;

function bubbleins( obj, ident )
{
	var dv = ce( 'DIV' );
	dv.className = ident;
	obj.appendChild( dv );
	return dv;
}

function bubblelize( obj, arrow, opacity )
{
	if( obj.done ) return;
	var width = obj.clientWidth;
	var height = obj.clientHeight;

	if( height < 30 ) obj.style.height = height = 30;
	var x = obj.left;
	var y = obj.top;
	var sx = x + '';
	var sy = y + '';
	if( sx.match( /%/ ) || sy.match( /%/ ) )
	{
		x = obj.offsetLeft;
		y = obj.offsetTop;
	}
	if( isdefined( obj.bubble ) && obj.bubble != null )
	{
		obj.bubble.parentNode.removeChild( obj.bubble );
		obj.bubble = null;
	}
	var bubble = ce( 'DIV' );
	bubble.className = 'bubble';
	bubble.style.top = -1000;
	bubble.style.left = -1000;
	obj.parentNode.appendChild( bubble );
	var ne = bubbleins( bubble, 'NE' );
	var nw = bubbleins( bubble, 'NW' );
	var se = bubbleins( bubble, 'SE' );
	var sw = bubbleins( bubble, 'SW' );
	var s = bubbleins( bubble, 'S' );
	var n = bubbleins( bubble, 'N' );
	var w = bubbleins( bubble, 'W' );
	var e = bubbleins( bubble, 'E' );
	var bg = bubbleins( bubble, 'bg' );
	var arr = bubbleins( bubble, 'pt' + arrow );
	if( isdefined( opacity ) )
	{
		var tmp = [ ne, nw, se, sw, s, n, w, e, bg, arr ];
		for( var i = 0 ; i < tmp.length ; i++ )
		{
			tmp[i].style.opacity=opacity;
			tmp[i].style.filter = 'alpha(opacity=' + opacity*100 + ')';
		}
	}

	var dw = e.clientWidth + w.clientWidth;
	var dh = n.clientHeight + s.clientHeight;

	bg.style.width = width;
	bg.style.height = height;
	bg.style.top = n.clientHeight;
	bg.style.left  = w.clientWidth;
	e.style.top = ne.clientHeight;

	var vh = height + dh - ne.clientHeight - se.clientHeight;
	if( vh <= 0 )
	{
		e.style.display = w.style.display = 'none';
	}
	e.style.height = vh;
	w.style.top = nw.clientHeight;
	w.style.height = vh;
	n.style.left = nw.clientWidth;
	n.style.width = width;
	s.style.left = sw.clientWidth;
	s.style.width = width;


	arrw = arrow.match( /W/ ) ? 8 : -8;
	var t, l;
	if( arrow == ''  )
	{
		arrw = 0;
		toleft = 0;
		tosouth = 0;
		t = bubble.style.top = y - n.clientHeight;
		l = bubble.style.left = x - w.clientWidth;
		bubble.style.width = width + dw;
		bubble.style.height = height + dh;
	}
	else
	{
		toleft = arrow.match( /E/ ) ? -(width + dw) : 0;
		tosouth = arrow.match( /S/ ) ? -(height + dh) : 0;
		obj.style.top = y + n.clientHeight + tosouth;
		obj.style.left = x + w.clientWidth + arrw + toleft;
		t = bubble.style.top = y - n.clientHeight + tosouth;
		l = bubble.style.left = x + arrw + toleft;
		bubble.style.width = width + dw;
		bubble.style.height = height + dh;
		var cornerdel = arrow.toLowerCase() + '.style.display=\'none\'';
		eval( cornerdel );
	}
	if( obj.bgdiv != null ) obj.bgdiv.style.zIndex = bubble_zidx++;
	bubble.style.zIndex = bubble_zidx++;

	if( isdefined( obj.shadow ) && obj.shadow != null )
	{
		obj.shadow.parentNode.removeChild( obj.shadow );
		obj.shadow = null;
	}
	var shadow = ce( 'DIV' );
	var w = bubble.clientWidth + 10;
	var h = bubble.clientHeight + 10;
	shadow.style.position = 'absolute';
	shadow.style.width = w;
	shadow.style.height = h;
	shadow.style.top = t-4;
	shadow.style.left = l-4;
	shadow.style.background = 'transparent';

	function sh_element( ident, top, left, width, height )
	{
		if( width <= 0 || height <= 0 ) return;
		var el = ce( 'DIV' );
		el.style.position = 'absolute';
		el.style.top = top;
		el.style.left = left;
		el.style.width = width;
		el.style.height = height;
		shadow.appendChild( el );
		if( ie )
		{
			el.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod='scale', src='/kintool/css/" + ident + ".png')";
		}
		else
		{
			el.style.background = 'transparent';
			el.style.backgroundImage = 'url( /kintool/css/' + ident + '.png )';
		}
	}
	sh_element( 'sh_topleft', 0, 0, 26, 26 );
	sh_element( 'sh_topright', 0, w-26, 26, 26 );
	sh_element( 'sh_top', 0, 26, w-26*2, 26 );
	sh_element( 'sh_left', 26, 0, 26, h-26*2 );
	sh_element( 'sh_right', 26, w-26, 26, h-26*2 );
	sh_element( 'sh_botleft', h-26, 0, 26, 26 );
	sh_element( 'sh_botright', h-26, w-26, 26, 26 );
	sh_element( 'sh_bot', h-26, 26, w-26*2, 26 );

	bubble.style.zIndex = bubble_zidx++;
	obj.shadow = shadow;

	obj.parentNode.appendChild( shadow );



	obj.style.zIndex = bubble_zidx++;
	obj.bubble = bubble;
}

var bubblelist = [];

function bubbleoutcheck( ev )
{
	if( ie ) ev = event;
	var target = ie ? ev.srcElement : ev.target;
	var inbubble = upDom( target, 'bubbleobj' ) != null;
	//alert( isbubble );
	if( !inbubble )
	{
		nobubble();
		document.body.onmousedown = null;
	}
	return true;
}

function sbubble( str, top, left, maxwidth, opacity, forcearr )
{
	var bcontent = ce('div');
	bcontent.className = 'bubblecontent';
	document.body.appendChild( bcontent );
	bcontent.maxwidth = maxwidth;
	bcontent.opacity = opacity;
	bcontent.forcearr = forcearr;
	bcontent.style.top = -1000;
	bcontent.style.left = -1000;
	bcontent.innerHTML = str;
	bcontent.top = top;
	bcontent.left = left;
	bcontent.bgdiv = null;
	var tmpwid = bcontent.clientWidth*1;
	if( tmpwid & 1 ) bcontent.style.width = tmpwid + 1;
	if( bcontent.clientWidth > maxwidth ) bcontent.style.width = maxwidth;
	if( ie )
	{
		var tmpheight = bcontent.clientHeight*1;
		if( tmpheight & 1 ) bcontent.style.height = tmpheight + 1;
	}
	var arr = top > bcontent.clientHeight + 20 ? 'S' : 'N';
	arr += left > 300 ? 'E' : 'W';
	if( isdefined( forcearr ) ) arr = forcearr;
	bubblelize( bcontent, arr, opacity );
	bcontent.id = 'bubble_' + bubblecnt;
	bcontent.bcount = bubblecnt++;
	bcontent.initop = top;
	bcontent.inileft = left;
	bubblelist.push( bcontent );
	bcontent.bubbleobj = bcontent;
	return bcontent;
}

function abubble( url, top, left, width, opacity, forcearr )
{
	nobubble();
	var bcontent = sbubble( '<div class="loading">&nbsp;&nbsp;Loading...</div>', top, left, width, opacity, forcearr );
	watch_animate( bcontent );
	bcontent.onchange = function() { bubbleresize( this ) };
	if( url != '' ) ajaxrequest( url, 'bubbleresult', bcontent, 0 );
	return bcontent;
}

function bubbleresize( obj )
{
	var maxwidth = obj.maxwidth;
	var opacity = obj.opacity;
	var forcearr = obj.forcearr;
	var top = obj.initop;
	var left = obj.inileft;
	var bcontent = obj;
	bcontent.style.height = '';
	bcontent.style.top = -1000;
	bcontent.style.left = -1000;
	if( bcontent.clientWidth > maxwidth ) bcontent.style.width = maxwidth;
	if( ie )
	{
		var tmpheight = bcontent.clientHeight*1;
		if( tmpheight & 1 ) bcontent.style.height = tmpheight + 1;
	}
	bcontent.style.top = top;
	bcontent.style.left = left;
	var arr = top > bcontent.clientHeight + 20 ? 'S' : 'N';
	arr += left > 300 ? 'E' : 'W';
	if( isdefined( forcearr ) ) arr = forcearr;
	bubblelize( obj, arr, opacity );
}

function bubbleresult( txt, obj )
{
	resultform( txt, obj );
//	bubbleresize( obj );
}

function bubbleout( obj )
{
	if( !isdefined( obj ) ) return;
	if( isdefined( obj.gbdiv ) ) document.body.removeChild( obj.bgdiv );
	document.body.removeChild( obj.shadow );
	document.body.removeChild( obj.bubble );
	document.body.removeChild( obj );
	obj.done = true;
	for( var i = 0 ; i < bubblelist.length ; i++ )
		if( bubblelist[i] == obj )
			delete( bubblelist[i] );
}

function nobubble()
{
	try
	{
		closeCalendar();
	}
	catch ( ev )
	{
	}
	var bub;
	while( isdefined( bub = bubblelist.pop() ) )
		bubbleout( bub );
}


function watch_animate( obj, num )
{
	if( typeof( obj.offsetParent ) == 'unknown' || obj.offsetParent == null )
		return;
	if( !isdefined( num ) ) num = 1;
	if( num > 6 ) num = 1;
	if( obj.className != 'loading' && obj.className != 'loading_button' )
	{
		var olist = obj.getElementsByTagName("DIV");
		var i;
		for( i = 0 ; i < olist.length ; i++ )
		{
			if( olist[i].className == 'loading' )
			{
				obj = olist[i];
				break;
			}
		}
	}
	if( ie )
	{
		if( !isdefined( obj.iebg ) )
		{
			var top = parseInt(obj.currentStyle.backgroundPositionY);
			var left = parseInt(obj.currentStyle.backgroundPositionX);
			obj.style.backgroundImage = 'none';
			obj.style.background = 'transparent';
			var loaddiv = ce( 'DIV' );
			loaddiv.iebg = true;
			loaddiv.style.position = 'absolute';
			loaddiv.style.top = top;
			loaddiv.style.left = left;
			loaddiv.style.width = 20;
			loaddiv.style.height = 20;
			obj.appendChild( loaddiv );
			if( obj.currentStyle.position == 'static') obj.style.position = 'relative';
			obj = loaddiv;
		}
		obj.style.filter = 	"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod='crop', src='/kintool/css/watch000" + num + ".png')";
	}
	else
	{
		obj.style.backgroundImage = 'url( /kintool/css/watch000' + num + '.png )';
	}
	setTimeout( function() { watch_animate( obj, num+1 ) }, 100 );
}



function plural( v, sing, plr )
{
	if( isdefined( sing ) )
		return v == 1 ? sing : plr;
	else
		return v == 1 ? '' : 's';
}

function bodycenter( val )
{
	if(!isdefined(val))
		val=1024;

	var cw = document.body.clientWidth;
	var mrg = Math.floor((cw - val)/2);
	if( mrg < 0 ) mrg = 0;
	document.body.style.marginLeft = mrg;
	document.body.mrg = mrg;
	//document.body.style.paddingBottom = 80;
//	if( ie )
//		document.body.style.height = document.body.clientHeight;
//	else
//		document.body.style.minHeight = document.body.clientHeight;
//		document.body.style.height = document.body.clientHeight;
	if( !isdefined( window.onresize ) || window.onresize == null ) window.onresize = function() { bodycenter() };
}


function execcommand( url )
{
	ajaxrequest( url, formresult, $('command'), 1, 'POST', '' );
}

function logout()
{
	execcommand( 'services/Account/logout' );
}


// returns a file link from the file array returned by service
// if empty or not found, return the noimage.gif
function getfilepath( arr, ident, thumb )
{
	var suffix = '';
	if( thumb ) suffix = 'th';
	for( var i = 0 ; i < arr.length ; i++ )
	{
		if( arr[i][1] == ident )
			return 'services/service.php?$serviceName=Items&$operation=file&id=' + arr[i][0] + '&suffix=' + suffix;
	}
	return 'kintool/' + csspath + '/noimage.gif';
}

function addclass( o, cls )
{
	var cn = o.className + ' ';
	cn += cls;
	o.className = cn;
}


function removeclass( o, cls )
{
	var cn = o.className + '';
	cn = eval( 'cn.replace( / ' + cls + '/g, \'\' )' );
	o.className = cn;
}

// image preload functions
// add images to a preload queue. This will preload gradualy the new images

var preloadimg_queue = [];
var preloadimg_queued = [];
var preloadimgs = [];

function preloadimg( url )
{
	var first = preloadimg_queue.length == 0;
	if( !preloadimg_queued[url] )
	{
		preloadimg_queued[url] = true;
		preloadimg_queue.push( url );
	}
	if( first ) preloadimg_next();
}

function preloadimg_next()
{
	if( preloadimg_queue.length == 0 ) return;
	var url = preloadimg_queue.shift();
	var img = new Image;
	preloadimgs.push( img );
	img.onload = function() { preloadimg_next() };
	img.src = url;
}

function modal( onoff, func, param )
{
	if( onoff )
	{
		var div = ce( 'DIV' );
		div.className = 'modal';
		div.id = 'modaldiv';
		document.body.appendChild( div );
		var cw = document.body.clientWidth;
		var ch = document.body.scrollHeight;
		div.style.width = cw;
		div.style.height = ch;
		if( !ie ) div.style.left = -document.body.mrg;
		if( isdefined( func ) )
		{
			div.onclick = function() { func( param ) };
		}
	}
	else
	{
		var div = $('modaldiv');
		if( div != null )
			document.body.removeChild( div );
	}
}


function logoclick( ev )
{
	if( ie ) ev = event;

	if( ev.ctrlKey && ev.shiftKey )
	{
		ajaxdebug = !ajaxdebug;
		debug( 'Ajaxdebug', ajaxdebug );
		savevar( 'ajaxdebug', ajaxdebug );
	}
	else
		document.location = 'index.php';
}


var lastSavedName, lastSavedVal;
function savevar( name, val, permanent )
{
	if( name == lastSavedName && val == lastSavedVal ) return;

	lastSavedName = name;
	lastSavedVal = val;

	if( !isdefined( permanent ) ) permanent = '';
	ajaxrequest('savevar.php?name=' + name + '&val=' + val + '&permanent=' + permanent, null, null, 0 );
	var ev = '';
	if( typeof( val ) == 'number' || typeof( val ) == 'boolean' )
		ev = name + '= ' + val + ';';
	else
	{
		val = val.replace( /"/g, '\\"' );
		ev = name + ' = "' + val + '";';
	}
	eval( ev );
}

function browserCSS()
{
	var nav = navigator.userAgent.toLowerCase();
	var browsertype = [ 'chrome', 'firefox', 'msie', 'safari' ];
	var browser = [];
	for( var i = 0 ; i < browsertype.length ; i++ )
		if( nav.indexOf( browsertype[i] ) >= 0 ) browser.push( browsertype[i] );

	html = document.getElementsByTagName('html')[0];
	var bclass = browser.join( ' ' );
	if( bclass.indexOf( 'chrome' ) >= 0 ) bclass = bclass.replace( /safari/, '' );
	if( bclass.indexOf( 'msie' ) >= 0 ) 
		bclass = bclass.replace( /msie/, 'ie' );
	else
		bclass += ' not_ie';
	html.className = bclass;
}

browserCSS();

var flash = new function()
{
    var self = this;
    self.installed = false;
    self.raw = "";
    self.major = -1;
    self.minor = -1;
    self.revision = -1;
    self.revisionStr = "";
    var activeXDetectRules = [
        {
            "name":"ShockwaveFlash.ShockwaveFlash.7",
            "version":function(obj){
                return getActiveXVersion(obj);
            }
        },
        {
            "name":"ShockwaveFlash.ShockwaveFlash.6",
            "version":function(obj){
                var version = "6,0,21";
                try{
                    obj.AllowScriptAccess = "always";
                    version = getActiveXVersion(obj);
                }catch(err){}
                return version;
            }
        },
        {
            "name":"ShockwaveFlash.ShockwaveFlash",
            "version":function(obj){
                return getActiveXVersion(obj);
            }
        }
    ];
    /**
     * Extract the ActiveX version of the plugin.
     * 
     * @param {Object} The flash ActiveX object.
     * @type String
     */
    var getActiveXVersion = function(activeXObj){
        var version = -1;
        try{
            version = activeXObj.GetVariable("$version");
        }catch(err){}
        return version;
    };
    /**
     * Try and retrieve an ActiveX object having a specified name.
     * 
     * @param {String} name The ActiveX object name lookup.
     * @return One of ActiveX object or a simple object having an attribute of activeXError with a value of true.
     * @type Object
     */
    var getActiveXObject = function(name){
        var obj = -1;
        try{
            obj = new ActiveXObject(name);
        }catch(err){
            obj = {activeXError:true};
        }
        return obj;
    };
    /**
     * Parse an ActiveX $version string into an object.
     * 
     * @param {String} str The ActiveX Object GetVariable($version) return value. 
     * @return An object having raw, major, minor, revision and revisionStr attributes.
     * @type Object
     */
    var parseActiveXVersion = function(str){
        var versionArray = str.split(",");//replace with regex
        return {
            "raw":str,
            "major":parseInt(versionArray[0].split(" ")[1], 10),
            "minor":parseInt(versionArray[1], 10),
            "revision":parseInt(versionArray[2], 10),
            "revisionStr":versionArray[2]
        };
    };
    /**
     * Parse a standard enabledPlugin.description into an object.
     * 
     * @param {String} str The enabledPlugin.description value.
     * @return An object having raw, major, minor, revision and revisionStr attributes.
     * @type Object
     */
    var parseStandardVersion = function(str){
        var descParts = str.split(/ +/);
        var majorMinor = descParts[2].split(/\./);
        var revisionStr = descParts[3];
        return {
            "raw":str,
            "major":parseInt(majorMinor[0], 10),
            "minor":parseInt(majorMinor[1], 10), 
            "revisionStr":revisionStr,
            "revision":parseRevisionStrToInt(revisionStr)
        };
    };
    /**
     * Parse the plugin revision string into an integer.
     * 
     * @param {String} The revision in string format.
     * @type Number
     */
    var parseRevisionStrToInt = function(str){
        return parseInt(str.replace(/[a-zA-Z]/g, ""), 10) || self.revision;
    };
    /**
     * Is the major version greater than or equal to a specified version.
     * 
     * @param {Number} version The minimum required major version.
     * @type Boolean
     */
    self.majorAtLeast = function(version){
        return self.major >= version;
    };
    /**
     * Is the minor version greater than or equal to a specified version.
     * 
     * @param {Number} version The minimum required minor version.
     * @type Boolean
     */
    self.minorAtLeast = function(version){
        return self.minor >= version;
    };
    /**
     * Is the revision version greater than or equal to a specified version.
     * 
     * @param {Number} version The minimum required revision version.
     * @type Boolean
     */
    self.revisionAtLeast = function(version){
        return self.revision >= version;
    };
    /**
     * Is the version greater than or equal to a specified major, minor and revision.
     * 
     * @param {Number} major The minimum required major version.
     * @param {Number} (Optional) minor The minimum required minor version.
     * @param {Number} (Optional) revision The minimum required revision version.
     * @type Boolean
     */
    self.versionAtLeast = function(major){
        var properties = [self.major, self.minor, self.revision];
        var len = Math.min(properties.length, arguments.length);
        for(i=0; i<len; i++){
            if(properties[i]>=arguments[i]){
                if(i+1<len && properties[i]==arguments[i]){
                    continue;
                }else{
                    return true;
                }
            }else{
                return false;
            }
        }
    };
    /**
     * Constructor, sets raw, major, minor, revisionStr, revision and installed public properties.
     */
    self.flash = function(){
        if(navigator.plugins && navigator.plugins.length>0){
            var type = 'application/x-shockwave-flash';
            var mimeTypes = navigator.mimeTypes;
            if(mimeTypes && mimeTypes[type] && mimeTypes[type].enabledPlugin && mimeTypes[type].enabledPlugin.description){
                var version = mimeTypes[type].enabledPlugin.description;
                var versionObj = parseStandardVersion(version);
                self.raw = versionObj.raw;
                self.major = versionObj.major;
                self.minor = versionObj.minor; 
                self.revisionStr = versionObj.revisionStr;
                self.revision = versionObj.revision;
                self.installed = true;
            }
        }else if(navigator.appVersion.indexOf("Mac")==-1 && window.execScript){
            var version = -1;
            for(var i=0; i<activeXDetectRules.length && version==-1; i++){
                var obj = getActiveXObject(activeXDetectRules[i].name);
                if(!obj.activeXError){
                    self.installed = true;
                    version = activeXDetectRules[i].version(obj);
                    if(version!=-1){
                        var versionObj = parseActiveXVersion(version);
                        self.raw = versionObj.raw;
                        self.major = versionObj.major;
                        self.minor = versionObj.minor; 
                        self.revision = versionObj.revision;
                        self.revisionStr = versionObj.revisionStr;
                    }
                }
            }
        }
    }();
};
