import { IGanttOwner } from "../../Interfaces/IGanttOwner";
import { DateRange } from "../../Model/WorkingTime/DateRange";
import { GanttView } from "../GanttView";
import { ViewType } from "../Helpers/Enums";
import { RenderHelper } from "../Render/RenderHelper";
import { Settings } from "../Settings/Settings";

export class GanttViewApi {
    private _ganttView: GanttView;
    private maxZoom: number = 3;
    constructor(ganttView: GanttView) {
        this._ganttView = ganttView;
    }

    protected get currentZoom(): number {
        return this._ganttView.currentZoom;
    }

    protected set currentZoom(value: number) {
        this._ganttView.currentZoom = value;
    }

    protected get renderHelper(): RenderHelper {
        return this._ganttView.renderHelper;
    }

    protected getTaskAreaContainerWidth(): number {
        return this.renderHelper.getTaskAreaContainerWidth();
    }

    protected updateTickSizeWidth(): void {
        this._ganttView.updateTickSizeWidth();
    }

    protected get settings(): Settings {
        return this._ganttView.settings;
    }

    protected resetAndUpdate(): void {
        this._ganttView.resetAndUpdate();
    }

    protected scrollToDateCore(date: Date, addLeftPos: number): void {
        this._ganttView.scrollToDateCore(date, addLeftPos);
    }

    protected get ganttOwner(): IGanttOwner {
        return this._ganttView.ganttOwner;
    }

    protected scrollLeftByViewType(): void {
        this._ganttView.scrollLeftByViewType();
    }

    protected get dataRange(): DateRange {
        return this._ganttView.dataRange;
    }

    protected calculateAutoViewType(startDate, endDate): ViewType {
        return this._ganttView.calculateAutoViewType(startDate, endDate);
    }

    zoomIn(leftPos: number = this.getTaskAreaContainerWidth() / 2): void {
        const targetDate = this.renderHelper.getTargetDateByPos(leftPos);
        const viewTypeRangeStart = this.settings.viewTypeRange.min;
        if(this.currentZoom < this.maxZoom) {
            this.currentZoom++;
            this.updateTickSizeWidth();
            this.resetAndUpdate();
        }
        else if(this.settings.viewType > viewTypeRangeStart) {
            this.currentZoom = 1;
            this.setViewType(this.settings.viewType - 1, false);
        }
        this.scrollToDateCore(targetDate, -leftPos);
    }
    zoomOut(leftPos: number = this.renderHelper.getTaskAreaContainerWidth() / 2): void {
        const targetDate = this.renderHelper.getTargetDateByPos(leftPos);
        const viewTypeRangeEnd = this.settings.viewTypeRange.max;
        if(this.currentZoom > 1) {
            this.currentZoom--;
            this.updateTickSizeWidth();
            this.resetAndUpdate();
        }
        else if(this.settings.viewType < viewTypeRangeEnd) {
            this.currentZoom = this.maxZoom;
            this.setViewType(this.settings.viewType + 1, false);
        }
        this.scrollToDateCore(targetDate, -leftPos);
    }

    setViewType(viewType: ViewType, autoPositioning: boolean = true): void {
        if(viewType == undefined)
            viewType = this.calculateAutoViewType(this.dataRange.start, this.dataRange.end);

        if(this.settings.viewType !== viewType) {
            this.settings.viewType = viewType;
            this.updateTickSizeWidth();
            this.resetAndUpdate();
            if(autoPositioning)
                this.scrollLeftByViewType();
            if(this.ganttOwner.UpdateGanttViewType)
                this.ganttOwner.UpdateGanttViewType(viewType);
        }
    }
    setViewTypeRange(min: ViewType, max: ViewType): void {
        if(min !== undefined)
            this.settings.viewTypeRange.min = Math.min(min, max);
        if(max !== undefined)
            this.settings.viewTypeRange.max = Math.max(min, max);

        const viewTypeRangeMin = this.settings.viewTypeRange.min;
        const viewTypeRangeMax = this.settings.viewTypeRange.max;
        const viewType = this.settings.viewType;

        if(viewTypeRangeMin > viewType)
            this.setViewType(viewTypeRangeMin);
        else if(viewTypeRangeMax < viewType)
            this.setViewType(viewTypeRangeMax);
    }

}
