
/*
 * weinre is available under *either* the terms of the modified BSD license *or* the
 * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
 * 
 * Copyright (c) 2010, 2011 IBM Corporation
 */

requireClass ../common/Weinre
requireClass ../target/Timeline

//-----------------------------------------------------------------------------
class Console

//-----------------------------------------------------------------------------
init
    var UsingRemote = false
    
    var RemoteConsole   = new Console()
    var OriginalConsole = window.console
    
    RemoteConsole.__original   = OriginalConsole
    OriginalConsole.__original = OriginalConsole
    
    var MessageSource = {
        HTML: 0,
        WML: 1,
        XML: 2,
        JS: 3,
        CSS: 4,
        Other: 5
    }
    
    var MessageType = {
        Log: 0,
        Object: 1,
        Trace: 2,
        StartGroup: 3,
        StartGroupCollapsed: 4,
        EndGroup: 5,
        Assert: 6,
        UncaughtException: 7,
        Result: 8
    }
    
    var MessageLevel = {
        Tip: 0,
        Log: 1,
        Warning: 2,
        Error: 3,
        Debug: 4
    }

//-----------------------------------------------------------------------------
static getter original
    return OriginalConsole

//-----------------------------------------------------------------------------
static method useRemote(value)
    if (arguments.length == 0) return UsingRemote
    
    var oldValue = UsingRemote
    
    UsingRemote = !!value
    
    if (UsingRemote) 
        window.console = RemoteConsole
    else
        window.console = OriginalConsole
        
    return oldValue

//-----------------------------------------------------------------------------
method _generic(level, messageParts)
    
    var message = messageParts[0]
    
    var parameters = []
    for (var i=0; i<messageParts.length; i++) {
        parameters.push(
            Weinre.injectedScript.wrapObjectForConsole(messageParts[i], true)
        )
    }
    
    var payload = {
        source:      MessageSource.JS,
        type:        MessageType.Log,
        level:       level,
        message:     message,
        parameters:  parameters
    }
    
    Weinre.wi.ConsoleNotify.addConsoleMessage(payload)

//-----------------------------------------------------------------------------
method log
    this._generic(MessageLevel.Log, [].slice.call(arguments)) 

//-----------------------------------------------------------------------------
method debug
    this._generic(MessageLevel.Debug, [].slice.call(arguments)) 

//-----------------------------------------------------------------------------
method error
    this._generic(MessageLevel.Error, [].slice.call(arguments)) 

//-----------------------------------------------------------------------------
method info
    this._generic(MessageLevel.Log, [].slice.call(arguments)) 

//-----------------------------------------------------------------------------
method warn
    this._generic(MessageLevel.Warning, [].slice.call(arguments)) 

//-----------------------------------------------------------------------------
method dir
    Weinre.notImplemented(arguments.callee.signature)

//-----------------------------------------------------------------------------
method dirxml
    Weinre.notImplemented(arguments.callee.signature)

//-----------------------------------------------------------------------------
method trace
    Weinre.notImplemented(arguments.callee.signature)
    
//-----------------------------------------------------------------------------
method assert(condition)
    Weinre.notImplemented(arguments.callee.signature)
    
//-----------------------------------------------------------------------------
method count
    Weinre.notImplemented(arguments.callee.signature)
    
//-----------------------------------------------------------------------------
method markTimeline(message)
    Timeline.addRecord_Mark(message)
    
//-----------------------------------------------------------------------------
method lastWMLErrorMessage
    Weinre.notImplemented(arguments.callee.signature)

//-----------------------------------------------------------------------------
method profile(title)
    Weinre.notImplemented(arguments.callee.signature)

//-----------------------------------------------------------------------------
method profileEnd(title)
    Weinre.notImplemented(arguments.callee.signature)

//-----------------------------------------------------------------------------
method time(title)
    Weinre.notImplemented(arguments.callee.signature)

//-----------------------------------------------------------------------------
method timeEnd(title)
    Weinre.notImplemented(arguments.callee.signature)

//-----------------------------------------------------------------------------
method group
    Weinre.notImplemented(arguments.callee.signature)

//-----------------------------------------------------------------------------
method groupCollapsed
    Weinre.notImplemented(arguments.callee.signature)

//-----------------------------------------------------------------------------
method groupEnd
    Weinre.notImplemented(arguments.callee.signature)
