Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
11 kB
2
Indexable
Never
import { TypeDialogModel } from 'nemo-utils';
import { i18n } from 'ngx-translate-core';
import { ItemAdd } from 'projects/libraries/i18n-libraries/ngx-poeditor/dist/dist';
import { EventBus, log, subscribe, subscribeToType } from 'services-lib';

import { FileNameTable } from '../constants/file-name-table';
import { NsiImageExporterConstants } from '../constants/nsi-image-exporter-constants';
import { BaseModelContainer } from '../core/model-container/base/base-model-container';
import { NSIImagesManager } from '../core/model-container/managers/nsi-images-manager';
import { NsiModelContainer } from '../core/model-container/nsi-model-container';
import { BaseChangeEventType } from '../events/base/base-change-event-type';
import { ChangesSavedOkEvent } from '../events/edit-images-events/changes-saved-ok-event';
import { NoChangesEvent, NoUndoneChangesEvent } from '../events/edit-images-events/no-changes-event';
import { RedoChangeEvent } from '../events/edit-images-events/redo-changes-event';
import { SaveDocumentCloudEvent } from '../events/edit-images-events/save-document-cloud-event';
import { UndoChangeEvent } from '../events/edit-images-events/undo-changes-event';
import { UnsavedChangesEvent } from '../events/edit-images-events/unsaved-changes-event';
import { Change2DModelEvent } from '../events/global-events/change-2d-model-event';
import { ModelSupplyEvent } from '../events/global-events/model-supply-event';
import { NMInfoXmlManagerEvent } from '../events/nm-data-events/nm-info-xml-manager.event';
import { NMMainXmlManagerEvent } from '../events/nm-data-events/nm-main-xml-manager.event';
import { SetProgressIndicatorVisibleEvent } from '../events/set-events/set-progress-indicator-visible-event';
import { ShowMessageEvent } from '../events/show-events/show-message-event';
import { ChangesManager } from './changes/changes-manager';
import { ProvidedDocument } from './document-provider/provided-document';
import { ExporterManager } from './exporters/exporter-manager';
import { NsiImageExporter } from './exporters/nsi-image-exporter';
import { XmlExporter } from './exporters/xml-exporter';
import { NMLoadPerioEvent } from '../events/nm-data-events/nm-load-perio.event';
import { ApplyPeriChangeEvent } from '../events/perio/perio-change-event';

export abstract class BaseExporterService {
    public static readonly LOG_SCOPUS = 'Export Service';
    protected unsaveStateActive = true;
    protected unsaveData = false; // por defecto false
    constructor() {
        EventBus.get().register(this);

        // evento para evitar cerrar pestaña o navegador sin salvar
        window.addEventListener('beforeunload', (event) => {
            if (this.unsaveData) {
                (event || window.event).returnValue = ''; // Gecko + IE
                return ''; // Gecko + Webkit, Safari, Chrome etc.
            }
        });
    }

    protected abstract export();

    protected notifyUnsavedChanges() {
        this.unsaveData = true;
        EventBus.get().post(new UnsavedChangesEvent()); // TODO: hacer q solo se dispare este evento en el primer cambio
    }

    protected notifyChangesSavedOk() {
        if (this.unsaveStateActive) {
            this.unsaveData = false;
            EventBus.get().post(new ChangesSavedOkEvent());
        }
    }

    protected exportSuccess() {
        log(1, BaseExporterService.LOG_SCOPUS, 'Export Ok version '/*, this.changesManager.currentVersion*/);
        this.notifyChangesSavedOk();
        EventBus.get().post(new ShowMessageEvent(
            i18n(['operation.save.successful', '$$field$$ was saved successfully'], { field: i18n(["general.document", "Document"]) }),
            TypeDialogModel.SUCCESS, 1000));

        // this.changesManager.setCurrentVerAsLastSavedVer();
    }

    protected exportFailure(status: number) {
        log(1, NemoDocumentExportService.LOG_SCOPUS, () => 'Error exporting ' + ', status: ' + status);
        EventBus.get().post(new ShowMessageEvent(
            i18n(['form.errors.documentSaveProblem', 'There was a problem saving the document']),
            TypeDialogModel.ERROR, 1000));
    }

    @subscribe(SaveDocumentCloudEvent)
    onSaveDocumentInCloudEvent() {
        if (this.unsaveData) { this.export(); }
    }

}

// @registerEventBus
export class NemoDocumentExportService extends BaseExporterService {


    private exporterManager: ExporterManager;
    private modelContainer: BaseModelContainer;

    // versionado
    private multiDocumentChangesMap: Map<string, ChangesManager>;
    private changesManager = new ChangesManager();

    constructor(document: ProvidedDocument) {
        super();
        log(1, BaseExporterService.LOG_SCOPUS, 'Creado export service ');

        this.exporterManager = new ExporterManager(
            document,
            () => this.exportSuccess(),
            (status) => this.exportFailure(status));

    }

    protected exportSuccess() {
        super.exportSuccess();
        EventBus.get().post(new SetProgressIndicatorVisibleEvent(false));

        this.changesManager.setCurrentVerAsLastSavedVer();
    }

    protected export() {
        EventBus.get().post(new SetProgressIndicatorVisibleEvent(true));
        this.exporterManager.exportDocument();
    }


    @subscribe(NMMainXmlManagerEvent)
    public onMainXmlManager(event: NMMainXmlManagerEvent) {
        this.exporterManager.addExporter(new XmlExporter(FileNameTable.MAIN_XML, event.xmlManager));
    }

    @subscribe(NMInfoXmlManagerEvent)
    public onNMInfoXmlManager(event: NMInfoXmlManagerEvent) {
        this.exporterManager.addExporter(new XmlExporter(FileNameTable.INFO_XML, event.xmlManager));
    }

    @subscribe(ModelSupplyEvent)
    public onModelSupply(event: ModelSupplyEvent) {

        this.modelContainer = event.modelContainer;

        if (event.modelContainer instanceof NsiModelContainer) { // si es un NSI añado exportador de imagen
            this.addNSIExporters(event.modelContainer);
        }
    }

    private addNSIExporters(modelContainer: BaseModelContainer) {

        const imageDataManager = <NSIImagesManager>(<NsiModelContainer>modelContainer).imageDataManager;

        imageDataManager.photoDataMap.forEach((element, key) => {
            this.exporterManager.addExporter( // añadir el exportador al manager
                new NsiImageExporter(
                    key,
                    () => imageDataManager.getImageAsPng(key)),
                key);
        });
        this.exporterManager.addExporter( // añadir el exportador al manager
            new NsiImageExporter(
                FileNameTable.THUMB_PNG,
                () => imageDataManager.getImageAsPng(undefined, NsiImageExporterConstants.ThumbSize)),
            NsiImageExporterConstants.NsiThumbId);

        this.exporterManager.addExporter( // añadir el exportador al manager
            new NsiImageExporter(
                FileNameTable.PAGE_PNG,
                () => imageDataManager.getImageAsPng(undefined, NsiImageExporterConstants.PageSize)),
            NsiImageExporterConstants.NsiPageId);

    }


    @subscribeToType(BaseChangeEventType)
    public onChangeDocument(event: BaseChangeEventType) {
        this.applyChange(event);
    }


    private applyChange(change: BaseChangeEventType) {
        try {
            change.do(this.exporterManager, this.modelContainer); // ejecuta el cambio
            this.notifyUnsavedChanges();  // notifico
            this.changesManager.pushChange(change); // apilo
            log(1, NemoDocumentExportService.LOG_SCOPUS,
                () => 'Aplicando cambio ver=' + change.versionStamp + ' ' + change.shortDescription(), change);
        } catch (e) {
            console.error('Error aplicando cambio ', e);
        }
    }

    @subscribe(RedoChangeEvent)
    public onRedoChange() {

        const change = this.changesManager.redoChange();
        if (change) {
            change.forEach(item => {
                this.applyRedo(item);
            });
        }

    }

    private applyRedo(change: BaseChangeEventType) {
        try {

            // modificar el xmlexporter correspondiente
            change.do(this.exporterManager, this.modelContainer);

            this.notifyUnsavedChanges();   // notifico

            // si se cae en la última versión salvada
            if (this.changesManager.isCurrentVerTheLastSavedVer()) { this.notifyChangesSavedOk(); }

            // si no hay más cambios notificar
            if (this.changesManager.isUndoneChangesStackEmpty()) { EventBus.get().post(new NoUndoneChangesEvent()); }

            log(1, NemoDocumentExportService.LOG_SCOPUS,
                () => 'Rehaciendo cambio ver=' + change.versionStamp + ' ' + change.shortDescription(), change);
        } catch (e) {
            console.error('Error rehaciendo cambio ', e);
        }
    }

    @subscribe(UndoChangeEvent)
    public onUndoChange() {

        const change = this.changesManager.popChange();
        if (change) {
            change.slice().reverse().forEach(item => {
                this.applyUndo(item);
            });
        }

    }

    private applyUndo(change: BaseChangeEventType) {
        try {

            // modificar el xmlexporter correspondiente
            change.undo(this.exporterManager, this.modelContainer); // se ejecuta el deshacer

            this.notifyUnsavedChanges();   // notifico

            // si se cae en la última versión salvada
            if (this.changesManager.isCurrentVerTheLastSavedVer()) { this.notifyChangesSavedOk(); }

            // si no hay más cambios notificar
            if (this.changesManager.isChangesStackEmpty()) { EventBus.get().post(new NoChangesEvent()); }

            log(1, NemoDocumentExportService.LOG_SCOPUS,
                () => 'Deshaciendo cambio ver=' + change.versionStamp + ' ' + change.shortDescription(), change);
        } catch (e) {
            console.error('Error deshaciendo cambio ', e);
        }
    }


    @subscribe(Change2DModelEvent)
    public onChange2DModel(event: Change2DModelEvent) {
        if (!this.multiDocumentChangesMap) {
            this.multiDocumentChangesMap = new Map<string, ChangesManager>();
            this.multiDocumentChangesMap.set(event.previousId, this.changesManager);

            this.changesManager = new ChangesManager();
            this.multiDocumentChangesMap.set(event.image2dId, this.changesManager);
        } else {
            this.changesManager = this.multiDocumentChangesMap.get(event.image2dId);
            if (!this.changesManager) {
                this.changesManager = new ChangesManager();
                this.multiDocumentChangesMap.set(event.image2dId, this.changesManager);
            }
        }
    }

    @subscribe(NMLoadPerioEvent)
    private LoadPerio(event: NMLoadPerioEvent) {
        this.unsaveData = true;
        this.unsaveStateActive = false;
        this.exporterManager.addExporter(new XmlExporter(FileNameTable.MAIN_XML, event.mainXmlManager));
        EventBus.get().post(new ApplyPeriChangeEvent(event.perioManager));
    }

}