
/*
 * 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
 */

requireClass ../common/Weinre
requireClass ../common/Native

//-----------------------------------------------------------------------------
class WiDOMStorageImpl

//-----------------------------------------------------------------------------
method getDOMStorageEntries(/*int*/ storageId, callback)
    var storageArea = _getStorageArea(storageId)
    
    if (!storageArea) {
        Weinre.logWarning(arguments.callee.signature + " passed an invalid storageId: " + storageId)
        return
    }
    
    var result = []
    
    var length = storageArea.length
    for (var i=0; i<length; i++) {
        var key = storageArea.key(i)
        var val = storageArea.getItem(key)
        
        result.push([key, val])    
    }
    
    if (callback) {
        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
    }

//-----------------------------------------------------------------------------
method setDOMStorageItem(/*int*/ storageId, /*string*/ key, /*string*/ value, callback)
    var storageArea = _getStorageArea(storageId)
    
    if (!storageArea) {
        Weinre.logWarning(arguments.callee.signature + " passed an invalid storageId: " + storageId)
        return
    }
    
    var result = true
    try {
        if (storageArea == window.localStorage) {
            Native.LocalStorage_setItem(key, value)
        }
        else if (storageArea == window.sessionStorage) {
            Native.SessionStorage_setItem(key, value)
        }
    }
    catch (e) {
        result = false
    }

    if (callback) {
        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
    }

//-----------------------------------------------------------------------------
method removeDOMStorageItem(/*int*/ storageId, /*string*/ key, callback)
    var storageArea = _getStorageArea(storageId)
    
    if (!storageArea) {
        Weinre.logWarning(arguments.callee.signature + " passed an invalid storageId: " + storageId)
        return
    }

    var result = true
    try {
        if (storageArea == window.localStorage) {
            Native.LocalStorage_removeItem(key)
        }
        else if (storageArea == window.sessionStorage) {
            Native.SessionStorage_removeItem(key)
        }
    }
    catch (e) {
        result = false
    }

    if (callback) {
        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
    }

    
//-----------------------------------------------------------------------------
function _getStorageArea(storageId)
    if (storageId == 1) {
        return window.localStorage
    }
    
    else if (storageId == 2) {
        return window.sessionStorage
    }
    
    return null

//-----------------------------------------------------------------------------
method initialize

    if (window.localStorage) {
        Weinre.wi.DOMStorageNotify.addDOMStorage({
            id:             1,
            host:           window.location.host,
            isLocalStorage: true
        })
        
        window.localStorage.setItem = function(key, value) {
            Native.LocalStorage_setItem(key, value)
            _storageEventHandler({storageArea: window.localStorage})
        }
        
        window.localStorage.removeItem = function(key) {
            Native.LocalStorage_removeItem(key)
            _storageEventHandler({storageArea: window.localStorage})
        }
        
        window.localStorage.clear = function() {
            Native.LocalStorage_clear()
            _storageEventHandler({storageArea: window.localStorage})
        }
    }
    
    if (window.sessionStorage) {
        Weinre.wi.DOMStorageNotify.addDOMStorage({
            id:             2,
            host:           window.location.host,
            isLocalStorage: false
        })
        
        window.sessionStorage.setItem = function(key, value) {
            Native.SessionStorage_setItem(key, value)
            _storageEventHandler({storageArea: window.sessionStorage})
        }
        
        window.sessionStorage.removeItem = function(key) {
            Native.SessionStorage_removeItem(key)
            _storageEventHandler({storageArea: window.sessionStorage})
        }
        
        window.sessionStorage.clear = function() {
            Native.SessionStorage_clear()
            _storageEventHandler({storageArea: window.sessionStorage})
        }
    }
    
    document.addEventListener("storage", _storageEventHandler, false)
    
//-----------------------------------------------------------------------------
function _storageEventHandler(event)
    var storageId
    
    if (event.storageArea == window.localStorage) {
        storageId = 1
    }
    
    else if (event.storageArea == window.sessionStorage) {
        storageId = 2
    }
    
    else {
        return
    }
    
    Weinre.wi.DOMStorageNotify.updateDOMStorage(storageId)
