/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @extends {WebInspector.Object}
 */
WebInspector.SnippetStorage = function(settingPrefix, namePrefix)
{
    this._snippets = {};

    this._lastSnippetIdentifierSetting = WebInspector.settings.createSetting(settingPrefix + "Snippets_lastIdentifier", 0);
    this._snippetsSetting = WebInspector.settings.createSetting(settingPrefix + "Snippets", []);
    this._namePrefix = namePrefix;

    this._loadSettings();
}

WebInspector.SnippetStorage.prototype = {
    get namePrefix()
    {
        return this._namePrefix;
    },

    _saveSettings: function()
    {
        var savedSnippets = [];
        for (var id in this._snippets)
            savedSnippets.push(this._snippets[id].serializeToObject());
        this._snippetsSetting.set(savedSnippets);
    },

    /**
     * @return {!Array.<!WebInspector.Snippet>}
     */
    snippets: function()
    {
        var result = [];
        for (var id in this._snippets)
            result.push(this._snippets[id]);
        return result;
    },

    /**
     * @param {string} id
     * @return {!WebInspector.Snippet}
     */
    snippetForId: function(id)
    {
        return this._snippets[id];
    },

    /**
     * @param {string} name
     * @return {?WebInspector.Snippet}
     */
    snippetForName: function(name)
    {
        var snippets = Object.values(this._snippets);
        for (var i = 0; i < snippets.length; ++i)
            if (snippets[i].name === name)
                return snippets[i];
        return null;
    },

    _loadSettings: function()
    {
        var savedSnippets = this._snippetsSetting.get();
        for (var i = 0; i < savedSnippets.length; ++i)
            this._snippetAdded(WebInspector.Snippet.fromObject(this, savedSnippets[i]));
    },

    /**
     * @param {!WebInspector.Snippet} snippet
     */
    deleteSnippet: function(snippet)
    {
        delete this._snippets[snippet.id];
        this._saveSettings();
    },

    /**
     * @return {!WebInspector.Snippet}
     */
    createSnippet: function()
    {
        var nextId = this._lastSnippetIdentifierSetting.get() + 1;
        var snippetId = String(nextId);
        this._lastSnippetIdentifierSetting.set(nextId);
        var snippet = new WebInspector.Snippet(this, snippetId);
        this._snippetAdded(snippet);
        this._saveSettings();
        return snippet;
    },

    /**
     * @param {!WebInspector.Snippet} snippet
     */
    _snippetAdded: function(snippet)
    {
        this._snippets[snippet.id] = snippet;
    },

    __proto__: WebInspector.Object.prototype
}

/**
 * @constructor
 * @extends {WebInspector.Object}
 * @param {!WebInspector.SnippetStorage} storage
 * @param {string} id
 * @param {string=} name
 * @param {string=} content
 */
WebInspector.Snippet = function(storage, id, name, content)
{
    this._storage = storage;
    this._id = id;
    this._name = name || storage.namePrefix + id;
    this._content = content || "";
}

/**
 * @param {!WebInspector.SnippetStorage} storage
 * @param {!Object} serializedSnippet
 * @return {!WebInspector.Snippet}
 */
WebInspector.Snippet.fromObject = function(storage, serializedSnippet)
{
    return new WebInspector.Snippet(storage, serializedSnippet.id, serializedSnippet.name, serializedSnippet.content);
}

WebInspector.Snippet.prototype = {
    /**
     * @return {string}
     */
    get id()
    {
        return this._id;
    },

    /**
     * @return {string}
     */
    get name()
    {
        return this._name;
    },

    set name(name)
    {
        if (this._name === name)
            return;

        this._name = name;
        this._storage._saveSettings();
    },

    /**
     * @return {string}
     */
    get content()
    {
        return this._content;
    },

    set content(content)
    {
        if (this._content === content)
            return;

        this._content = content;
        this._storage._saveSettings();
    },

    /**
     * @return {!Object}
     */
    serializeToObject: function()
    {
        var serializedSnippet = {};
        serializedSnippet.id = this.id;
        serializedSnippet.name = this.name;
        serializedSnippet.content = this.content;
        return serializedSnippet;
    },

    __proto__: WebInspector.Object.prototype
}
