/**
 * @license
 * Copyright 2023 Tyler Technologies, Inc. 
 * License: Apache-2.0
 */
import { isDefined } from '@tylertech/forge-core';
import { VIEW_SWITCHER_CONSTANTS, ViewAnimationDirection, ViewSwitcherAnimationType } from './view-switcher-constants';
export class ViewSwitcherFoundation {
    constructor(_adapter) {
        this._adapter = _adapter;
        this._viewCount = 0;
        this._viewIndex = 0;
        this._animationType = ViewSwitcherAnimationType.None;
        this._viewsChangedListener = () => this._onViewsChanged();
    }
    initialize() {
        this._viewCount = this._adapter.getViewCount();
        this._adapter.startViewObserver(this._viewsChangedListener);
        this._adapter.setAnimationType(this._animationType);
        if (this._viewCount) {
            this._initializeAnimationType();
        }
    }
    disconnect() {
        this._adapter.stopViewObserver();
    }
    _initializeAnimationType() {
        switch (this._animationType) {
            case ViewSwitcherAnimationType.Slide:
                this._adapter.initializeSlideViews(this._viewIndex);
                break;
            case ViewSwitcherAnimationType.Fade:
                this._adapter.initializeFadeViews(this._viewIndex);
                break;
            case ViewSwitcherAnimationType.None:
            default:
                this._adapter.hideInactiveViews(this._viewIndex);
                break;
        }
    }
    _onViewsChanged() {
        this._viewCount = this._adapter.getViewCount();
        if (this._viewCount === 0) {
            this._viewIndex = 0;
        }
        if (this._viewCount) {
            this._initializeAnimationType();
        }
        // If the view index is higher than the number of views then we need to reset it
        if (this._viewCount > 0 && this._viewIndex >= this._viewCount) {
            const currIndex = this._viewIndex;
            this._viewIndex = this._viewCount > 0 ? this._viewCount - 1 : 0;
            this._goToView(currIndex, this._viewCount);
        }
    }
    async _goToView(fromIndex, viewCount) {
        this._viewCount = !isDefined(viewCount) ? this._adapter.getViewCount() : viewCount;
        // If the index that we're trying to transition to is out of range, or is the same index, then we ignore the transition
        const isValidIndex = this._viewIndex >= 0 && this._viewIndex <= this._viewCount - 1;
        if (!isValidIndex || fromIndex === this._clampedViewIndex(this._viewIndex, this._viewCount)) {
            return;
        }
        switch (this._animationType) {
            case ViewSwitcherAnimationType.Slide:
                const animationDirection = this._viewIndex > fromIndex ? ViewAnimationDirection.Left : ViewAnimationDirection.Right;
                await this._adapter.transitionToView(fromIndex, this._viewIndex, ViewSwitcherAnimationType.Slide, animationDirection);
                this._adapter.initializeSlideViews(this._viewIndex);
                break;
            case ViewSwitcherAnimationType.Fade:
                await this._adapter.transitionToView(fromIndex, this._viewIndex, ViewSwitcherAnimationType.Fade);
                this._adapter.initializeFadeViews(this._viewIndex);
                break;
            case ViewSwitcherAnimationType.None:
            default:
                this._adapter.setActiveView(this._viewIndex);
                break;
        }
    }
    _clampedViewIndex(viewIndex, viewCount) {
        if (viewIndex < 0) {
            viewIndex = 0;
        }
        else if (viewIndex > viewCount - 1) {
            viewIndex = viewCount > 0 ? viewCount - 1 : 0;
        }
        return viewIndex;
    }
    next() {
        this.index++;
    }
    previous() {
        this.index--;
    }
    goToStart() {
        this.index = 0;
    }
    goToEnd() {
        this.index = this._viewCount - 1;
    }
    get index() {
        return this._viewIndex;
    }
    set index(value) {
        if (this._viewIndex !== value) {
            const currIndex = this._viewIndex;
            this._viewIndex = value;
            this._goToView(currIndex);
            this._adapter.setHostAttribute(VIEW_SWITCHER_CONSTANTS.attributes.INDEX, this._viewIndex.toString());
        }
    }
    get animationType() {
        return this._animationType;
    }
    set animationType(value) {
        if (this._animationType !== value) {
            this._animationType = value;
            this._initializeAnimationType();
            this._adapter.setAnimationType(this._animationType);
            this._adapter.setHostAttribute(VIEW_SWITCHER_CONSTANTS.attributes.ANIMATION_TYPE, this._animationType);
        }
    }
}
