/*
 * Copyright (C) 2017 TypeFox and others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 */

import * as ReactDOM from "react-dom";
import * as React from 'react';

import { injectable, inject } from 'inversify';

import { Emitter, Event, ResourceProvider } from '@theia/core';
import { Message } from '@phosphor/messaging';
import { BaseWidget, SaveableSource, Navigatable, Widget, Saveable } from '@theia/core/lib/browser';

import { CatalogoContainer } from './layout/catalogo-container';
import { CatalogoService } from "./catalogo-service";
import URI from "@theia/core/lib/common/uri";
import { CatalogoUri } from "./catalogo-uri";


export const WIDGET_ID = 'widget.Catalogo';
export const CatalogoWidgetOptions = Symbol('CatalogoWidgetOptions');
export interface CatalogoWidgetOptions {
    uri: URI;
    longId: string;
    shortId: string;
    parentId: string;
    sequence: number;
}

@injectable()
export class CatalogoWidget extends BaseWidget implements SaveableSource, Navigatable {

    @inject(CatalogoUri)
    protected readonly catalogoUri: CatalogoUri;

    protected reactElement:any;
    protected widget: Element;

    protected _dirty: boolean = false;

    protected readonly onCatalogoChangeEmitter = new Emitter<void>();

    readonly onDirtyChanged: Event<void> = this.onCatalogoChangeEmitter.event;

    constructor(
        @inject(CatalogoWidgetOptions) protected readonly options: CatalogoWidgetOptions,
        @inject(ResourceProvider) protected readonly resourceProvider: ResourceProvider,
        @inject(CatalogoService) protected readonly service: CatalogoService
    ) {
        super();

        this.id = `catalogo-widget-${this.options.sequence}`;
        this.title.label = options.longId ? `Task: ${options.longId}` : `Task: ${options.sequence}`;
        this.title.caption = options.longId ? `Task: ${options.longId}` : `Task: ${options.sequence}`;
        this.title.closable = true;
        
        this.onAfterShow = this.onAfterShow.bind(this);

        this.node.tabIndex = 0;
    }

    dispose() {
        super.dispose();
    }

    onActivateRequest(msg: Message): void {
        super.onActivateRequest(msg);
        this.node.focus();
        this.render();
    }

    protected async onAfterShow(msg: Message): Promise<void> {
        if (this.reactElement) {
            super.onAfterShow(msg);
            this.node.focus();
        } else {
            this.render()
        }
    }

    public get dirty():boolean {
        return this._dirty;
    }

    async close() {
        this.dispose();
        super.close();
    }

    protected onReveal(widget: Widget): Promise<void> {
        if (widget.isVisible) {
            return new Promise(resolve => window.requestAnimationFrame(() => resolve()));
        }
        return new Promise(resolve => {
            const waitForVisible = () => window.requestAnimationFrame(() => {
                if (widget.isVisible) {
                    window.requestAnimationFrame(() => resolve());
                } else {
                    waitForVisible();
                }
            });
            waitForVisible();
        });
    }

    get autoSave(): 'on' | 'off' {
        return 'off';
    }

    get saveable(): Saveable | undefined {
        return this;
    }

    async save(): Promise<void> {
        // @Acinar metodo para ativar o save do Theia
    }

    getResourceUri(): URI {
        return this.catalogoUri.validate(this.options.uri); 
    }
    
    createMoveToUri(resourceUri: URI): URI | undefined {
        return undefined;
    }

    async render(): Promise<void> {
        if(!this.reactElement){
            var preloader = document.createElement('div');
            preloader.classList.add('theia-preload');
            preloader.style.backgroundAttachment = 'inherit';

            let container = document.getElementById(this.id);
            container.appendChild(preloader);

            const catalogoUri = this.catalogoUri.validate(new URI(this.options.uri.toString()));
            const resource = await this.resourceProvider(catalogoUri)

            this.reactElement = <CatalogoContainer options={{options: this.options, widget: this}} service={this.service} resource={resource}/>;
            this.widget = ReactDOM.render(this.reactElement , container);
        }
    }
}
