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

        view._didMoveToParent(null);

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

    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) {
            console.assert(WI.setReentrantCheck(this, "initialLayout"), "ERROR: calling `initialLayout` while already in it", this);
            this.initialLayout();
            this._didInitialLayout = true;
        }

        if (this._layoutReason === WI.View.LayoutReason.Resize || isInitialLayout) {
            console.assert(WI.setReentrantCheck(this, "sizeDidChange"), "ERROR: calling `sizeDidChange` while already in it", this);
            this.sizeDidChange();
            console.assert(WI.clearReentrantCheck(this, "sizeDidChange"), "ERROR: missing return from `sizeDidChange`", this);
        }

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

        console.assert(WI.setReentrantCheck(this, "layout"), "ERROR: calling `layout` while already in it", this);
        this.layout();
        console.assert(WI.clearReentrantCheck(this, "layout"), "ERROR: missing return from `layout`", this);

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

        console.assert(WI.setReentrantCheck(this, "didLayoutSubtree"), "ERROR: calling `didLayoutSubtree` while already in it", this);
        this.didLayoutSubtree();
        console.assert(WI.clearReentrantCheck(this, "didLayoutSubtree"), "ERROR: missing return from `didLayoutSubtree`", this);
    }

    _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;
