/*
 * Copyright (C) 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.View = class View extends WI.Object
{
    constructor(element)
    {
        super();

        this._element = element || document.createElement("div");
        this._element.__view = this;
        this._parentView = null;
        this._subviews = [];
        this._dirty = false;
        this._dirtyDescendantsCount = 0;
        this._isAttachedToRoot = false;
        this._layoutReason = null;
        this._didInitialLayout = false;
    }

    // Static

    static fromElement(element)
    {
        if (!element || !(element instanceof HTMLElement))
            return null;

        if (element.__view instanceof WI.View)
            return element.__view;
        return null;
    }

    static rootView()
    {
        if (!WI.View._rootView) {
            // Since the root view is attached by definition, it does not go through the
            // normal view attachment process. Simply mark it as attached.
            WI.View._rootView = new WI.View(document.body);
            WI.View._rootView._isAttachedToRoot = true;
        }

        return WI.View._rootView;
    }

    // Public

    get element() { return this._element; }
    get layoutPending() { return this._dirty; }
    get parentView() { return this._parentView; }
    get subviews() { return this._subviews; }
    get isAttached() { return this._isAttachedToRoot; }

    isDescendantOf(view)
    {
        let parentView = this._parentView;
        while (parentView) {
            if (parentView === view)
                return true;
            parentView = parentView.parentView;
        }

        return false;
    }

    addSubview(view)
    {
        this.insertSubviewBefore(view, null);
    }

    insertSubviewBefore(view, referenceView)
    {
        console.assert(view instanceof WI.View);
        console.assert(!referenceView || referenceView instanceof WI.View);
        console.assert(view !== WI.View._rootView, "Root view cannot be a subview.");

        if (this._subviews.includes(view)) {
            console.assert(false, "Cannot add view that is already a subview.", view);
            return;
        }

        const beforeIndex = referenceView ? this._subviews.indexOf(referenceView) : this._subviews.length;
        if (beforeIndex === -1) {
            console.assert(false, "Cannot insert view. Invalid reference view.", referenceView);
            return;
        }

        this._subviews.insertAtIndex(view, beforeIndex);

        console.assert(!view.element.parentNode || this._element.contains(view.element.parentNode), "Subview DOM element must be a descendant of the parent view element.");
        if (!view.element.parentNode)
            this._element.insertBefore(view.element, referenceView ? referenceView.element : null);

        view._didMoveToParent(this);
    }

    removeSubview(view)
    {
        console.assert(view instanceof WI.View);
        console.assert(this._element.contains(view.element), "Subview DOM element must be a child of the parent view element.");

        let index = this._subviews.lastIndexOf(view);
        if (index === -1) {
            console.assert(false, "Cannot remove view which isn't a subview.", view);
            return;
        }

        this._subviews.splice(index, 1);
        view.element.remove();

        view._didMoveToParent(null);
    }

    removeAllSubviews()
    {
        for (let subview of this._subviews)
            subview._didMoveToParent(null);

        this._subviews = [];
        this._element.removeChildren();
    }

    replaceSubview(oldView, newView)
    {
        console.assert(oldView !== newView, "Cannot replace subview with itself.");
        if (oldView === newView)
            return;

        this.insertSubviewBefore(newView, oldView);
        this.removeSubview(oldView);
    }

    updateLayout(layoutReason)
    {
        this.cancelLayout();

        this._setLayoutReason(layoutReason);
        this._layoutSubtree();
    }

    updateLayoutIfNeeded(layoutReason)
    {
        if (!this._dirty && this._didInitialLayout)
            return;

        this.updateLayout(layoutReason);
    }

    needsLayout(layoutReason)
    {
        this._setLayoutReason(layoutReason);

        if (this._dirty)
            return;

        WI.View._scheduleLayoutForView(this);
    }

    cancelLayout()
    {
        WI.View._cancelScheduledLayoutForView(this);
    }

    // Protected

    get layoutReason() { return this._layoutReason; }
    get didInitialLayout() { return this._didInitialLayout; }

    attached()
    {
        // Implemented by subclasses.
    }

    detached()
    {
        // Implemented by subclasses.
    }

    initialLayout()
    {
        // Implemented by subclasses.

        // Called once when the view is shown for the first time.
        // Views with complex DOM subtrees should create UI elements in
        // initialLayout rather than at construction time.
    }

    layout()
    {
        // Implemented by subclasses.

        // Not responsible for recursing to child views.
        // Should not be called directly; use updateLayout() instead.
    }

    didLayoutSubtree()
    {
        // Implemented by subclasses.

        // Called after the view and its entire subtree have finished layout.
    }

    sizeDidChange()
    {
        // Implemented by subclasses.

        // Called after initialLayout, and before layout.
    }

    // Private

    _didMoveToParent(parentView)
    {
        this._parentView = parentView;

        let isAttachedToRoot = this.isDescendantOf(WI.View._rootView);
        this._didMoveToWindow(isAttachedToRoot);

        if (!this._parentView)
            return;

        let pendingLayoutsCount = this._dirtyDescendantsCount;
        if (this._dirty)
            pendingLayoutsCount++;

        let view = this._parentView;
        while (view) {
            view._dirtyDescendantsCount += pendingLayoutsCount;
            view = view.parentView;
        }
    }

    _didMoveToWindow(isAttachedToRoot)
    {
        if (this._isAttachedToRoot === isAttachedToRoot)
            return;

        this._isAttachedToRoot = isAttachedToRoot;
        if (this._isAttachedToRoot) {
            WI.View._scheduleLayoutForView(this);
            this.attached();
        } else {
            if (this._dirty)
                this.cancelLayout();
            this.detached();
        }

        for (let view of this._subviews)
            view._didMoveToWindow(isAttachedToRoot);
    }

    _layoutSubtree()
    {
        this._dirty = false;
        this._dirtyDescendantsCount = 0;
        let isInitialLayout = !this._didInitialLayout;

        if (isInitialLayout) {
            this.initialLayout();
            this._didInitialLayout = true;
        }

        if (this._layoutReason === WI.View.LayoutReason.Resize || isInitialLayout)
            this.sizeDidChange();

        let savedLayoutReason = this._layoutReason;
        if (isInitialLayout) {
            // The initial layout should always be treated as dirty.
            this._setLayoutReason();
        }

        this.layout();

        // Ensure that the initial layout override doesn't affects to subviews.
        this._layoutReason = savedLayoutReason;

        if (WI.settings.debugEnableLayoutFlashing.value)
            this._drawLayoutFlashingOutline(isInitialLayout);

        for (let view of this._subviews) {
            view._setLayoutReason(this._layoutReason);
            view._layoutSubtree();
        }

        this._layoutReason = null;

        this.didLayoutSubtree();
    }

    _setLayoutReason(layoutReason)
    {
        this._layoutReason = layoutReason || WI.View.LayoutReason.Dirty;
    }

    _drawLayoutFlashingOutline(isInitialLayout)
    {
        if (this._layoutFlashingTimeout)
            clearTimeout(this._layoutFlashingTimeout);
        else
            this._layoutFlashingPreviousOutline = this._element.style.outline;

        let hue = isInitialLayout ? 20 : 40;
        this._element.style.outline = `1px solid hsla(${hue}, 100%, 51%, 0.8)`;

        this._layoutFlashingTimeout = setTimeout(() => {
            if (this._element)
                this._element.style.outline = this._layoutFlashingPreviousOutline;

            this._layoutFlashingTimeout = undefined;
            this._layoutFlashingPreviousOutline = null;
        }, 500);
    }

    // Layout controller logic

    static _scheduleLayoutForView(view)
    {
        view._dirty = true;

        let parentView = view.parentView;
        while (parentView) {
            parentView._dirtyDescendantsCount++;
            parentView = parentView.parentView;
        }

        if (!view._isAttachedToRoot)
            return;

        if (WI.View._scheduledLayoutUpdateIdentifier)
            return;

        WI.View._scheduledLayoutUpdateIdentifier = requestAnimationFrame(WI.View._visitViewTreeForLayout);
    }

    static _cancelScheduledLayoutForView(view)
    {
        let cancelledLayoutsCount = view._dirtyDescendantsCount;
        if (view.layoutPending)
            cancelledLayoutsCount++;

        let parentView = view.parentView;
        while (parentView) {
            parentView._dirtyDescendantsCount = Math.max(0, parentView._dirtyDescendantsCount - cancelledLayoutsCount);
            parentView = parentView.parentView;
        }

        view._dirty = false;

        if (!WI.View._scheduledLayoutUpdateIdentifier)
            return;

        let rootView = WI.View._rootView;
        if (!rootView || rootView._dirtyDescendantsCount)
            return;

        // No views need layout, so cancel the pending requestAnimationFrame.
        cancelAnimationFrame(WI.View._scheduledLayoutUpdateIdentifier);
        WI.View._scheduledLayoutUpdateIdentifier = undefined;
    }

    static _visitViewTreeForLayout()
    {
        console.assert(WI.View._rootView, "Cannot layout view tree without a root.");

        WI.View._scheduledLayoutUpdateIdentifier = undefined;

        let views = [WI.View._rootView];
        while (views.length) {
            let view = views.shift();
            if (view.layoutPending)
                view._layoutSubtree();
            else if (view._dirtyDescendantsCount) {
                views.pushAll(view.subviews);
                view._dirtyDescendantsCount = 0;
            }
        }
    }
};

WI.View.LayoutReason = {
    Dirty: Symbol("layout-reason-dirty"),
    Resize: Symbol("layout-reason-resize")
};

WI.View._rootView = null;
WI.View._scheduledLayoutUpdateIdentifier = undefined;
