"use strict" ;

import dumpArray  from './dumpArray'
import dumpDate   from './dumpDate'
import dumpObject from './dumpObject'
import dumpString from './dumpString'

/**
 * Dumps a string representation of any object reference.
 * @name dump
 * @memberof core
 * @function
 * @instance
 * @param {*} value - Any object to dump.
 * @param {boolean} [prettyprint=false] boolean option to output a pretty printed string
 * @param {number} [indent=0] initial indentation
 * @param {string} [indentor=    ] initial string used for the indent.
 * @return The string expression of the dump.
 * @example
 * var object =
 * {
 *     name   : "vegas" ,
 *     count  : 10 ,
 *     time   : new Date() ,
 *     flag   : true ,
 *     values : [1,2,3]
 * } ;
 * trace( dump( object ) ) ;
 */
export default function dump( value , prettyprint=false , indent=0  , indentor="    " )
{
    indent = isNaN(indent) ? 0 : indent ;

    prettyprint = Boolean( prettyprint ) ;

    if( !indentor )
    {
        indentor = "    " ;
    }

    if( value === undefined )
    {
        return "undefined";
    }
    else if( value === null )
    {
        return "null";
    }
    else if( typeof(value) === "string" || value instanceof String )
    {
        return dumpString( value );
    }
    else if ( typeof(value) === "boolean" || value instanceof Boolean  )
    {
        return value ? "true" : "false";
    }
    else if( typeof(value) === "number" || value instanceof Number )
    {
        return value.toString() ;
    }
    else if( value instanceof Date )
    {
        return dumpDate( value );
    }
    else if( value instanceof Array )
    {
        return dumpArray( value , prettyprint, indent, indentor );
    }
    else if( value.constructor && value.constructor === Object )
    {
        return dumpObject( value , prettyprint, indent, indentor );
    }
    else if( "toSource" in value )
    {
        return value.toSource( indent );
    }
    else
    {
        return '<unknown>';
    }
}