//
// <hCbLib.js>
// 
// HTML Callback mini-fwk
// 
// requires UtilLite
//          BrowserCheck
// exports  hCbLib.init
//          hCbLib.fetch
//

function hCbLib(){};
	  hCbLib.__ok    = null;
     hCbLib.__begin = 'begin';
     hCbLib.__end   = 'end';
     hCbLib.__wrapper_level = 'wrapper';
     hCbLib.__onload        = 'onload';
     hCbLib.__format        = 'format';
     hCbLib.__buffers       = 1;
     hCbLib.__timeout       = 30;
     hCbLib.__tool          = 'tool';
     hCbLib.__prefix        = 'io_';
     hCbLib.__path          = top;
     hCbLib.__code          = 'top';
     hCbLib.__rid           = 1;
     hCbLib.OK              = 0;
     hCbLib.BUSY            = -1;
     hCbLib.NO_ARGS         = -2;
     hCbLib.NO_CB           = -3;
     hCbLib.NO_URI          = -4;
     hCbLib.NO_BUFFERS      = -5;
     hCbLib.BAD_RID         = -6;
     hCbLib.IS_OK           = 0;
     hCbLib.IS_TIMEOUT      = 1;
     hCbLib.IS_ERROR        = 2;

//                                                                             init
//                                                                             ----
hCbLib.init = function( args )
{
    for( var arg in args ) {
        this[ "__" + arg ] = args[arg];
    }
    if ( typeof Util == "undefined" ) {
        Util = top.Util;
    }
	 this.__b = new Array( this.__buffers );
	 for( var fr = 0; fr < this.__buffers; fr++ ) 
	 {
        if ( !Util.isOk( this.__path[ this.__prefix + fr ] ) ) {
            return hCbLib.NO_BUFFERS;
        }
		  this.__b[fr]= { __ri : this.BAD_RID };
	 }
    if ( self != top ) {
        hCbLib.__code = '.' + self.name;
    }
    else {
        hCbLib.__code = '';
    }
    var wf = self;
    while( top != wf.parent ) {
        wf = wf.parent;
        hCbLib.__code = '.' + wf.name + hCbLib.__code;
    }
    hCbLib.__code = 'top' + hCbLib.__code;
	 hCbLib.__ok = 1;
	 return hCbLib.OK;
}

//                                                                            fetch
//                                                                            -----
hCbLib.fetch = function( args )
{
    if ( !Util.isOk( args ) ) {
        return hCbLib.NO_ARGS;
    }
    var u = Util.get_if_ok( args.uri, null );
    if ( u != null ) {
        var cbo = Util.get_if_ok( args.callback_context, null );
        var cbf = Util.get_if_ok( args.callback_function, null );
        if ( cbo == null ) {
            cbo = Util.get_if_ok( args.callback, null );
        }
        if ( cbo != null ) {
            var to = Util.get_if_ok( args.timeout, hCbLib.__timeout );
            var id     = hCbLib.__get_buffer( cbo, cbf, to );
            var tool   = Util.get_if_ok( args.tool, '__s0');
            var format = Util.get_if_ok( args.format, 'text/html');
            var w  = Util.get_if_ok( args.wrapper, 2 );
            var wb = Util.get_if_ok( args.begin, escape('window.onerror=function(){' + hCbLib.__code + '.hCbLib.__fetch_done(null,'+id+',2);return true;};') );
            var we = Util.get_if_ok( args.end, '' );
            if ( Util.isOk( id ) ) {
                u =  u + (u.indexOf('?') != -1 ? '&' : '?');
                u +=       hCbLib.__format        + '=' + format;
                u += '&' + hCbLib.__tool          + '=' + tool;
                u += '&' + hCbLib.__wrapper_level + '=' + w;
                u += '&' + hCbLib.__end   + '=' + we;
                u += '&' + hCbLib.__begin + '=' + wb;
                u += '&' + hCbLib.__onload        + '=' + escape( hCbLib.__code + '.hCbLib.__fetch_done('+ tool +','+id+',0);');
                this.__path[this.__prefix+id].location.replace( u );
                return hCbLib.__get_request_id( id );
            }
            else {
                // there isn't a free buffer
                // [tbd] try again
                return hCbLib.BUSY;
            }
        }
        else {
           return hCbLib.NO_CB;
        }
    }
    else {
        return hCbLib.NO_URI;
    }
return hCbLib.NO_ARGS;
}


// get_buffer
// @param ho -> a handler object
// @param hf -> the function name
// @param to -> time out
// @return a buffer id or null
hCbLib.__get_buffer = function( ho, hf, to )
{
    hf = Util.get_if_ok( hf, null );
	 for(var __fb=0; __fb<this.__b.length; __fb++) {
		  if ( this.__b[__fb].__ri < 0 ) {
				this.__b[__fb] = {
                 __ho : ho
                ,__hf : hf
					 ,__to : window.setTimeout('hCbLib.__to_consumed('+__fb+')',to*1000)
                ,__ri : hCbLib.__generate_id()
				};
            if ( hCbLib.__color_1 ) {
					 hCbLib.__write_in_frame( __fb, '<body bgcolor=' + hCbLib.__color_1 +'></body>' );
            }
				return __fb;
		  }
	 }
	 return null;
}

// (release_buffer)
// @param id -> the buffer id
hCbLib.__release_buffer = function(id)
{
	 var __t = hCbLib.__noop;
	 if (Util.isOk(this.__b[id])) {
		  __t = { o: this.__b[id].__ho, f: this.__b[id].__hf, i: this.__b[id].__ri };
		  window.clearTimeout(this.__b[id].__to);
	 }
	 this.__b[id].__ri = this.BAD_RID;
    if ( hCbLib.__color_2 ) {
		  hCbLib.__write_in_frame( id, '<body bgcolor=' + hCbLib.__color_2 +'></body>' );
    }
    return __t;
}

hCbLib.__generate_id = function()
{
    return hCbLib.__rid++;
}

hCbLib.__get_request_id = function( id ) 
{
	 if ( Util.isOk( this.__b[id] ) ) {
		  return this.__b[id].__ri;
	 }
	 else {
		  return this.BAD_RID;
	 }
}

hCbLib.__noop = function()
{
};

// (fetch_done)
// o -> the fetched object
// id -> the buffer used to obtain the object 
// tor -> type of result 0-normal 1-timeout 2-error en eval
hCbLib.__fetch_done = function(o,id,tor)
{
	 to = Util.get_if_ok( tor, 0 );
	 if ( hCbLib.isOk() ) {
		  var rid = hCbLib.__get_request_id( id );
		  var handler = this.__release_buffer( id );
		  if ( Util.isOk(handler) ) {
				if ( handler.o.constructor == String ) {
					 eval( handler.o + '(' + o + ',{ request:' + rid + ',type:' + tor + ' })' );
				}
				else {
					 if ( handler.f != null ) {
						  handler.o[handler.f]( o, { request: rid, type: tor } );
					 }
					 else {
						  handler.o( o, { request: rid, type: tor } );
					 }
				}
		  }
	 }
}

// timeout
// manage the time-out
// @param id -> request id
hCbLib.__to_consumed = function( id )
{
	 this.__fetch_done( null, id, 1 );
}

hCbLib.__write_in_frame = function( id, htmlStr )
{
	 var d = this.__path[this.__prefix+id].document;
	 if ( is.ie ) {
		  d.charset = 'iso-8859-1';
		  d.body.innerHTML = htmlStr; 
	 }
	 else {
		  d.open();
		  d.write( htmlStr );
		  d.close();
	 }
}

hCbLib.isOk = function()
{
	 return hCbLib.__ok;
}

// </hCbLib.js>
