
/*
 * 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 ./Ex
requireClass ./IDLTools
requireClass ./StackTrace

//-----------------------------------------------------------------------------
class Weinre
    throw new Ex(arguments, "this class is not intended to be instantiated")

//-----------------------------------------------------------------------------
init 
    var _notImplemented     = {}
    var _showNotImplemented = false
    var CSSProperties       = []
    var logger              = null

//-----------------------------------------------------------------------------
static method addIDLs(idls)
    IDLTools.addIDLs(idls)

//-----------------------------------------------------------------------------
static method addCSSProperties(cssProperties)
    CSSProperties = cssProperties

//-----------------------------------------------------------------------------
static method getCSSProperties
    return CSSProperties

//-----------------------------------------------------------------------------
static method deprecated()
    StackTrace.dump(arguments)
    
//-----------------------------------------------------------------------------
static method notImplemented(thing)
    if (_notImplemented[thing]) return
    
    _notImplemented[thing] = true
    
    if (!_showNotImplemented) return
    Weinre.logWarning(thing + " not implemented")

//-----------------------------------------------------------------------------
static method showNotImplemented()
    _showNotImplemented = true
    for (var key in _notImplemented) {
        Weinre.logWarning(key + " not implemented")
    }
    
//-----------------------------------------------------------------------------
static method logError(message)
    getLogger().logError(message)

//-----------------------------------------------------------------------------
static method logWarning(message)
    getLogger().logWarning(message)

//-----------------------------------------------------------------------------
static method logInfo(message)
    getLogger().logInfo(message)

//-----------------------------------------------------------------------------
static method logDebug(message)
    getLogger().logDebug(message)

//-----------------------------------------------------------------------------
function getLogger()
    if (logger) return logger
    
    if      (Weinre.client) logger = Weinre.WeinreClientCommands
    else if (Weinre.target) logger = Weinre.WeinreTargetCommands
    
    return logger
    