
/*
 * 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) 2011 IBM Corporation
 */

//-----------------------------------------------------------------------------
class Native

//-----------------------------------------------------------------------------
init
    Native.original = {}

    Native.original.clearInterval             = window.clearInterval
    Native.original.clearTimeout              = window.clearTimeout
    Native.original.setTimeout                = window.setTimeout
    Native.original.setInterval               = window.setInterval
    Native.original.XMLHttpRequest            = window.XMLHttpRequest
    Native.original.XMLHttpRequest_open       = window.XMLHttpRequest.prototype.open
    Native.original.LocalStorage_setItem      = window.localStorage   ? window.localStorage.setItem      : null
    Native.original.LocalStorage_removeItem   = window.localStorage   ? window.localStorage.removeItem   : null
    Native.original.LocalStorage_clear        = window.localStorage   ? window.localStorage.clear        : null
    Native.original.SessionStorage_setItem    = window.sessionStorage ? window.sessionStorage.setItem    : null
    Native.original.SessionStorage_removeItem = window.sessionStorage ? window.sessionStorage.removeItem : null
    Native.original.SessionStorage_clear      = window.sessionStorage ? window.sessionStorage.clear      : null

    Native.clearInterval             = function() { return Native.original.clearInterval.apply( window, [].slice.call(arguments))}
    Native.clearTimeout              = function() { return Native.original.clearTimeout.apply(  window, [].slice.call(arguments))}
    Native.setInterval               = function() { return Native.original.setInterval.apply(   window, [].slice.call(arguments))}
    Native.setTimeout                = function() { return Native.original.setTimeout.apply(    window, [].slice.call(arguments))}
    Native.XMLHttpRequest            = function() { return new Native.original.XMLHttpRequest()}
    Native.XMLHttpRequest_open       = function() { return Native.original.XMLHttpRequest_open.apply(this, [].slice.call(arguments))}
    Native.LocalStorage_setItem      = function() { return Native.original.LocalStorage_setItem.apply(      window.localStorage,   [].slice.call(arguments))}
    Native.LocalStorage_removeItem   = function() { return Native.original.LocalStorage_removeItem.apply(   window.localStorage,   [].slice.call(arguments))}
    Native.LocalStorage_clear        = function() { return Native.original.LocalStorage_clear.apply(        window.localStorage,   [].slice.call(arguments))}
    Native.SessionStorage_setItem    = function() { return Native.original.SessionStorage_setItem.apply(    window.sessionStorage, [].slice.call(arguments))}
    Native.SessionStorage_removeItem = function() { return Native.original.SessionStorage_removeItem.apply( window.sessionStorage, [].slice.call(arguments))}
    Native.SessionStorage_clear      = function() { return Native.original.SessionStorage_clear.apply(      window.sessionStorage, [].slice.call(arguments))}
