/*
    .-------------------------.
    |   Show error functions  |
    *-------------------------*
	   
    Requires:
        - dojo
    
    Author: 
        Marko Ristin
    
    Changelog:
        - 2007/01/27, mristin, initial version
        - 2007/08/15, ahermann, reformatted comments for automatic documentation
        - 2007/11/16, ahermann, merged debug functions into file
*/

/**
 * Function: show_errors
 *       Takes care of displaying error messages.
 *       All the other spans will be hidden.
 * 
 * @param {Array} error_msgs Error messages
 * @param {String} error_div_id Error div identifier
 */
function show_errors( error_msgs, error_div_id )
{      
    /*extern dojo */
    var error_div = null;
    
    if ( !error_div_id )
    {
        error_div = dojoWrapper.getById ( 'id_div_errors' );
    }
    else
    {
        error_div = dojoWrapper.getById ( error_div_id );
    }
    
    /*
        Show errors:
    */
    error_div.style.display = '';
        
    /*
        Add errors to the list:    
    */
    var an_error_list = document.createElement ( 'ul' );
    error_div.appendChild ( an_error_list );   

    for ( i in error_msgs )
    {
        /*
            Create list item for this error message:            
        */
        var a_list_item = document.createElement ( 'li' );            

        /*
            Check if it's conventional error:                
        */                                           
        var a_msg = '#' + i + ': ';
        
        if ( error_msgs[i].name )
        {
            a_msg = error_msgs[i].name + ': ';
        }
        
        if ( error_msgs[i].message )
        {
            a_msg += error_msgs[i].message;
        }                                             
        else
        {
            a_msg += error_msgs [ i ];
        }
     
        a_list_item.innerHTML = a_msg;
        
        /*
            Attach it to the list:
        */       
        an_error_list.appendChild ( a_list_item );
    }
}

/**
 * Function: show_errors_dump
 * @param {Object} an_obj
 * @param {Object} a_title
 * @param {Object} parent_string
 * @param {Object} next_line_string
 * @param {Object} only_shallow_dump
 */
function show_errors_dump ( an_obj,
                            a_title, 
                            parent_string, 
                            next_line_string,
                            only_shallow_dump )
{
    var next_line_joiner = '<br>\n';
    
    if ( next_line_string ) 
    {
        next_line_joiner = next_line_string;
    }
        
    if ( a_title )
    {
        a_title = '<b>  ' + a_title + '  </b>';
    }
    else
    {
        a_title = '';
    }
        
    show_errors( [ a_title + next_line_joiner +
                    dump(an_obj, parent_string, only_shallow_dump).join( next_line_joiner )
                  ]);
}

/**
 * Function: show_errors_dump_shallow
 * 
 * @param {Object} an_obj
 * @param {Object} a_title
 * @param {Object} parent_string
 * @param {Object} next_line_string
 */
function show_errors_dump_shallow ( an_obj, 
                                    a_title, 
                                    parent_string, 
                                    next_line_string )
{
    show_errors_dump ( an_obj,
                       a_title, 
                       parent_string, 
                       next_line_string,
                       true /* only_shallow_dump */ 
                     );
}

/**
 * Function: dump_shallow
 *   Dumps the properties on the top of the object hierarchy
 *   
 * @param {Object} obj The object that should be dumped
 * @param {Object} parent_string
 */
function dump_shallow ( obj, parent_string )
{
    var result;
    
    result = dump ( obj, 
                    parent_string, 
                    true /* only_shallow_dump */
                  );
                  
    return result;                  
}

/**
 * Function: dump
 *   Dumps the information of an object
 *   
 * @param {Object} obj The object that should be dumped
 * @param {Object} parent_string
 * @param {Object} only_shallow_dump Whether only the properties on the top of the object hierarchy should be dumped
 * @return {String} dumped information
 */
function dump( obj, parent_string, only_shallow_dump ) 
{       
    var regexp_identifier = /^[_A-Za-z][_A-Za-z0-9]*$/;
    
    var dump_strs = [];        
    
    if ( obj === null )
    {
        var prefix = '';
        if ( parent_string )
        {
            prefix = parent_string + ' = ';
        }
        
        dump_strs.push ( prefix + 'null' ); 
    }    
    else if ( is_number  ( obj ) || 
              is_boolean ( obj )    
            )
    {
        var prefix = '';
        if ( parent_string )
        {
            prefix = parent_string + ' = ';
        }
        
        dump_strs.push ( prefix + String ( obj ));
    }
    else if ( is_string ( obj ) )
    {
        var prefix = '';
        if ( parent_string )
        {
            prefix = parent_string + ' = ';
        }
                                     
        dump_strs.push (  prefix + '"' + String ( obj ) + '"');        
    }
    else
    {
        /*
            It's an object:
        */    
        for ( var a_property in obj )
        {
            /*
                Is it a property, an index or a
                hashed string?
            */
            var a_property_transformed;
            
            if ( regexp_identifier .test ( a_property ) )
            {
                a_property_transformed = '.' + a_property;
            }
            else
            {
                a_property_transformed = ' [ ' +
                                         a_property +
                                         ' ]';
            }
            
            /*
                Now print that property:
            */
            
            if ( is_string   ( obj [ a_property ] ) ||
                 is_number   ( obj [ a_property ] ) ||
                 is_boolean  ( obj [ a_property ] ) ||
                 is_function ( obj [ a_property ] ) ||
                 obj [ a_property ] == null         ||                 
                 obj [ a_property ] == undefined    ||
                 typeof ( obj [ a_property ] ) == 'unknown')
            {                
                /*
                    It is a simple item:
                */
                dump_strs .push ( parent_string + 
                                  a_property_transformed +
                                  ' = ' +
                                    dump ( obj [ a_property ] )[0]
                                );            
            }
            else if ( typeof obj [ a_property ] == 'object' && obj != null)
            {
                /*
                    It is a structure:
                */
                
                /*
                    If we have shallow dump,
                    just print object.
                    
                    Otherwise recurse:
                */
                if ( only_shallow_dump )
                {
                    if ( is_array ( obj [ a_property ] ) )
                    {
                        dump_strs.push ( parent_string             + 
                                          a_property_transformed    +
                                          ' = '                     +
                                          '[Array, length: '        +
                                          obj [ a_property ].length +
                                          ']');       
                    }
                    else
                    {
                        dump_strs .push ( parent_string + 
                                          a_property_transformed +
                                          ' = ' + 
                                          String ( obj ) 
                                        );
                    }
                }
                else
                {
                    var a_sub_dump_array  = dump ( obj [ a_property ], 
                                     parent_string +  a_property_transformed );
                    
                    for ( var i = 0; i < a_sub_dump_array.length; i ++ )
                    {
                        dump_strs .push ( a_sub_dump_array [ i ] );
                    }                
                }                    
            }
            else
            {
                dump_strs .push ( 
                                  parent_string + 
                                  a_property_transformed + 
                                  ' = ' + 
                                  String ( obj [ a_property ] )
                                );
            }
        }         
        
    }    
    return dump_strs;
}
