function onDocumentReady()
{
    // make sure the channel image is not too big 
    $("img#channelImage").load( function() {
        if ( $(this).height() > 50 )
        {
            $(this).height( 50 ) ;
            $(this).width( "auto" ) ;
        }
        else if ( $(this).width() > 300 )
        {
            $(this).width( 300 ) ;
            $(this).height( "auto" ) ;
        }
    } ).each( function() {
        // FUDGE! Handle images that have already loaded (probably from the cache).
        if ( this.complete )
            $(this).trigger( "load" ) ;
    } ) ;

    // start loading item content
    if ( gAsyncItemsReqId != null )
        loadItemContent() ;
}

function loadItemContent()
{
    // NOTE: We load the content for each item one at a time. When each one finishes,
    //  it kicks off the next one.
    if ( gAsyncItemIds.length == 0 )
    {
        // notify Awasu we're done
        var url = gApiBaseUrl + "/channels/_getItem?req=" + gAsyncItemsReqId + "&id=0" ;
        if ( gApiToken != null )
            url += "&token=" + gApiToken ;
        $.get( url ) ;
        return ;
    }
    var itemId = gAsyncItemIds.shift() ;

    // allocate a request
    var url = gApiBaseUrl + "/channels/_getItem?req=" + gAsyncItemsReqId + "&id=" + itemId ;
    if ( gApiToken != null )
        url += "&token=" + gApiToken ;
    var xhr = new XMLHttpRequest() ;
    if ( "withCredentials" in xhr )
        xhr.open( "get" , url , true ) ;
    else if ( typeof XDomainRequest != "undefined" )
    {
        xhr = new XDomainRequest() ;
        xhr.open( "get" , url ) ;
    }
        
    // prepare the request
    var divId = "async-item-" + itemId ;
    xhr.onload = function() {
        document.getElementById(divId).innerHTML = xhr.responseText ;
        awasu_resizeImages( "#"+divId ) ;
        if ( location.hash == "#"+itemId )
        {
            // NOTE: While doing this looks pointless, it tells the browser to go to this anchor.
            //  We want to do it now since this item, and everything above it, has now been loaded
            //  and so the browser will go to the correct place (i.e. any page re-layouts will be
            //  below this item, and so the content we want to show will stay in place).
            // NOTE: We're not immune from images above this item from loading and causing a reflow,
            //  but there's not much we can do about that.
            location.hash = "#" + itemId ;
        }
        loadItemContent() ;
    }
    xhr.onerror = function() {
        document.getElementById(divId).innerHTML = "ERROR: " + xhr.statusText ;
        loadItemContent() ;
    }   ;
    
    // work around problems in IE9
    xhr.onprogress = function () { } ;
    xhr.ontimeout = function () { } ;
    
    // send the request (wrap in timeout to work-around a problem in IE9)
    setTimeout(
        function () { xhr.send() ; } ,
        0
    );
}

function awasu_resizeImages( selList )
{
    $.each( selList.split(",") , function(key,val) {
        // adjust over-sized images
        $(val+" img").load( function() {
            if ( $(this).width() > document.body.clientWidth )
            {
                $(this).width( "99%" ) ;
                $(this).height( "auto" ) ;
            }
        } ).each( function() {
            // FUDGE! Handle images that have already loaded (probably from the cache).
            if( this.complete )
                $(this).trigger( "load" ) ;
        } ) ;
        
        // retry images that failed to load
        $(val+" img").error( function() {
            if( (typeof this.naturalWidth != "undefined" && this.naturalWidth == 0) || this.readyState == 'uninitialized' )
            {
                var url = $(this).attr( "src" ) ;
                if ( url.indexOf("127.0.0.1") < 0 && url.indexOf("localhost") < 0 )
                {
                    url = gProxyBaseUrl + "/" + $(this).attr("awasuid") ;
                    $(this).removeAttr("src").attr( "src" , url ) ;
                }
            }
        } ) ;
        
    } ) ;
}
