/*
 * Copyright (C) 2010, 2013-2015 Apple 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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

WI.ApplicationCacheFrameContentView = class ApplicationCacheFrameContentView extends WI.ContentView
{
    constructor(representedObject)
    {
        console.assert(representedObject instanceof WI.ApplicationCacheFrame);

        super(representedObject);

        this.element.classList.add("application-cache-frame");

        this._frame = representedObject.frame;

        this._emptyView = WI.createMessageTextView(WI.UIString("No Application Cache information available"), false);
        this._emptyView.classList.add("hidden");
        this.element.appendChild(this._emptyView);

        this._markDirty();

        var status = representedObject.status;
        this.updateStatus(status);

        WI.applicationCacheManager.addEventListener(WI.ApplicationCacheManager.Event.FrameManifestStatusChanged, this._updateStatus, this);
    }

    shown()
    {
        super.shown();

        this._maybeUpdate();
    }

    closed()
    {
        WI.applicationCacheManager.removeEventListener(null, null, this);

        super.closed();
    }

    saveToCookie(cookie)
    {
        cookie.type = WI.ContentViewCookieType.ApplicationCache;
        cookie.frame = this.representedObject.frame.url;
        cookie.manifest = this.representedObject.manifest.manifestURL;
    }

    get scrollableElements()
    {
        if (!this._dataGrid)
            return [];
        return [this._dataGrid.scrollContainer];
    }

    _maybeUpdate()
    {
        if (!this.visible || !this._viewDirty)
            return;

        this._update();
        this._viewDirty = false;
    }

    _markDirty()
    {
        this._viewDirty = true;
    }

    _updateStatus(event)
    {
        var frameManifest = event.data.frameManifest;
        if (frameManifest !== this.representedObject)
            return;

        console.assert(frameManifest instanceof WI.ApplicationCacheFrame);

        this.updateStatus(frameManifest.status);
    }

    updateStatus(status)
    {
        var oldStatus = this._status;
        this._status = status;

        if (this.visible && this._status === WI.ApplicationCacheManager.Status.Idle && (oldStatus === WI.ApplicationCacheManager.Status.UpdateReady || !this._resources))
            this._markDirty();

        this._maybeUpdate();
    }

    _update()
    {
        WI.applicationCacheManager.requestApplicationCache(this._frame, this._updateCallback.bind(this));
    }

    _updateCallback(applicationCache)
    {
        if (!applicationCache || !applicationCache.manifestURL) {
            delete this._manifest;
            delete this._creationTime;
            delete this._updateTime;
            delete this._size;
            delete this._resources;

            this._emptyView.classList.remove("hidden");

            if (this._dataGrid)
                this._dataGrid.element.classList.add("hidden");
            return;
        }

        // FIXME: are these variables needed anywhere else?
        this._manifest = applicationCache.manifestURL;
        this._creationTime = applicationCache.creationTime;
        this._updateTime = applicationCache.updateTime;
        this._size = applicationCache.size;
        this._resources = applicationCache.resources;

        if (!this._dataGrid)
            this._createDataGrid();

        this._populateDataGrid();
        this._dataGrid.autoSizeColumns(20, 80);
        this._dataGrid.element.classList.remove("hidden");

        this._emptyView.classList.add("hidden");
    }

    _createDataGrid()
    {
        var columns = {url: {}, type: {}, size: {}};

        columns.url.title = WI.UIString("Resource");
        columns.url.sortable = true;

        columns.type.title = WI.UIString("Type");
        columns.type.sortable = true;

        columns.size.title = WI.UIString("Size");
        columns.size.aligned = "right";
        columns.size.sortable = true;

        this._dataGrid = new WI.DataGrid(columns);
        this._dataGrid.addEventListener(WI.DataGrid.Event.SortChanged, this._sortDataGrid, this);

        this._dataGrid.sortColumnIdentifier = "url";
        this._dataGrid.sortOrder = WI.DataGrid.SortOrder.Ascending;
        this._dataGrid.createSettings("application-cache-frame-content-view");

        this.addSubview(this._dataGrid);
        this._dataGrid.updateLayout();
    }

    _sortDataGrid()
    {
        function numberCompare(columnIdentifier, nodeA, nodeB)
        {
            return nodeA.data[columnIdentifier] - nodeB.data[columnIdentifier];
        }
        function localeCompare(columnIdentifier, nodeA, nodeB)
        {
             return (nodeA.data[columnIdentifier] + "").extendedLocaleCompare(nodeB.data[columnIdentifier] + "");
        }

        var comparator;
        switch (this._dataGrid.sortColumnIdentifier) {
            case "type": comparator = localeCompare.bind(this, "type"); break;
            case "size": comparator = numberCompare.bind(this, "sizeNumber"); break;
            case "url":
            default: comparator = localeCompare.bind(this, "url"); break;
        }

        this._dataGrid.sortNodes(comparator);
    }

    _populateDataGrid()
    {
        this._dataGrid.removeChildren();

        for (var resource of this._resources) {
            var data = {
                url: resource.url,
                type: resource.type,
                size: Number.bytesToString(resource.size),
                sizeNumber: resource.size,
            };
            var node = new WI.DataGridNode(data);
            this._dataGrid.appendChild(node);
        }
    }

    _deleteButtonClicked(event)
    {
        if (!this._dataGrid || !this._dataGrid.selectedNode)
            return;

        // FIXME: Delete Button semantics are not yet defined. (Delete a single, or all?)
        this._deleteCallback(this._dataGrid.selectedNode);
    }

    _deleteCallback(node)
    {
        // FIXME: Should we delete a single (selected) resource or all resources?
        // InspectorBackend.deleteCachedResource(...)
        // this._update();
    }
};
