
class ChartsPage extends PageWithHeading {
    constructor(toolbar)
    {
        console.assert(toolbar instanceof ChartsToolbar);
        super('Charts', toolbar);
        this._paneList = [];
        this._paneListChanged = false;
        this._mainDomain = null;
        this._currentRepositoryId = null;

        toolbar.setAddPaneCallback(this.insertPaneAfter.bind(this));
    }

    routeName() { return 'charts'; }

    static createStateForDashboardItem(platformId, metricId, startTime)
    {
        var state = {paneList: [[platformId, metricId]], since: startTime};
        return state;
    }

    static createDomainForAnalysisTask(task)
    {
        var diff = (task.endTime() - task.startTime()) * 0.1;
        return [task.startTime() - diff, task.endTime() + diff];
    }

    static createStateForAnalysisTask(task)
    {
        var domain = this.createDomainForAnalysisTask(task);
        var state = {
            paneList: [[task.platform().id(), task.metric().id()]],
            since: Math.round(task.startTime() - (Date.now() - task.startTime()) * 0.1),
            zoom: domain,
        };
        return state;
    }

    static createStateForConfigurationList(configurationList, startTime)
    {
        console.assert(configurationList instanceof Array);
        var state = {paneList: configurationList};
        return state;
    }

    open(state)
    {
        this.toolbar().setNumberOfDaysCallback(this.setNumberOfDaysFromToolbar.bind(this));
        super.open(state);
    }

    serializeState()
    {
        var state = {since: this.toolbar().startTime()};
        var serializedPaneList = [];
        for (var pane of this._paneList)
            serializedPaneList.push(pane.serializeState());

        if (this._mainDomain)
            state['zoom'] = this._mainDomain;
        if (serializedPaneList.length)
            state['paneList'] = serializedPaneList;

        var repository = this._currentRepositoryId;
        if (repository)
            state['repository'] = this._currentRepositoryId;

        return state;
    }

    updateFromSerializedState(state, isOpen)
    {
        var paneList = [];
        if (state.paneList instanceof Array)
            paneList = state.paneList;

        var newPaneList = this._updateChartPanesFromSerializedState(paneList);
        if (newPaneList) {
            this._paneList = newPaneList;
            this._paneListChanged = true;
            this.enqueueToRender();
        }

        this._updateDomainsFromSerializedState(state);

        this._currentRepositoryId = parseInt(state['repository']);
        var currentRepository = Repository.findById(this._currentRepositoryId);

        console.assert(this._paneList.length == paneList.length);
        for (var i = 0; i < this._paneList.length; i++) {
            this._paneList[i].updateFromSerializedState(state.paneList[i], isOpen);
            this._paneList[i].setOpenRepository(currentRepository);
        }
    }

    _updateDomainsFromSerializedState(state)
    {
        var since = parseFloat(state.since);
        var zoom = state.zoom;
        if (typeof(zoom) == 'string' && zoom.indexOf('-'))
            zoom = zoom.split('-')
        if (zoom instanceof Array && zoom.length >= 2)
            zoom = zoom.map(function (value) { return parseFloat(value); });

        if (zoom && since)
            since = Math.min(zoom[0], since);
        else if (zoom)
            since = zoom[0] - (zoom[1] - zoom[0]) / 2;

        this.toolbar().setStartTime(since);
        this.toolbar().enqueueToRender();

        this._mainDomain = zoom || null;

        this._updateOverviewDomain();
        this._updateMainDomain();
    }

    _updateChartPanesFromSerializedState(paneList)
    {
        var paneMap = {}
        for (var pane of this._paneList)
            paneMap[pane.platformId() + '-' + pane.metricId()] = pane;

        var newPaneList = [];
        var createdNewPane = false;
        for (var paneInfo of paneList) {
            var platformId = parseInt(paneInfo[0]);
            var metricId = parseInt(paneInfo[1]);
            var existingPane = paneMap[platformId + '-' + metricId];
            if (existingPane)
                newPaneList.push(existingPane);
            else {
                newPaneList.push(new ChartPane(this, platformId, metricId));
                createdNewPane = true;
            }
        }

        if (createdNewPane || newPaneList.length !== this._paneList.length)
            return newPaneList;

        for (var i = 0; i < newPaneList.length; i++) {
            if (newPaneList[i] != this._paneList[i])
                return newPaneList;
        }

        return null;
    }

    setNumberOfDaysFromToolbar(numberOfDays, shouldUpdateState)
    {
        this.toolbar().setNumberOfDays(numberOfDays, true);
        this.toolbar().enqueueToRender();
        this._updateOverviewDomain();
        this._updateMainDomain();
        if (shouldUpdateState)
            this.scheduleUrlStateUpdate();
    }

    setMainDomainFromOverviewSelection(domain, originatingPane, shouldUpdateState)
    {
        this._mainDomain = domain;
        this._updateMainDomain(originatingPane);
        if (shouldUpdateState)
            this.scheduleUrlStateUpdate();
    }

    setMainDomainFromZoom(selection, originatingPane)
    {
        this._mainDomain = selection;
        this._updateMainDomain(originatingPane);
        this.scheduleUrlStateUpdate();
    }

    mainChartSelectionDidChange(pane, shouldUpdateState)
    {
        if (shouldUpdateState)
            this.scheduleUrlStateUpdate();
    }

    mainChartIndicatorDidChange(pane, shouldUpdateState)
    {
        if (shouldUpdateState)
            this.scheduleUrlStateUpdate();
    }

    graphOptionsDidChange(pane)
    {
        this.scheduleUrlStateUpdate();
    }

    setOpenRepository(repository)
    {
        this._currentRepositoryId = repository ? repository.id() : null;
        for (var pane of this._paneList)
            pane.setOpenRepository(repository);
        this.scheduleUrlStateUpdate();
    }

    _updateOverviewDomain()
    {
        var startTime = this.toolbar().startTime();
        var endTime = this.toolbar().endTime();
        for (var pane of this._paneList)
            pane.setOverviewDomain(startTime, endTime);
    }

    _updateMainDomain(originatingPane)
    {
        var startTime = this.toolbar().startTime();
        var endTime = this.toolbar().endTime();
        if (this._mainDomain) {
            startTime = this._mainDomain[0];
            endTime = this._mainDomain[1];
        }

        for (var pane of this._paneList) {
            pane.setMainDomain(startTime, endTime);
            if (pane != originatingPane) // Don't mess up the selection state.
                pane.setOverviewSelection(this._mainDomain);
        }
    }

    closePane(pane)
    {
        var index = this._paneList.indexOf(pane);
        console.assert(index >= 0);
        this._paneList.splice(index, 1);
        this._didMutatePaneList(false);
    }

    insertPaneAfter(platform, metric, referencePane)
    {
        var newPane = new ChartPane(this, platform.id(), metric.id());
        if (referencePane) {
            var index = this._paneList.indexOf(referencePane);
            console.assert(index >= 0);
            this._paneList.splice(index + 1, 0, newPane);
        } else
            this._paneList.unshift(newPane);
        this._didMutatePaneList(true);
    }

    alternatePlatforms(platform, metric)
    {
        var existingPlatforms = {};
        for (var pane of this._paneList) {
            if (pane.metricId() == metric.id())   
                existingPlatforms[pane.platformId()] = true;
        }

        return metric.platforms().filter(function (platform) {
            return !existingPlatforms[platform.id()];
        });
    }

    insertBreakdownPanesAfter(platform, metric, referencePane)
    {
        console.assert(referencePane);
        var childMetrics = metric.childMetrics();

        var index = this._paneList.indexOf(referencePane);
        console.assert(index >= 0);
        var args = [index + 1, 0];

        for (var metric of childMetrics)
            args.push(new ChartPane(this, platform.id(), metric.id()));

        this._paneList.splice.apply(this._paneList, args);
        this._didMutatePaneList(true);
    }

    canBreakdown(platform, metric)
    {
        var childMetrics = metric.childMetrics();
        if (!childMetrics.length)
            return false;

        var existingMetrics = {};
        for (var pane of this._paneList) {
            if (pane.platformId() == platform.id())
                existingMetrics[pane.metricId()] = true;
        }

        for (var metric of childMetrics) {
            if (!existingMetrics[metric.id()])
                return true;
        }

        return false;
    }

    _didMutatePaneList(addedNewPane)
    {
        this._paneListChanged = true;
        if (addedNewPane) {
            this._updateOverviewDomain();
            this._updateMainDomain();
        }
        this.enqueueToRender();
        this.scheduleUrlStateUpdate();
    }

    render()
    {
        super.render();

        if (this._paneListChanged)
            this.renderReplace(this.content().querySelector('.pane-list'), this._paneList);

        for (var pane of this._paneList)
            pane.enqueueToRender();

        this._paneListChanged = false;
    }

    static htmlTemplate()
    {
        return `<div class="pane-list"></div>`;
    }

}
