import {BrowserModule, Title} from '@angular/platform-browser';
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
import {APP_INITIALIZER, NgModule} from '@angular/core';
import {NgbModule} from "@ng-bootstrap/ng-bootstrap";
import {HttpClientModule} from "@angular/common/http";
import {FormsModule, ReactiveFormsModule} from '@angular/forms';

import {EnvServiceProvider} from "./env/env.service.provider";
import {ConfigurationService} from "./env/configuration.service";

import {AppRoutingModule} from './app-routing.module';
import {AppComponent} from './app.component';
import {SettingsComponent} from './settings/settings.component';
import {TilesComponent} from './tiles/tiles.component';
import {CalibratorsComponent} from './calibrators/calibrators.component';
import {ProductsComponent} from './products/products.component';
import {JobspecsComponent} from './jobspecs/jobspecs.component';
import {ExecutionsComponent} from './executions/executions.component';
import {TileComponent} from './tiles/tile/tile.component';
import {CalibratorComponent} from './calibrators/calibrator/calibrator.component';
import {ProductComponent} from './products/product/product.component';
import {JobspecComponent} from './jobspecs/jobspec/jobspec.component';
import {ExecutionComponent} from './executions/execution/execution.component';
import {FileeditorComponent} from './fileeditor/fileeditor.component';
import {ContentEditableDirective} from './directives/content-editable.directive';
import {AlertComponent} from './alert/alert.component';
import {HomeComponent} from './home/home.component';
import {JobspecDetailComponent} from './jobspecs/jobspec/jobspec-detail/jobspec-detail.component';
import {ProductVersionComponent} from './products/product/product-details/product-version/product-version.component';
import {ProductDetailsComponent} from './products/product/product-details/product-details.component';
import {ProductPrerequsitesComponent} from './products/product/product-details/product-prerequsites/product-prerequsites.component';
import {JobspecTargetComponent} from './jobspecs/jobspec/jobspec-detail/jobspec-target/jobspec-target.component';
import {JobspecInputComponent} from './jobspecs/jobspec/jobspec-detail/jobspec-input/jobspec-input.component';
import {JobspecExecutionComponent} from './jobspecs/jobspec/jobspec-detail/jobspec-execution/jobspec-execution.component';
import {ExecutionDetailComponent} from './executions/execution/execution-detail/execution-detail.component';
import {ExecutionDetailPlanesComponent} from './executions/execution/execution-detail/execution-detail-planes/execution-detail-planes.component';
import {FontAwesomeModule} from "@fortawesome/angular-fontawesome";
import {LoadingComponent} from './loading/loading.component';
import {QueueSettingsComponent} from './settings/queue-settings/queue-settings.component';
import {WINDOW_PROVIDERS} from "./env/window.provider";
import {FutureProductComponent} from './products/product/product-details/future-product/future-product.component';
import {ProgressComponent} from './tiles/progress/progress.component';

/*
We will 'provide' this function below to load and set the global configuration from the
configuration.service before the app loads using APP_INITIALIZER.
This function (and the configuration.service method it calls) must return a promise.
Angular will wait for the promise to resolve before loading the app.
 */
export function init_app(configService: ConfigurationService) {
  return () => configService.getSettings();
}

@NgModule({
  declarations: [
    AppComponent,
    SettingsComponent,
    TilesComponent,
    CalibratorsComponent,
    ProductsComponent,
    JobspecsComponent,
    ExecutionsComponent,
    TileComponent,
    CalibratorComponent,
    ProductComponent,
    JobspecComponent,
    ExecutionComponent,
    FileeditorComponent,
    ContentEditableDirective,
    AlertComponent,
    HomeComponent,
    JobspecDetailComponent,
    ProductVersionComponent,
    ProductDetailsComponent,
    ProductPrerequsitesComponent,
    JobspecTargetComponent,
    JobspecInputComponent,
    JobspecExecutionComponent,
    ExecutionDetailComponent,
    ExecutionDetailPlanesComponent,
    LoadingComponent,
    QueueSettingsComponent,
    FutureProductComponent,
    ProgressComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutingModule,
    NgbModule,
    HttpClientModule,
    ReactiveFormsModule,
    FormsModule,
    FontAwesomeModule
  ],
  providers: [EnvServiceProvider, {
    provide: APP_INITIALIZER,
    useFactory: init_app,
    deps: [ConfigurationService],
    multi: true
  }, Title, WINDOW_PROVIDERS],
  bootstrap: [AppComponent]
})
export class AppModule {
}