/***********************************************************************
 * @filename            : inc/j/common.js
 * @author              : Ken Wang
 * @description         : javascript
 * @created             : 2005-11-22
 * @modified            : 2006-11-10
 * @requires            : none
 ***********************************************************************/

/***** Detect Browser Capabilities *****/
var isDom = (document.getElementById) ? true:false;

/***** Generic Functions *****/
/* string manipulation */
function trim( String ) 
{
    if ( String == null ) { return (false); }
    return String.replace( /(^\s+)|(\s+$)/g,"" );
}
function nl2br( String, max_consec_br )
{
    if ( String == null ) { return (false); }
    String = String.replace( /\n/g,"<br />" );
    if( typeof max_consec_br == 'number' ) 
    {
        switch( max_consec_br )
        {
            case 1: String = String.replace( /(<br \/>){2,}/g, "<br />" ); break;
            default:
            case 2: String = String.replace( /(<br \/>){3,}/g, "<br /><br />" ); break;
        }
    }
    return String;
}

function myHSC( String )
{
    if ( String == null ) return (false);
    //var search = [ '&','<','>','"' ]; var replace = [ '&amp;', '&lt;', '&gt;', '&quot;' ];
    return String.replace( /&/g,"&amp;" ).replace( /</g,"&lt;" ).replace( />/g,"&gt;" ).replace( /"/g,"&quot;" );
}

// public mixed
function runExpr( str_expr )
{
    if( typeof str_expr != 'string' ) return;
    //alert( 'runExpr('+ str_expr +')' );
    if(str_expr.length > 3)
    { eval( str_expr ); }
}

var STR_PAD_LEFT = 0;
var STR_PAD_RIGHT = 1;
function strPad( s_input, i_pad_length, s_pad_string, i_pad_type )
{
    var s_input = new String( s_input );
    if( typeof s_pad_string != 'string' || s_pad_string == '' )
    { s_pad_string = ' '; } // default pad string
    while( s_input.length < i_pad_length )
    { s_input = (i_pad_type==STR_PAD_LEFT?s_pad_string:'')+s_input+(i_pad_type==STR_PAD_RIGHT?s_pad_string:''); }
    return s_input;
}

function myParseInt( String )
{
    if ( String == null )
    { return (false); }
    return parseInt( String.replace( /^0+/,"" ), 10 );
}

function inArray( needle, haystack )
{
    for( var i=0; i<haystack.length; i++ )
    { if( needle == haystack[i] ) return true; }
    return false;
}

function strReplace( search_arg, replace_arg, str )
{
    if(typeof search_arg == 'string')
    { str = str.replace( new RegExp(search_arg,'gi'), replace_arg ); }
    else
    {
        for( var i=0; i<search_arg.length; i++ )
        { str = strReplace( search_arg[i], replace_arg[i], str ); }
    }
    return str;
}

/***** Populate GET Vars *****/
var cgi = new Object();
    cgi.http_host = location.host.toLowerCase();
    cgi.http_user_agent = navigator.userAgent;
    cgi.http_cookie = document.cookie;
    cgi.https = (location.protocol == 'https:\/\/') ? 'on' : 'off';
    cgi.path_info = (location.pathname.indexOf('?') != -1) ? location.pathname.substring(0, location.pathname.indexOf('?')) : location.pathname;
    cgi.query_string = (location.search) ? ((location.search.indexOf('#') != -1) ? location.search.substring(1, location.search.indexOf('#')) : location.search.substring(1)) : '';
    cgi.script_name = cgi.path_info;
    cgi.http_referer = document.referrer;

function parseGETVars()
{
    var qs = cgi.query_string;
    var nv = qs.split('&');
    var url = new Object();
    for(i = 0; i < nv.length; i++) 
    {
        eq = nv[i].indexOf('=');
        url[nv[i].substring(0,eq).toLowerCase()] = decodeURIComponent(nv[i].substring(eq + 1));
    }
    return url;
}
var GET = parseGETVars();


/***** XML HTTP Requests (AJAX) *****/
var XHR = {
    cons:{
        target:'xhr.php'
    },
    vars:{
    },
    requester:null,
    
    // public boolean : initialises XML-HTTP-Request
    init:function(){
        try {
            XHR.requester = new XMLHttpRequest(); 
        }
        catch( error ){
            try{
                XHR.requester = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch( error ){
                return false;
            }
        }
        return true;
    }, // end init
    
    // public void : stop running connections
    halt:function(){
        if( XHR.requester != null &&
            XHR.requester.readyState != 0 &&
            XHR.requester.readyState != 4 )
        { XHR.requester.abort(); }
    }   // end halt
    
};  // end XHR


/***** Init Constants *****/
var ipavo = {
    constants:{
        site_ipavo:'',
        site_blog:'',
        site_space:'',
        cookie_domain:'',
        cookie_path:'/'
    },
    vars:{
        mbrLoggedIn:false,
        mbrAcc:'',
        mbrStatusChkTime:false,
        checkOnLoad:true,
        reloadOnLogin:false
    },
    // poublic boolean
    IsMbrLoggedIn:function(){
        return ( ipavo.vars.mbrLoggedIn === true && ipavo.vars.mbrAcc!='' )?true:false;
    },
    InitMbrStatus:function( acc ){
    	ipavo.vars.mbrAcc=acc; ipavo.vars.mbrLoggedIn=true;
    },
    // public void
    ChkMbrLoginStatus:function( expr2run ){
    	if( ipavo.IsMbrLoggedIn() ) { ipavo.TryLogin(); return; }
        if( !ipavo.vars.checkOnLoad ) { return; } // not logged in and there's no need to check
        XHR.halt(); XHR.init();
        XHR.requester.onreadystatechange = function() {
            if( XHR.requester.readyState == 4) {
                var responseNode = XHR.requester.responseXML.getElementsByTagName("response")[0];
                if( !responseNode ) { runExpr( expr2run ); return; }
                ipavo.vars.mbrLoggedIn = ( typeof responseNode.getAttribute('loggedIn') != 'undefined' && responseNode.getAttribute('loggedIn')=='1' ) ? true : false;
                ipavo.vars.mbrAcc = ( ipavo.vars.mbrLoggedIn == true && typeof responseNode.getAttribute('mbrAcc') == 'string' ) ? responseNode.getAttribute('mbrAcc') : '';
                ipavo.vars.mbrStatusChkTime = new Date();
                runExpr( expr2run ); return;
            }
        }
        XHR.requester.open( "GET", '/login.swf.php?mode=status' );
        XHR.requester.send(null);
    },
    // public void
    DoMbrLogin:function( account, passwd, expr2run ){
        XHR.halt(); XHR.init();
        XHR.requester.onreadystatechange = function() {
            if( XHR.requester.readyState == 4) {
                var responseNode = XHR.requester.responseXML.getElementsByTagName("response")[0];
                if( !responseNode || responseNode.getAttribute("result")=="0" ) 
                { runExpr( expr2run ); return; }
                ipavo.vars.mbrLoggedIn = ( typeof responseNode.getAttribute('loggedIn') != 'undefined' && responseNode.getAttribute('loggedIn')=='1' ) ? true : false;
                ipavo.vars.mbrAcc = ( ipavo.vars.mbrLoggedIn == true && typeof responseNode.getAttribute('mbrAcc') == 'string' ) ? responseNode.getAttribute('mbrAcc') : '';
                ipavo.vars.mbrStatusChkTime = new Date();
                runExpr( expr2run ); return;
            }
        }
        XHR.requester.open( "POST", '/login.swf.php' );
        XHR.requester.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
        XHR.requester.send("mode=login&account="+encodeURIComponent(account)+"&password="+encodeURIComponent(passwd) );
    },
    // public boolean
    ChkLoginForm:function( formObj ){
        var errors = [];
        if( !Validator.checkString( formObj.account.value, 2, 24 ) )
        { errors[errors.length] = __('Lgn_Field_Account'); }
        if( !Validator.checkString( formObj.password.value, 2, 24 ) )
        { errors[errors.length] = __('Lgn_Field_Password'); }
        if( errors.length > 0 )
        { alert( __('FrmGeneric_FixTheFollowing')+"\n\n- "+errors.join("\n- ") ); return false; }
        formObj.loginGo.disabled = true;
        ipavo.DoMbrLogin( formObj.account.value, formObj.password.value, "ipavo.TryLogin(true)" );
        return false;
    },
    // public void
    TryLogin:function(loginAttempt){
        if( !ipavo.IsMbrLoggedIn() )
        { 
            if( loginAttempt == true ) 
            { 
                alert( __('Lgn_InvalidAccountAndOrPassword') );
                if(document.forms['mbrLoginForm']) document.forms['mbrLoginForm'].loginGo.disabled=false;
            }
            return;
        }
        if( loginAttempt == true && ipavo.vars.reloadOnLogin === true )
        { window.location.reload(true); return; }
        if( document.getElementById('mbr-toolbar-in') )
        { document.getElementById('mbr-toolbar-in').style.display = 'block'; }
        if( document.getElementById('mbr-toolbar-out') )
        {
            Animator.fader.init( 'mbr-toolbar-out', 100, 0, 20, 30, "document.getElementById('mbr-toolbar-out').style.left='-1024px'; document.getElementById('mbr-toolbar-out').style.top='1px';document.forms['mbrLoginForm'].account.value=document.forms['mbrLoginForm'].password.value='';" );
            Animator.fader.fadeOut();
        }
    }
};
switch( cgi.http_host )
{
    case 'www.ipavo.com': case 'media.ipavo.com': case 'space.ipavo.com':
        ipavo.constants.site_ipavo = 'http://www.ipavo.com';
        ipavo.constants.site_blog  = 'http://media.ipavo.com';
        ipavo.constants.site_space = 'http://space.ipavo.com';
        ipavo.constants.cookie_domain = '.ipavo.com';
        break;
    case 'www.ipavo.tw': case 'media.ipavo.tw': case 'space.ipavo.tw':
        ipavo.constants.site_ipavo = 'http://www.ipavo.tw';
        ipavo.constants.site_blog  = 'http://media.ipavo.tw';
        ipavo.constants.site_space = 'http://space.ipavo.tw';
        ipavo.constants.cookie_domain = '.ipavo.tw';
        break;
    case 'www.ipavo.mini': case 'media.ipavo.mini': case 'space.ipavo.mini':
        ipavo.constants.site_ipavo = 'http://www.ipavo.mini';
        ipavo.constants.site_blog  = 'http://media.ipavo.mini';
        ipavo.constants.site_space = 'http://space.ipavo.mini';
        ipavo.constants.cookie_domain = '.ipavo.mini';
        break;
    case 'ipavo.dev':
        ipavo.constants.site_ipavo = 'http://ipavo.dev/ipavo';
        ipavo.constants.site_blog  = 'http://ipavo.dev/ipavo-media';
        ipavo.constants.site_space = 'http://ipavo.dev/ipavo-space';
        ipavo.constants.cookie_domain = 'ipavo.dev';
        break;
}


/***** Cookie Handling *****/
var MyCookie = {
    defaultPath:'/',
    defaultDomain:'',
    SetDefaultPath:function(s_path){this.defaultPath=s_path;},
    SetDefaultDomain:function(s_domain){this.defaultDomain=s_domain;},
    InitDefaults:function(){
        this.SetDefaultDomain(ipavo.constants.cookie_domain);
        this.SetDefaultPath(ipavo.constants.cookie_path);
    },
    Create:function(s_name,s_val,i_days,s_path,s_domain){
        if( typeof i_days == 'number' )
        { var date = new Date(); date.setTime(date.getTime()+(i_days*24*3600*1000)); var expires = '; expires='+date.toGMTString(); }
        else
        { var expires = ''; }
        var path = ( typeof s_path == 'string' && s_path.length > 0 ) ? '; path='+s_path : '; path='+this.defaultPath;
        var domain = ( typeof s_domain == 'string' && s_path.length > 5 ) ? '; domain='+s_domain : '; domain='+this.defaultDomain;
        document.cookie = s_name + '=' + encodeURIComponent(s_val) + expires + path + domain;
    },
    Read:function(s_name){
        var a_cookie = document.cookie.split(';');
        for( var i=0; i<a_cookie.length; i++ )
        { var s_cookie = trim(a_cookie[i]); if( s_cookie.indexOf(s_name+'=')==0 ){ return decodeURIComponent( s_cookie.substring(s_name.length+1,s_cookie.length) ); } }
        return '';
    },
    Delete:function(s_name){
        this.Create(s_name,"",-7);
    }
}
MyCookie.InitDefaults();



/* Copyright (c) 2005 Scott S. McCoy
 * This was originally a non-object oriented interface
* Function printf(format_string,arguments...)
 * Javascript emulation of the C printf function (modifiers and argument types 
 *    "p" and "n" are not supported due to language restrictions)
 *
 * Copyright 2003 K&L Productions. All rights reserved
 * http://www.klproductions.com 
 *
 * Terms of use: This function can be used free of charge IF this header is not
 *               modified and remains with the function code.
 * 
 * Legal: Use this code at your own risk. K&L Productions assumes NO resposibility
 *        for anything.
 ********************************************************************************/

String.prototype.sprintf = function () {
  var fstring = this.toString();

  var pad = function(str,ch,len) { var ps='';
      for(var i=0; i<Math.abs(len); i++) {
		  ps+=ch;
	  }
      return len>0?str+ps:ps+str;
  };
  var processFlags = function(flags,width,rs,arg) { 
      var pn = function(flags,arg,rs) {
          if(arg>=0) { 
              if(flags.indexOf(' ')>=0) {
				  rs = ' ' + rs;
			  } else if(flags.indexOf('+')>=0) {
				  rs = '+' + rs;
			  }
          } else {
              rs = '-' + rs;
		  }
          return rs;
      };
      var iWidth = parseInt(width,10);
      if(width.charAt(0) == '0') {
          var ec=0;
          if(flags.indexOf(' ')>=0 || flags.indexOf('+')>=0) {
			  ec++;
		  }
          if(rs.length<(iWidth-ec)) {
			  rs = pad(rs,'0',rs.length-(iWidth-ec));
		  }
          return pn(flags,arg,rs);
      }
      rs = pn(flags,arg,rs);
      if(rs.length<iWidth) {
          if(flags.indexOf('-')<0) {
			  rs = pad(rs,' ',rs.length-iWidth);
		  } else {
			  rs = pad(rs,' ',iWidth - rs.length);
		  }
      }    
      return rs;
  };
  var converters = [];
  converters.c = function(flags,width,precision,arg) { 
      if (typeof(arg) == 'number') {
		  return String.fromCharCode(arg);
	  } else if (typeof(arg) == 'string') {
		  return arg.charAt(0);
	  } else {
		  return '';
	  }
  };
  converters.d = function(flags,width,precision,arg) { 
      return converters.i(flags,width,precision,arg); 
  };
  converters.u = function(flags,width,precision,arg) { 
      return converters.i(flags,width,precision,Math.abs(arg)); 
  };
  converters.i =  function(flags,width,precision,arg) {
      var iPrecision=parseInt(precision, 10);
      var rs = ((Math.abs(arg)).toString().split('.'))[0];
      if(rs.length<iPrecision) {
		  rs=pad(rs,' ',iPrecision - rs.length);
	  }
      return processFlags(flags,width,rs,arg); 
  };
  converters.E = function(flags,width,precision,arg) {
      return (converters.e(flags,width,precision,arg)).toUpperCase();
  };
  converters.e = function(flags,width,precision,arg) {
      iPrecision = parseInt(precision, 10);
      if(isNaN(iPrecision)) {
		  iPrecision = 6;
	  }
      rs = (Math.abs(arg)).toExponential(iPrecision);
      if(rs.indexOf('.')<0 && flags.indexOf('#')>=0) {
		  rs = rs.replace(/^(.*)(e.*)$/,'$1.$2');
	  }
      return processFlags(flags,width,rs,arg);        
  };
  converters.f = function(flags,width,precision,arg) { 
      iPrecision = parseInt(precision, 10);
      if(isNaN(iPrecision)) {
		  iPrecision = 6;
	  }
      rs = (Math.abs(arg)).toFixed(iPrecision);
      if(rs.indexOf('.')<0 && flags.indexOf('#')>=0) {
		  rs = rs + '.';
	  }
      return processFlags(flags,width,rs,arg);
  };
  converters.G = function(flags,width,precision,arg) { 
      return (converters.g(flags,width,precision,arg)).toUpperCase();
  };
  converters.g = function(flags,width,precision,arg) {
      iPrecision = parseInt(precision, 10);
      absArg = Math.abs(arg);
      rse = absArg.toExponential();
      rsf = absArg.toFixed(6);
      if(!isNaN(iPrecision)) { 
          rsep = absArg.toExponential(iPrecision);
          rse = rsep.length < rse.length ? rsep : rse;
          rsfp = absArg.toFixed(iPrecision);
          rsf = rsfp.length < rsf.length ? rsfp : rsf;
      }
      if(rse.indexOf('.')<0 && flags.indexOf('#')>=0) {
		  rse = rse.replace(/^(.*)(e.*)$/,'$1.$2');
	  }
      if(rsf.indexOf('.')<0 && flags.indexOf('#')>=0) {
		  rsf = rsf + '.';
	  }
      rs = rse.length<rsf.length ? rse : rsf;
      return processFlags(flags,width,rs,arg);        
  };  
  converters.o = function(flags,width,precision,arg) { 
      var iPrecision=parseInt(precision, 10);
      var rs = Math.round(Math.abs(arg)).toString(8);
      if(rs.length<iPrecision) {
		  rs=pad(rs,' ',iPrecision - rs.length);
	  }
      if(flags.indexOf('#')>=0) {
		  rs='0'+rs;
	  }
      return processFlags(flags,width,rs,arg); 
  };
  converters.X = function(flags,width,precision,arg) { 
      return (converters.x(flags,width,precision,arg)).toUpperCase();
  };
  converters.x = function(flags,width,precision,arg) { 
      var iPrecision=parseInt(precision, 10);
      arg = Math.abs(arg);
      var rs = Math.round(arg).toString(16);
      if(rs.length<iPrecision) {
		  rs=pad(rs,' ',iPrecision - rs.length);
	  }
      if(flags.indexOf('#')>=0) {
		  rs='0x'+rs;
	  }
      return processFlags(flags,width,rs,arg); 
  };
  converters.s = function(flags,width,precision,arg) { 
      var iPrecision=parseInt(precision, 10);
      var rs = arg;
      if(rs.length > iPrecision) {
		  rs = rs.substring(0,iPrecision);
	  }
      return processFlags(flags,width,rs,0);
  };

  farr = fstring.split('%');
  retstr = farr[0];
  fpRE = /^([-+ #]*)(?:(\d*)\$|)(\d*)\.?(\d*)([cdieEfFgGosuxX])(.*)$/;
  for(var i = 1; i<farr.length; i++) { 
      fps=fpRE.exec(farr[i]);
      if(!fps) {
		  continue;
	  }
	  var my_i = fps[2] ? fps[2] : i;
      if(typeof arguments[my_i-1] != 'undefined') {
          retstr+=converters[fps[5]](fps[1],fps[3],fps[4],arguments[my_i-1]);
      }
      retstr += fps[6];
  }
  return retstr;
};


/* 
public string
internationalization: returns sprintf formatted text
sprintf called only if more than one argument supplied, for example __( 'MbrStorage_alert', 100 )
*/
function __( s_code )
{
    var args = arguments;
    var arg_count = args.length;
    switch( arg_count )
    {
        case 1: return LANG[ s_code ]; break;
        case 2: return LANG[ s_code ].sprintf( args[1] ); break;
        case 3: return LANG[ s_code ].sprintf( args[1],args[2] ); break;
        case 4: return LANG[ s_code ].sprintf( args[1],args[2],args[3] ); break;
        case 5: return LANG[ s_code ].sprintf( args[1],args[2],args[3],args[4] ); break;
        case 6: return LANG[ s_code ].sprintf( args[1],args[2],args[3],args[4],args[5] ); break;
        default: return LANG[ s_code ]; break;
    }
}


/* jsCSS : mixed */
/*
swap, add, remove, check
http://www.onlinetools.org/articles/unobtrusivejavascript/cssjsseparation.html
*/
function jsCSS( action, obj, class1, class2 )
{
    if( obj && typeof obj.className == 'undefined' )
    { obj.className = ''; }
    switch( action )
    {
        case 'swap': // i.e. toggle
            obj.className = !jsCSS('check',obj,class1) ? 
                obj.className.replace( class2, class1 ) :
                obj.className.replace( class1, class2 );
            break;
        
        case 'add':
            if( !jsCSS('check',obj,class1) )
            { obj.className += obj.className ? ' '+class1 : class1; }
            break;
        
        case 'remove':
            var rep = obj.className.match(' '+class1) ? ' '+class1 : class1;
            obj.className = obj.className.replace( rep, '' );
            break;
        
        case 'check':
            return new RegExp('\\b'+class1+'\\b').test(obj.className);
            break;
    }   // end switch
}   // end jsCSS


/* Multiple Onloads */
/*
usage:
    addLoadEvent( nameOfSomeFunctionToRunOnPageLoad );
    addLoadEvent( function() { // more code to run on page load } );
*/
function addLoadEvent(func) 
{
    var oldonload = window.onload;
    if ( typeof window.onload != 'function' ) 
    {
        window.onload = func;
    } 
    else 
    {
        window.onload = function() 
        {
            oldonload();
            func();
        }
    }
}

function addDomReadyEvent(f){ //(C)webreflection.blogspot.com
    var a=addDomReadyEvent,b=navigator.userAgent,d=document,w=window,c="addDomReadyEvent",e="addEventListener",o="opera",r="readyState",
    s="<scr".concat("ipt defer src='//:' on",r,"change='if(this.",r,"==\"complete\"){this.parentNode.removeChild(this);",c,".",c,"()}'></scr","ipt>");
    a[c]=(function(o){return function(){a[c]=function(){};for(a=arguments.callee;!a.done;a.done=1)f(o?o():o)}})(a[c]);
    if(d[e])d[e]("DOMContentLoaded",a[c],false);
    if(/WebKit|Khtml/i.test(b)||(w[o]&&parseInt(w[o].version())<9))(function(){/loaded|complete/.test(d[r])?a[c]():setTimeout(arguments.callee,1)})();
    else if(/MSIE/i.test(b))d.write(s);
}

/* multiple onsubmits for <form>s */
function addOnSubmitEvent(formObj, func)
{
    var oldonsubmit = formObj.onsubmit;
    if( typeof formObj.onsubmit != 'function' )
    {
        formObj.onsubmit = func;
    }
    else
    {
        form.obj.onsubmit = function()
        {
            oldonsubmit();
            func();
        }
    }
}

// addEvent( document.getElementById('abc'), 'click', someFunc );
// ev = click | load | mouseover | mouseout ...etc
// u
function addEvent( el, ev, fn, useCapture )
{
    useCapture = (typeof useCapture != 'boolean') ? false : useCapture;
    if( typeof el.addEventListener != 'undefined' ) // w3c compliant
    { el.addEventListener( ev,fn,useCapture ); }
    else if( typeof el.attachEvent != 'undefined' ) // msie
    { el.attachEvent( 'on'+ev, fn ); }
    else // all other browsers
    {
        var oldEvent = el['on'+ev];
        if( typeof el['on'+ev] != 'function' )
        { el['on'+ev] = fn; }
        else
        {
            el['on'+ev] = function()
            { oldEvent(); fn(); }
        }
    }
}


/* popup window */
function popWin( url, winame, wintype, override_extras ) 
{
    if( typeof wintype != "string" ) { wintype = ""; }
    switch( wintype )
    {
        case 'audio-info': case 'video-info': case 'image-info': case 'show-info': case 'report':
            extras = 'scrollbars=yes,resizable=yes,width=560,height=570,left=20,top=20,status=yes'; break;
        case 'audio-player': extras = 'scrollbars=no,resizable=no,width=320,height=380,left=40,top=40,status=yes'; break;
        case 'sfx-player': extras = 'scrollbars=no,resizable=no,width=320,height=380,left=40,top=40,status=yes'; break;
        case 'video-player': extras = 'scrollbars=no,resizable=no,width=320,height=380,left=40,top=40,status=yes'; break;
        case 'live-player': extras = 'scrollbars=no,resizable=no,width=320,height=400,left=500,top=40,status=yes'; break;
        case 'image-player': extras = 'scrollbars=no,resizable=yes,left=20,top=20,status=yes,'+override_extras; break;
        case 'basic': extras = 'scrollbars=yes,resizable=yes,width=350,height=550,left=20,top=20,status=yes'; break;
        case 'override': extras = override_extras; break;
        default: extras = 'scrollbars=yes,width=620,height=420,resizable=yes,status=yes';
    }
    myPop = window.open( url, winame, extras );
    try
    { myPop.focus(); } catch( e ){}
}

/* resizes viewport to w*h */
function resizeWin( w, h, x, y )
{
    var ows = window.getSize(); if(ows.size.x==w && ows.size.y==h) return;
    if(x==undefined) x = window.screenLeft || window.screenX;
    if(y==undefined) y = window.screenTop || window.screenY;
    window.moveTo(0,0); window.resizeTo(screen.availWidth,screen.availHeight);
    var ws = window.getSize();
    var ox = screen.availWidth-ws.size.x; var oy = screen.availHeight-ws.size.y; // offsets
    //alert( 'w.size.x='+ws.size.x+', w.size.y='+ws.size.y+'ox='+ox+', oy='+oy );
    window.resizeTo( w+ox, h+oy ); window.moveTo(x,y);
}

/* confirm action */
function confirmAction( url, msg )
{
    if( typeof msg != "string" )
    { msg = "Are you sure you want to proceed?"; }
    if( confirm( msg ) )
    { window.location = url; }
}


/***** Pagination *****/
function gotoPage( page_id, form_name )
{
    var formObj = document.forms[form_name];
    formObj.page.value = page_id;
    formObj.submit();
}
function orderPage( field, form_name )
{
    var formObj = document.forms[form_name];
    var reverse_sort_dir = (formObj.sort_dir.value == 'ASC') ? 'DESC' : 'ASC';
    formObj.sort_by.value = field;
    formObj.sort_dir.value = (formObj.sort_by.value == field) ? reverse_sort_dir : 'ASC';
    formObj.page.value = '1'; // always go back to page 1 upon sort/order
    formObj.submit();
}


/***** Validator class *****/
var Validator = new Object();

/* regular expressions */
Validator.RE = new Object();
Validator.RE.email = /^[_\.0-9A-Za-z-]+@([0-9A-Za-z][0-9A-Za-z-]+\.)+[A-Za-z]{2,6}$/;

/* checkString : boolean */
Validator.checkString = function( str, min_len, max_len, chktype )
{
    if( typeof chktype != "string" ) { chktype = ""; }
    if( typeof str != "string" )
    { alert( "Validator.checkString error: non-string provided" ); return false; }
    // trim the string!
    str = trim( str );
    if( min_len == 0 && str.length == 0 ) { return true; }
    if( str.length < min_len ) { return false; }
    if( str.length > max_len ) { return false; }
    switch( chktype )
    {
        case 'email':
            return Validator.RE.email.test(str);
            break;
        
        case 'no-bad-chars': // like these ones ~`!@#$%^&*()[]{}|\:;"'<,>.?/
            var badCharCodes = [126,96,33,64,35,36,37,94,38,42,40,41,91,93,123,125,124,92,58,59,34,39,60,44,62,46,63,47];
            for( var i=0; i<str.length; i++ )
            {
                for( var j=0; j<badCharCodes.length; j++ )
                { if( str.charCodeAt(i) == badCharCodes[j] ) return false; }
            }
            break;
        
        case 'safe-ascii': // ascii chars except non-printing ones
            for( var i=0; i<str.length; i++ )
            { if( str.charCodeAt(i)>125 || str.charCodeAt(i)<32 ) return false; }
            break;
        
        case 'non-english':
            for( var i=0; i<str.length; i++ )
            { if( str.charCodeAt(i)<128 ) return false; }
            break;
            
        case 'tw-pid': // Personal ID (Taiwan)
            var c, n, i;
            var t = "ABCDEFGHJKLMNPQRSTUVXYWZIO";
            var s = str;
            c = s.substring(0,1);
            c = t.indexOf(c.toUpperCase());
            if ((s.length!= 10) || (c<0)) return false;
            n = parseInt(c/10)+ c%10*9+ 1;
            for (var i=1; i<9; i++) n = n + parseInt(s.substring(i,i+1))* (9-i);
            n = (10- (n% 10))% 10;
            if (n != parseInt(s.substring(9,10))) return false;
            break;
        
        default: // only check length, which is done above
            break;
    }   // end switch
    return true;
}   // end Validator.checkString()

/* checkNumber : boolean */
Validator.checkNumber = function( num, min, max, chktype )
{
    if( isNaN(num) ) { return false; }
    switch( chktype )
    {
        case 'float':
            return ( num >= min && num <= max ); 
            break;
            
        case 'int':
        default:
            if( !(/^[0-9]+$/.test(num) ) ) { return false; }
            else { return ( num >= min && num <= max ); }
            break;
    }
    return true;
}


/***** Form Validation *****/
/*
grabs values from the "required" hidden field
*/
Validator.genericFormChecker = function( formObj )
{
    if( !isDom ) { return true; }
    // no "required" field specified
    if( !formObj.required ) return true;
    var warnings = "";
    // sample "required" field value="username,¦W¦r,3,24|gender,©Ê§O|city|email,E-mail,10,128,email"
    var req_fields_arr = formObj.required.value.split("|");
    for( var i=0; i<req_fields_arr.length; i++ )
    {
        var field_params_arr = req_fields_arr[i].split(",");
        var field_name = field_params_arr[0];
        var field_label = (field_params_arr[1]) ? field_params_arr[1] : field_name;
        if( !formObj.elements[field_name] )
        { alert("Validator.genericFormChecker Error:\nNot a form element: "+field_name); }
        var ele = formObj.elements[field_name];
        // alert( field_name + " is of type: " + ele.type +", with "+ele.length+" sub elements." );
        // do things according to field type
        switch( ele.type )
        {
            case 'text':
            case 'textarea':
                var min_len = (field_params_arr[2]) ? field_params_arr[2] : 0;
                // max length is optional and will be derviced from "required" param, maxlength attribute or hard coded (216)
                var max_len = (field_params_arr[3]) ? field_params_arr[3] : (ele.maxLength) ? ele.maxLength : 216;
                var chktype = (field_params_arr[4]) ? field_params_arr[4] : ""; // eg. "email"
                if( chktype == "int" || chktype == "float" )
                {
                    if( !Validator.checkNumber( ele.value, min_len, max_len, chktype ) )
                    { warnings += "\n- " + field_label; }
                }
                else if( !Validator.checkString( ele.value, min_len, max_len, chktype ) )
                { warnings += "\n- " + field_label; }
                break;
            
            case 'select-one':
                // just check if selected value is empty or not
                // due to IE's inability to automatically fill-in "text" as the value when
                // none has been specified
                if( ele.options[ele.selectedIndex].value == "" && ele.selectedIndex == 0 )
                { warnings += "\n- " + field_label; }
                break;
            
            case 'select-multiple':
                // not sure what to check for just yet
                break;
            
            case 'checkbox':
                // if specified, must be checked
                if( !ele.checked )
                { warnings += "\n- " + field_label }
                break;
            
            case 'file':
                if( ele.value == "" )
                { warnings += "\n- " + field_label; }
                break;
            
            case 'password': // only check for length
                var min_len = (field_params_arr[2]) ? field_params_arr[2] : 0;
                // max length is optional and will be derviced from "required" param, maxlength attribute or hard coded (216)
                var max_len = (field_params_arr[3]) ? field_params_arr[3] : (ele.maxLength) ? ele.maxLength : 216;
                var chktype = (field_params_arr[4]) ? field_params_arr[4] : ""; // eg. "email"
                if( !Validator.checkString( ele.value, min_len, max_len, chktype ) )
                { warnings += "\n- " + field_label; }
                break;
            
            default: // most likely radio group
                // determine whether this is a group of radio buttons
                if( typeof ele.length != "undefined" && ele[0].type == "radio" )
                {   // there's more than one
                    var radio_checked = 0;
                    for( var j=0; j<ele.length; j++ )
                    { if( ele[j].checked ) { radio_checked++; } }
                    if( radio_checked < 1 )
                    { warnings += "\n- " + field_label; }
                }
        }   // end switch
    
    }   // end for
    if( warnings.length > 1 )
    {
        alert( "Please make sure the following fields are correct:\n" + warnings );
        return false;
    }
    return confirm( "Are you sure you wish to proceed?" );
    
}

/*
attach form checkers
according to the "name" attribute specified
*/
Validator.attachFormCheckers = function()
{
    if( !isDom ) return;
    var formObjs = document.getElementsByTagName( "form" );
    for( var i=0; i<formObjs.length; i++ )
    {
        switch( formObjs[i].name )
        {
            
            //case 'addProjectForm':
            //    addOnSubmitEvent( formObjs[i], function(){return Validator.checkAddProjectForm(this)} );
            //    break;
            
            default: // attach generic form checker
                if( formObjs[i].elements['required'] )
                { addOnSubmitEvent( formObjs[i], function(){return Validator.genericFormChecker(this)} ); }
                break;
        }
    }
}



/***** FormUtils *****/
var FormUtils = {
    resetSelectObj:function( selObj ){
        selObjLen = selObj.length;
        for( var i=(selObjLen-1); i>=0; i-- )
        {
            selObj.options[i] = null;
        }
    },

    setSelected:function( selObj, selectedValue ){
        selObjLen = selObj.length;
        for( var i=0; i<selObjLen; i++ )
        {
            if( selObj.options[i].value == selectedValue )
            {
                if( selObj.selectedIndex == i ) { break; }
                selObj.options[i].selected = true; break; 
            }
        }
    },
    
    lockSelected:function( selObj, msg ){
        selObj.onfocus = function(){ this.blur(); alert(msg); }
    },
    
    unlockSelected:function( selObj ){
        selObj.onfocus = function(){};
    },
    
    buildSelect:function( selObj, valArr, selectedValue ){
        FormUtils.resetSelectObj( selObj );
        for( var i=0; i<valArr.length; i++ )
        {
            var label = value = valArr[i];
            selObj.options[i] = new Option( label, value, false, false );
        }
        FormUtils.setSelected( selObj, selectedValue );
    },
    
    buildSelectAssoc:function( selObj, assocObj, selectedValue ){
        FormUtils.resetSelectObj( selObj );
        var i = 0;
        for( var value in assocObj )
        {
            var label = assocObj[value];
            selObj.options[i] = new Option( label, value, false, false );
            i++;
        }
        FormUtils.setSelected( selObj, selectedValue );
    }
    
};


/* DOM Element Positioning */
function getClientWidth()
{
    if( self.innerWidth ) { return self.innerWidth; }
    else if ( document.documentElement.clientWidth ) { return document.documentElement.clientWidth; }
    else if ( document.body ) { return document.body.clientWidth; }
}
function getClientHeight()
{
    if( self.innerHeight ) { return self.innerHeight; }
    else if ( document.documentElement.clientHeight ) { return document.documentElement.clientHeight; }
    else if ( document.body ) { return document.body.clientHeight; }
}
function getPageWidth()
{
    if( window.innerWidth && window.scrollMaxX ) { return (window.innerWidth+window.scrollMaxX); }
    else if( document.body.scrollWidth > document.body.offsetWidth ) { return (document.body.scrollWidth); }
    else { return document.body.offsetWidth + document.body.offsetLeft; }
}
function getPageHeight()
{
    if( window.innerHeight && window.scrollMaxY ) { return (window.innerHeight+window.scrollMaxY); }
    else if( document.body.scrollHeight > document.body.offsetHeight ) { return (document.body.scrollHeight); }
    else { return document.body.offsetHeight + document.body.offsetTop; }
}
function findPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft;
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
	{ curleft += obj.x; }
	return curleft;
}

function findPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop;
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
	{ curtop += obj.y; }
	return curtop;
}


function addFlashObj( s_src, i_width, i_height, a_params )
{
    var new_params = new Array();
    var new_embed_params = new Array();
    if( typeof a_params != "undefined" )
    {
        for( var i=0; i<a_params.length; i++ )
        {
            var param_bits = a_params[i].split('|');
            var param_name = param_bits[0];
            var param_value = param_bits[1];
            new_params[new_params.length] = '<param name="' +param_name+ '" value="' +param_value+ '" />';
            new_embed_params[new_embed_params.length] = param_name+'="' +param_value+ '"';
        }
    }
    var obj_html = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="' +i_width+ '" height="' +i_height+ '">'+
    '<param name="movie" value="' +s_src+ '" />'+ 
    new_params.join('') +
    '<embed src="' +s_src+ '" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="' +i_width+ '" height="' +i_height+ '" ' +new_embed_params.join(' ')+ '></embed>'+
    '</object>';
    document.write( obj_html );
}



// a_params = ['showcontrols|true','autostart|true', 'uimode|mini']
// a_params = ['name|WMP','animationatstart|false','autosize|true','transparentatstart|true','showcontrols|true','autostart|true', 'uimode|mini']
// s_type = video/x-ms-wmv, audio/x-mp3
function addMediaPlayerObject( s_src, i_width, i_height, a_params )
{
    var min_width = 320;
    var ui_height = 40;
    i_height += ui_height;
    var new_params = new Array();
    var new_embed_params = new Array();
    var conf = {
        ext:''
    };
    if( typeof a_params != "undefined" )
    {
        for( var i=0; i<a_params.length; i++ )
        {
            var param_bits = a_params[i].split('|');
            var param_name = param_bits[0];
            var param_value = param_bits[1];
            if( param_name.indexOf('__') == 0 )
            { conf[param_name.substr(2)] = param_value; }
            else
            {
                new_params[new_params.length] = '<param name="' +param_name+ '" value="' +param_value+ '" />';
                new_embed_params[new_embed_params.length] = param_name+'="' +param_value+ '"';
            }
        }
    }
    if( window.ActiveXObject && ( conf['ext']!='rm' && conf['ext']!='mov' ) )
    {   // browser supports ActiveX
        var obj_html = '<object classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" width="' +i_width+ '" height="' +i_height+ '" type="application/x-oleobject">'+ // media player 9+
        //var obj_html = '<object classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95" width="' +i_width+ '" height="' +i_height+ '" type="application/x-oleobject">'+ // media player old-school
        '<param name="url" value="' +s_src+ '" />'+
        '<param name="src" value="' +s_src+ '" />'+
        new_params.join('')+
        '</object>';
    }
    else
    {   // browser does not support ActiveX object
        var embed_type = 'application/x-mplayer2';
        var obj_html = '<embed type="'+embed_type+'" width="' +i_width+ '" height="' +i_height+ '" src="' +s_src+ '" '+
        new_embed_params.join(' ')+
        '></embed>';
    }
    document.write( obj_html );
}   // end addMediaPlayerObject



function addMediaPlayerObject2( s_src, s_ext, i_mediatype, i_width, i_height, a_params )
{
    //prepare player default data
    var s_mime;
    var s_objproperty;
    var s_player;
    var isIE = ( navigator.userAgent.indexOf("MSIE") != -1 ) ? true:false;
    s_ext = s_ext.toLowerCase();
    switch(s_ext)
    {
        case 'm3u':
            i_height += 40;
            s_mime = 'audio/mpeg';
            s_objproperty = ' CLASSID="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6"';
            s_objproperty += ' STANDBY="Loading Windows Media Player components..."';
            s_player = 'wmp';
            break;
        case 'avi':
            i_height += 40;
            s_mime = 'video/avi';
            s_objproperty = ' CLASSID="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6"';
            s_objproperty += ' STANDBY="Loading Windows Media Player components..."';
            s_player = 'wmp';
            break;
        case 'mpg':
        case 'mpeg':
            i_height += 40;
            s_mime = 'video/mpeg';
            s_objproperty = ' CLASSID="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6"';
            s_objproperty += ' STANDBY="Loading Windows Media Player components..."';
            s_player = 'wmp';
            break;
        case 'asf':
        case 'wmv':
            i_height += 40;
            s_mime = 'video/x-ms-wmv';
            s_objproperty = ' CLASSID="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6"';
            s_objproperty += ' STANDBY="Loading Windows Media Player components..."';
            s_player = 'wmp';
            break;
        case 'wma':
            i_height += 40;
            s_mime = 'audio/x-ms-wma';
            s_objproperty = ' CLASSID="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6"';
            s_objproperty += ' STANDBY="Loading Windows Media Player components..."';
            s_player = 'wmp';
            break;
        case 'mp3':
            i_height += 40;
            s_mime = 'audio/mp3';
            s_objproperty = ' CLASSID="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6"';
            s_player = 'wmp';
            break;
        case 'rm':
        case 'ra':
        case 'ram':
            s_mime = 'audio/x-pn-realaudio';        
            if( !isIE ) s_mime = 'audio/x-pn-realaudio-plugin';
            s_objproperty = ' CLASSID="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"';
            s_player = 'rmp';
            break;
        case 'mov':
        case 'qt':
            i_height += 16;
            s_mime = 'video/quicktime';
            s_objproperty = ' classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"';            
            s_objproperty += ' codebase="http://www.apple.com/qtactivex/qtplugin.cab"';
            s_player = 'qtp';
            break;
        case 'mp4':
            i_height += 16;
            if(i_mediatype)
                s_mime = 'audio/quicktime';        
            else
                s_mime = 'video/quicktime';        
            s_objproperty = ' classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"';            
            s_objproperty += ' codebase="http://www.apple.com/qtactivex/qtplugin.cab"';
            s_player = 'qtp';
            break;
    }
    s_objproperty += ' type="'+s_mime+'"';
    //prepare parameters
    var new_params = new Array();
    var new_embed_params = new Array();
    var conf = {
        ext:''
    };
    if( typeof a_params != "undefined" )
    {
        for( var i=0; i<a_params.length; i++ )
        {
            var param_bits = a_params[i].split('|');
            var param_name = param_bits[0];
            var param_value = param_bits[1];
            if( param_name.indexOf('__') == 0 )
            { conf[param_name.substr(2)] = param_value; }
            else
            {
                new_params[new_params.length] = '<param name="' +param_name+ '" value="' +param_value+ '" />';
                new_embed_params[new_embed_params.length] = param_name+'="' +param_value+ '"';
            }
        }
    }
    //prepare player tag
    var obj_html;
    var s_param, s_embed_param;
    s_param = '<param name="url" value="' +s_src+ '" />'+
              '<param name="src" value="' +s_src+ '" />'+
                new_params.join('');
    s_embed_param = new_embed_params.join(' ');
    switch(s_player)
    {
        case 'rmp': // real media player
            obj_html = '<object width="' +i_width+ '" height="' +i_height+ '"' +s_objproperty+ '>'+
                s_param +
                '<PARAM name="controls" value="imagewindow">'+
                '<PARAM name="autostart" value="true">'+
                '<embed type="'+s_mime+'" width="' +i_width+ '" height="' +i_height+ '" src="' +s_src+ '" '+
                s_embed_param + 
                ' CONTROLS="imagewindow" autostart="true"' +
                '></embed></object><br/>'+
                '<object width="' +i_width+ '" height="40"' +s_objproperty+ '>'+
                s_param +
                '<PARAM name="controls" value="ControlPanel">'+
                '<PARAM name="autostart" value="true">'+
                '<embed type="'+s_mime+'" width="' +i_width+ '" height="40" src="' +s_src+ '" '+
                s_embed_param + 
                ' CONTROLS="ControlPanel" autostart="true"' +
                '></embed></object>';
            break;
            
        case 'wmp':
            obj_html = '<object width="' +i_width+ '" height="' +i_height+ '"' +s_objproperty+ '>'+
                s_param +
            	'<param name="ShowAudioControls" value="true">'+
	            '<param name="ShowStatusBar" value="true">'+
	            '<param name="ShowDisplay" value="true">'+
                '<param name="ShowPositionControls" value="true">'+
                '<param name="ShowTracker" value="true">'+
                '<PARAM name="autostart" value="true">'+
                '<Param name="volume" value="50">'+
                '<Param name="StretchToFit" value="true">'+
                '<Param name="invokeURLs" value="false">'+
                '<param name="fullScreen" value="false">'+
                '<param name="enable" value="true">'+
                '<embed type="'+s_mime+'" width="' +i_width+ '" height="' +i_height+ '" src="' +s_src+ '" '+
                s_embed_param +
                'autostart="1" '+
                'ShowAudioControls="1" '+
                'ShowStatusBar="1" '+
                //'ShowDisplay=1 '+
                //'ShowPositionControls=1 '
                //'ShowTracker=1 '+
                'Volume="50" '+
                'StretchToFit="1" '+
                'invokeURLs="0" '+
                'fullscreen="0" '+
                'enableContextMenu="1" '+
                '></embed></object>';
            break;
        
        case 'qtp': // automatic
            obj_html = '<object width="' +i_width+ '" height="' +i_height+ '"' +s_objproperty+ '>'+
                s_param +
                '<PARAM name="controller" value="true">'+
                '<PARAM name="autoplay" value="true">'+
                '<embed type="'+s_mime+'" width="' +i_width+ '" height="' +i_height+ '" src="' +s_src+ '" '+
                'pluginspage="http://www.apple.com/quicktime/download/" controller="true" autoplay="true" ' +s_embed_param +
                '></embed></object>';
            break;
        
        default:
            obj_html = '<embed src="' +s_src+ '" width="' +i_width+ '" height="' +i_height+ '">';
            break;
    }
    document.write( obj_html );
}   // end addMediaPlayerObject2


var Animator = new Object();
Animator.fader = new Object();
Animator.fader.vars = new Object();
Animator.fader.vars.opac_now = false;
Animator.fader.vars.ele_id = false;
Animator.fader.vars.opac_start = 100;
Animator.fader.vars.opac_end = 0;
Animator.fader.vars.opac_increment = 10;
Animator.fader.vars.ms_delay = 50;
Animator.fader.vars.func2run = "";

// Animator.fader.fadeInit( 'some-div', 0, 100, 10, 50, "funcToRun('whatever')" );
Animator.fader.init = function( ele_id, opac_start, opac_end, opac_increment, ms_delay, func2run )
{
    var afv = Animator.fader.vars;
    afv.ele_id = ele_id;
    afv.opac_start = ( opac_start > 100 ? 100 : ( opac_start < 0 ? 0 : opac_start ) );
    afv.opac_end = ( opac_end > 100 ? 100 : ( opac_end < 0 ? 0 : opac_end ) );
    afv.opac_now = afv.opac_start;
    afv.opac_increment = opac_increment;
    afv.ms_delay = ms_delay;
    afv.func2run = func2run;
}
Animator.fader.fadeIn = function( afv )
{
    if( typeof afv == 'undefined' )
    {
        var afv = {
            opac_now:   Animator.fader.vars.opac_now,
            ele_id:     Animator.fader.vars.ele_id,
            opac_start: Animator.fader.vars.opac_start,
            opac_end:   Animator.fader.vars.opac_end,
            opac_increment:Animator.fader.vars.opac_increment,
            ms_delay:   Animator.fader.vars.ms_delay,
            func2run:   Animator.fader.vars.func2run }
    }
    if( afv.opac_now < afv.opac_end )
    {
        afv.opac_now += afv.opac_increment;
        afv.opac_now = (afv.opac_now > 100) ? 100:afv.opac_now;
        var ele = document.getElementById( afv.ele_id );
        if( document.all && navigator.appName.indexOf('Opera')<0 ) { ele.style.filter = "alpha(opacity="+afv.opac_now+")"; }
        else { ele.style.opacity = ( afv.opac_now/100 ); }
        //window.status = 'fadeIn:'+afv.opac_now;
        setTimeout( 'Animator.fader.fadeIn({opac_now:'+afv.opac_now+', ele_id:"'+afv.ele_id+'", opac_start:'+afv.opac_start+', opac_end:'+afv.opac_end+', opac_increment:'+afv.opac_increment+', ms_delay:'+afv.ms_delay+', func2run:"'+afv.func2run+'"})', afv.ms_delay );
    }
    else
    {   // done, execute function
        if( typeof afv.func2run == "string" && afv.func2run.length > 0 ) 
        { eval( afv.func2run ); }
        //window.status = 'fadeIn:done'+afv.opac_now;
    }
}
Animator.fader.fadeOut = function( afv )
{   
    if( typeof afv == 'undefined' )
    {
        var afv = {
            opac_now:   Animator.fader.vars.opac_now,
            ele_id:     Animator.fader.vars.ele_id,
            opac_start: Animator.fader.vars.opac_start,
            opac_end:   Animator.fader.vars.opac_end,
            opac_increment:Animator.fader.vars.opac_increment,
            ms_delay:   Animator.fader.vars.ms_delay,
            func2run:   Animator.fader.vars.func2run }
    }
    if( afv.opac_now > afv.opac_end )
    {
        afv.opac_now -= afv.opac_increment;
        afv.opac_now = (afv.opac_now<0) ? 0:afv.opac_now;
        var ele = document.getElementById( afv.ele_id );
        if( document.all && navigator.appName.indexOf('Opera')<0 ) { ele.style.filter = "alpha(opacity="+afv.opac_now+")"; }
        else { ele.style.opacity = ( afv.opac_now/100 ); }
        //window.status = 'fadeOut:'+afv.opac_now;
        setTimeout( 'Animator.fader.fadeOut({opac_now:'+afv.opac_now+', ele_id:"'+afv.ele_id+'", opac_start:'+afv.opac_start+', opac_end:'+afv.opac_end+', opac_increment:'+afv.opac_increment+', ms_delay:'+afv.ms_delay+', func2run:"'+afv.func2run+'"})', afv.ms_delay );
    }
    else
    {   // done, execute function
        if( typeof afv.func2run == "string" && afv.func2run.length > 0 ) 
        { eval( afv.func2run ); }
        //window.status = 'fadeOut:done'+afv.opac_now;
    }
}
Animator.scroller = {
    YDown:function( asv ) // asv:{ ele_id:"", scroll2height:-1, increment:2, delay }
    {
        
    },
    YUp:function(  )
    {}
};


function addBannerAd( zone )
{
    if( !document.phpAds_used) document.phpAds_used = ',';
    phpAds_random = new String(Math.random()); phpAds_random = phpAds_random.substring(2,11);
    document.write( '<'+'script type="text/javascript" src="http://ads.iwant-in.net/v1/adjs.php?n='+phpAds_random+'&amp;what=zone:'+zone+'&amp;exclude='+document.phpAds_used+'&amp;charset='+(document.charset || document.characterSet)+(document.referrer?'&amp;referer='+document.referrer:'')+'"></'+'script>');
}

function loadBannerAds()
{
    var divEls = document.getElementsByTagName('div');
    var adRE = new RegExp( "phpad-[0-9]{1,8}-[0-9]{2,3}-[0-9]{2,3}" ); // phpad-(id)-(width)-(height)
    for( var i=0; i<divEls.length; i++ )
    {
        if( typeof divEls[i].className == 'string' && adRE.test( divEls[i].className ) )
        {
            var ad_params = divEls[i].className.match(adRE)[0].split('-');
            var pa_id = ad_params[1]; var pa_w = ad_params[2]; var pa_h = ad_params[3];
            var pa_random = new String(Math.random()); pa_random = 'N'+pa_random.substring(2,11);
            var pa_html = '<iframe id="'+pa_random+'" name="'+pa_random+'" width="'+pa_w+'" height="'+pa_h+'" src="http://ads.iwant-in.net/v1/adframe.php?n='+pa_random+'&amp;what=zone:'+pa_id+'&amp;charset='+(document.charset || document.characterSet)+'" framespacing="0" frameborder="no" scrolling="no"></iframe>';
            divEls[i].innerHTML = pa_html;
        }
    }
}

/*
counter
*/
var initCounterImg = function()
{
    var pageviewImg = new Image();
    pageviewImg.src = ipavo.constants.site_ipavo+'/counter.php?url='+escape(location.href);
}

/* Navigation */
var iNav = {
    cons:{
        revertCheckIntervalMS:1000,
        revertDelayMS:2500
    },
    vars:{
        defaultNavId:'',
        defaultSubId:'',
        currentNavId:'',
        lastChanged:0,
        lastHovered:0,
        lastLeft:0,
        revertIntervalId:0
    },
    SetDefaults:function( navId, subId ) {
        if( typeof navId == 'string' ) iNav.vars.defaultNavId = navId;
        if( typeof subId == 'string' ) iNav.vars.defaultSubId = subId;
    },
    Init:function() {
        if( !document.getElementById('sec-nav') || !document.getElementById('main-nav') ) return;
        if( document.getElementById('sec-nav') )
        {   // secondary nav
            var snItems = document.getElementById('sec-nav').getElementsByTagName('li');
            for( var i=0; i<snItems.length; i++ )
            {
                if( snItems[i].className.indexOf('lv-1') != 0 ) continue;
                snItems[i].onmouseover = function(){this.className='lv-1 navOn'};
                snItems[i].onmouseout  = function(){this.className='lv-1'};
            }
        }
        if( document.getElementById('main-nav') )
        {   // main nav
            var mnItems = document.getElementById('main-nav').getElementsByTagName('li');
            for( var i=0; i<mnItems.length; i++ )
            {
                if( mnItems[i].className == 'lv-1' )
                { 
                    mnItems[i].onmouseover = function(){ iNav.ShowSubNav(this.id) }; 
                    mnItems[i].onmouseout  = function(){ iNav.vars.lastLeft = new Date() }; 
                }
            }
        }
        if( document.getElementById('mbr-toolbar-out') )
        { 
            addOnSubmitEvent( document.forms['mbrLoginForm'], function(){return ipavo.ChkLoginForm(this)} );
            ipavo.ChkMbrLoginStatus("ipavo.TryLogin(false)");
        }
        var subNav = document.getElementById('sub-nav');
        subNav.onmouseover = iNav.HoverSub;
        subNav.onmouseout = iNav.LeaveSub;
        if( iNav.vars.defaultNavId != '' )
        { iNav.ShowSubNav( iNav.vars.defaultNavId ); }
        iNav.vars.revertIntervalId = setInterval("iNav.RevertDefault()",iNav.cons.revertCheckIntervalMS);
    },
    ShowSubNav:function( nav_id ) {
        var subNav = document.getElementById('sub-nav');
        if( document.getElementById(nav_id) )
        {
            var navItem = document.getElementById(nav_id);
            var subItems = document.getElementById(nav_id).getElementsByTagName('a');
            var tmpItems = [];
            for( var i=0; i<subItems.length; i++ )
            {
                if( subItems[i].className.indexOf('lv-1') != -1 ) continue;
                var tmpItem = subItems[i].cloneNode(true); tmpItem.id = 'sub'+tmpItem.id;
                tmpItems[tmpItems.length] =  tmpItem;
            }
            subNav.innerHTML = '';
            var divEl = document.createElement('span');
            divEl.className = 'divider';
            divEl.appendChild( document.createTextNode(' | ') );
            for( var i=0; i<tmpItems.length; i++ )
            {
                if( tmpItems[i].id == 'sub'+iNav.vars.defaultNavId+'-'+iNav.vars.defaultSubId ) tmpItems[i].className = 'navOn';
                subNav.appendChild( tmpItems[i] );
                if( i != (tmpItems.length-1) )
                { subNav.appendChild( divEl.cloneNode(true) ); }
            }
            subNav.style.display = 'block';
            var mnItems = document.getElementById('main-nav').getElementsByTagName('li');
            for( var i=0; i<mnItems.length; i++ )
            {
                if( mnItems[i].className.indexOf('lv-1')==0 )
                { mnItems[i].className = (mnItems[i].id==nav_id) ? 'lv-1 navOn':'lv-1'; }
            }
            iNav.vars.currentNavId = nav_id;
            iNav.vars.lastChanged = new Date();
            iNav.vars.lastHovered = new Date();
            iNav.vars.lastLeft = 0;
        }
    },
    RevertDefault:function() {
        var now = new Date();
        if( iNav.vars.defaultNavId == '' ) return;
        if( iNav.vars.defaultNavId == iNav.vars.currentNavId ) return; // no revert required
        if( ( now - iNav.vars.lastChanged ) < iNav.cons.revertDelayMS ) return; // just changed
        if( iNav.vars.lastHovered > 0 && iNav.vars.lastLeft == 0 ) return; // still hovering on subnav
        if( iNav.vars.lastLeft != 0 && (now-iNav.vars.lastLeft)<iNav.cons.revertDelayMS ) return; // haven't left for long enough
        iNav.ShowSubNav( iNav.vars.defaultNavId );
    },
    HoverSub:function() {
        iNav.vars.lastHovered = new Date();
        iNav.vars.lastLeft = 0;
    },
    LeaveSub:function() {
        iNav.vars.lastLeft = new Date();
    }
}

/***** Codes to run on body onload *****/
addLoadEvent( initCounterImg );
addDomReadyEvent( iNav.Init );
addDomReadyEvent( function(){ setTimeout('loadBannerAds();',1200); } );