/*
 * Copyright (c) 2012-2018 Red Hat, Inc.
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *   Red Hat, Inc. - initial API and implementation
 */
package org.eclipse.che.ide.core;

import com.google.gwt.inject.client.AbstractGinModule;
import com.google.gwt.inject.client.assistedinject.GinFactoryModuleBuilder;
import com.google.inject.Singleton;
import org.eclipse.che.ide.api.icon.IconRegistry;
import org.eclipse.che.ide.icon.DefaultIconsRegistrar;
import org.eclipse.che.ide.icon.IconRegistryImpl;
import org.eclipse.che.ide.menu.MainMenuView;
import org.eclipse.che.ide.menu.MainMenuViewImpl;
import org.eclipse.che.ide.menu.StatusPanelGroupView;
import org.eclipse.che.ide.menu.StatusPanelGroupViewImpl;
import org.eclipse.che.ide.part.WorkBenchControllerFactory;
import org.eclipse.che.ide.part.WorkBenchPartController;
import org.eclipse.che.ide.part.WorkBenchPartControllerImpl;
import org.eclipse.che.ide.ui.button.ConsoleButton;
import org.eclipse.che.ide.ui.button.ConsoleButtonFactory;
import org.eclipse.che.ide.ui.button.ConsoleButtonImpl;
import org.eclipse.che.ide.ui.dialogs.DialogFactory;
import org.eclipse.che.ide.ui.dialogs.choice.ChoiceDialog;
import org.eclipse.che.ide.ui.dialogs.choice.ChoiceDialogFooter;
import org.eclipse.che.ide.ui.dialogs.choice.ChoiceDialogPresenter;
import org.eclipse.che.ide.ui.dialogs.choice.ChoiceDialogView;
import org.eclipse.che.ide.ui.dialogs.choice.ChoiceDialogViewImpl;
import org.eclipse.che.ide.ui.dialogs.confirm.ConfirmDialog;
import org.eclipse.che.ide.ui.dialogs.confirm.ConfirmDialogFooter;
import org.eclipse.che.ide.ui.dialogs.confirm.ConfirmDialogPresenter;
import org.eclipse.che.ide.ui.dialogs.confirm.ConfirmDialogView;
import org.eclipse.che.ide.ui.dialogs.confirm.ConfirmDialogViewImpl;
import org.eclipse.che.ide.ui.dialogs.input.InputDialog;
import org.eclipse.che.ide.ui.dialogs.input.InputDialogFooter;
import org.eclipse.che.ide.ui.dialogs.input.InputDialogPresenter;
import org.eclipse.che.ide.ui.dialogs.input.InputDialogView;
import org.eclipse.che.ide.ui.dialogs.input.InputDialogViewImpl;
import org.eclipse.che.ide.ui.dialogs.message.MessageDialog;
import org.eclipse.che.ide.ui.dialogs.message.MessageDialogFooter;
import org.eclipse.che.ide.ui.dialogs.message.MessageDialogPresenter;
import org.eclipse.che.ide.ui.dialogs.message.MessageDialogView;
import org.eclipse.che.ide.ui.dialogs.message.MessageDialogViewImpl;
import org.eclipse.che.ide.ui.multisplitpanel.SubPanel;
import org.eclipse.che.ide.ui.multisplitpanel.SubPanelFactory;
import org.eclipse.che.ide.ui.multisplitpanel.panel.SubPanelPresenter;
import org.eclipse.che.ide.ui.multisplitpanel.panel.SubPanelView;
import org.eclipse.che.ide.ui.multisplitpanel.panel.SubPanelViewFactory;
import org.eclipse.che.ide.ui.multisplitpanel.panel.SubPanelViewImpl;
import org.eclipse.che.ide.ui.multisplitpanel.tab.Tab;
import org.eclipse.che.ide.ui.multisplitpanel.tab.TabItemFactory;
import org.eclipse.che.ide.ui.multisplitpanel.tab.TabWidget;
import org.eclipse.che.ide.ui.toolbar.MainToolbar;
import org.eclipse.che.ide.ui.toolbar.ToolbarPresenter;
import org.eclipse.che.ide.ui.toolbar.ToolbarView;
import org.eclipse.che.ide.ui.toolbar.ToolbarViewImpl;
import org.eclipse.che.ide.workspace.WorkspaceView;
import org.eclipse.che.ide.workspace.WorkspaceViewImpl;

/**
 * GIN module for configuring UI components.
 *
 * @author Artem Zatsarynnyi
 */
public class UiModule extends AbstractGinModule {

  @Override
  protected void configure() {
    bind(IconRegistry.class).to(IconRegistryImpl.class).in(Singleton.class);
    bind(DefaultIconsRegistrar.class).asEagerSingleton();
    bind(FontAwesomeInjector.class).asEagerSingleton();
    bind(BrowserTabCloseHandler.class).asEagerSingleton();

    // core UI components
    install(
        new GinFactoryModuleBuilder()
            .implement(WorkBenchPartController.class, WorkBenchPartControllerImpl.class)
            .build(WorkBenchControllerFactory.class));

    bind(WorkspaceView.class).to(WorkspaceViewImpl.class).in(Singleton.class);
    bind(MainMenuView.class).to(MainMenuViewImpl.class).in(Singleton.class);
    bind(ToolbarView.class).to(ToolbarViewImpl.class);
    bind(ToolbarPresenter.class)
        .annotatedWith(MainToolbar.class)
        .to(ToolbarPresenter.class)
        .in(Singleton.class);

    // dialog factory
    bind(MessageDialogFooter.class);
    bind(MessageDialogView.class).to(MessageDialogViewImpl.class);
    bind(ConfirmDialogFooter.class);
    bind(ConfirmDialogView.class).to(ConfirmDialogViewImpl.class);
    bind(ChoiceDialogFooter.class);
    bind(ChoiceDialogView.class).to(ChoiceDialogViewImpl.class);
    bind(InputDialogFooter.class);
    bind(InputDialogView.class).to(InputDialogViewImpl.class);

    install(
        new GinFactoryModuleBuilder()
            .implement(MessageDialog.class, MessageDialogPresenter.class)
            .implement(ConfirmDialog.class, ConfirmDialogPresenter.class)
            .implement(ChoiceDialog.class, ChoiceDialogPresenter.class)
            .implement(InputDialog.class, InputDialogPresenter.class)
            .build(DialogFactory.class));

    // multi-split panel
    install(
        new GinFactoryModuleBuilder()
            .implement(SubPanel.class, SubPanelPresenter.class)
            .build(SubPanelFactory.class));
    install(
        new GinFactoryModuleBuilder()
            .implement(SubPanelView.class, SubPanelViewImpl.class)
            .build(SubPanelViewFactory.class));
    install(
        new GinFactoryModuleBuilder()
            .implement(Tab.class, TabWidget.class)
            .build(TabItemFactory.class));

    // miscellaneous UI components
    install(
        new GinFactoryModuleBuilder()
            .implement(ConsoleButton.class, ConsoleButtonImpl.class)
            .build(ConsoleButtonFactory.class));

    bind(StatusPanelGroupView.class).to(StatusPanelGroupViewImpl.class).in(Singleton.class);
  }
}
