import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

//external modules
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
import { EffectsModule } from '@ngrx/effects';
import { ActionReducer, MetaReducer, StoreModule } from '@ngrx/store';
import { AngularOpenlayersModule } from '@farmmaps/ng-openlayers';

//common modules
import { AppCommonModule } from '@farmmaps/common';

import * as mapActions from './actions/map.actions';
import * as mapEffects from './effects/map.effects';
import { MODULE_NAME } from './module-name';
import * as mapReducers from './reducers/map.reducer';

import { IClickedFeature } from './models/clicked.feature';
import { IItemLayer, ItemLayer, ITemporalItemLayer, TemporalItemLayer } from './models/item.layer';
import { IMapState } from './models/map.state';
import { IPeriodState } from './models/period.state';
import { ISelectedFeatures } from './models/selected.features';

// components
import { MapRoutingModule } from './common-map-routing.module';
import { FileDropTargetComponent } from './components/aol/file-drop-target/file-drop-target.component';
import { GpsLocation } from './components/aol/gps-location/gps-location.component';
import { ItemLayersComponent } from './components/aol/item-layers/item-layers.component';
import { ItemVectorSourceComponent } from './components/aol/item-vector-source/item-vector-source.component';
import { LayerListComponent } from './components/aol/layer-list/layer-list.component';
import { LayerValuesComponent } from './components/aol/layer-values/layer-values.component';
import { LayerVectorImageComponent } from './components/aol/layer-vector-image/layer-vector-image.component';
import { PanToLocation } from './components/aol/pan-to-location/pan-to-location.component';
import { RotationResetComponent } from './components/aol/rotation-reset/rotation-reset.component';
import { ZoomToExtentComponent } from './components/aol/zoom-to-extent/zoom-to-extent.component';
import { FeatureListContainerComponent } from './components/feature-list-container/feature-list-container.component';
import { FeatureListCropfieldComponent } from './components/feature-list-cropfield/feature-list-cropfield.component';
import { FeatureListObservationComponent } from './components/feature-list-observation/feature-list-observation.component';
import { FeatureListCroppingschemeComponent } from './components/feature-list-croppingscheme/feature-list-croppingscheme.component';
import { FeatureListFeatureContainerComponent } from './components/feature-list-feature-container/feature-list-feature-container.component';
import { FeatureListFeatureCropfieldComponent } from './components/feature-list-feature-cropfield/feature-list-feature-cropfield.component';
import { FeatureListFeatureCroppingschemeComponent } from './components/feature-list-feature-croppingscheme/feature-list-feature-croppingscheme.component';
import { AbstractFeatureListFeatureComponent, FeatureListFeatureComponent } from './components/feature-list-feature/feature-list-feature.component';
import { AbstractFeatureListComponent, FeatureListComponent } from './components/feature-list/feature-list.component';
import { GeometryThumbnailComponent } from './components/feature-thumbnail/feature-thumbnail.component';
import { ForChild } from './components/for-item/for-child.decorator';
import { ForItemType } from './components/for-item/for-itemtype.decorator';
import { ForPackage } from './components/for-item/for-package.decorator';
import { ForSourceTask } from './components/for-item/for-sourcetask.decorator';
import { ifZoomToShowDirective } from './components/if-zoom-to-show/if-zoom-to-show.directive';
import { ItemListItemContainerComponent } from './components/item-list-item-container/item-list-item-container.component';
import { AbstractItemListItemComponent, AbstractItemWidgetComponent, ItemListItemComponent } from './components/item-list-item/item-list-item.component';
import { AbstractItemListComponent, ItemListComponent } from './components/item-list/item-list.component';
import { ItemWidgetListComponent } from './components/item-widget-list/item-widget-list.component';
import { LayerSwitcher } from './components/layer-switcher/layer-switcher.component';
import { HistogramDetailsComponent } from './components/legend/histogram-details/histogram-details.component';
import { LegendComponent } from './components/legend/legend.component';
import { StatisticsDetailsComponent } from './components/legend/statistics-details/statistics-details.component';
import { MapSearchComponent } from './components/map-search/map-search.component';
import { MapComponent } from './components/map/map.component';
import { MetaDataModalComponent } from './components/meta-data-modal/meta-data-modal.component';
import { SelectPeriodModalComponent } from './components/select-period-modal/select-period-modal.component';
import { SelectedItemContainerComponent } from './components/selected-item-container/selected-item-container.component';
import { SelectedItemCropfieldComponent } from './components/selected-item-cropfield/selected-item-cropfield.component';
import { SelectedItemGeotiffComponent } from './components/selected-item-geotiff/selected-item-geotiff.component';
import { SelectedItemShapeComponent } from './components/selected-item-shape/selected-item-shape.component';
import { SelectedItemTemporalComponent } from './components/selected-item-temporal/selected-item-temporal.component';
import { AbstractSelectedItemComponent, SelectedItemComponent } from './components/selected-item/selected-item.component';
import { WidgetHostDirective } from './components/widget-host/widget-host.directive';
import { WidgetStatusComponent } from './components/widget-status/widget-status.component';
import { ZoomToShowAlert } from './components/zoom-to-show-alert/zoom-to-show-alert.component';
import { DeviceOrientationService } from './services/device-orientation.service';
import { FeatureIconService } from './services/feature-icon.service';
import { GeolocationService } from './services/geolocation.service';
import { TemporalService } from './services/temporal.service';

export function LocalStorageSync(reducer: ActionReducer<any>): ActionReducer<any> {
  const r = function(state, action) {
    const r2 = reducer(state, action);

    if(action.type == "@ngrx/store/update-reducers") {
        const ms = window.localStorage.getItem(MODULE_NAME+"_mapState");
        if(ms) {
          r2["mapState"] = JSON.parse(ms);
        }
        const sp = window.localStorage.getItem(MODULE_NAME+"_searchPeriod");
        if(sp) {          
          const p = JSON.parse(sp);
          r2["period"] = { startDate: new Date(Date.parse(p.startDate)),endDate:new Date(Date.parse(p.endDate))};
        }
    }
    if(action.type == "[Map] MapState" || action.type == "[Map] SetState") {
      window.localStorage.setItem(MODULE_NAME + "_mapState",JSON.stringify(r2["mapState"]));
    }
    if(action.type == "[Map] SetPeriod" ) {
      window.localStorage.setItem(MODULE_NAME + "_searchPeriod",JSON.stringify(r2["period"]));
    }

    return r2;
  };
  return r;
 }

const metaReducers: Array<MetaReducer<any, any>> = [LocalStorageSync];

export {
  AbstractFeatureListComponent,
  AbstractFeatureListFeatureComponent, AbstractItemListComponent, AbstractItemListItemComponent, AbstractItemWidgetComponent, AbstractSelectedItemComponent, DeviceOrientationService, FeatureIconService, FeatureListComponent, FeatureListContainerComponent, FeatureListCropfieldComponent, FeatureListObservationComponent, FeatureListCroppingschemeComponent, FeatureListFeatureComponent, FeatureListFeatureContainerComponent, FeatureListFeatureCropfieldComponent, FeatureListFeatureCroppingschemeComponent, FileDropTargetComponent, ForChild,
  ForItemType, ForPackage, ForSourceTask, GeolocationService, GeometryThumbnailComponent, GpsLocation, IClickedFeature, ifZoomToShowDirective, IItemLayer, IMapState, IPeriodState, ISelectedFeatures, ItemLayer, ItemLayersComponent, ItemListComponent, ItemListItemComponent,
  ItemListItemContainerComponent, ITemporalItemLayer, ItemVectorSourceComponent, ItemWidgetListComponent, LayerListComponent, LayerSwitcher, LayerVectorImageComponent, LegendComponent, mapActions, MapComponent, mapEffects,
  mapReducers, MapSearchComponent, MetaDataModalComponent, PanToLocation, RotationResetComponent, SelectedItemComponent, SelectedItemContainerComponent, SelectedItemCropfieldComponent,
  SelectedItemGeotiffComponent, SelectedItemShapeComponent, SelectedItemTemporalComponent, SelectPeriodModalComponent, TemporalItemLayer, TemporalService, WidgetHostDirective, WidgetStatusComponent, ZoomToExtentComponent, ZoomToShowAlert
};

@NgModule({
    imports: [
        CommonModule,
        AngularOpenlayersModule,
        MapRoutingModule,
        StoreModule.forFeature(MODULE_NAME, mapReducers.reducer, { metaReducers: metaReducers }),
        EffectsModule.forFeature([mapEffects.MapEffects]),
        NgbModule,
        FormsModule,
        ReactiveFormsModule,
        AppCommonModule
    ],
    declarations: [
        ZoomToExtentComponent,
        ItemVectorSourceComponent,
        ItemLayersComponent,
        FileDropTargetComponent,
        MapComponent,
        MetaDataModalComponent,
        RotationResetComponent,
        MapSearchComponent,
        SelectPeriodModalComponent,
        LayerListComponent,
        LegendComponent,
        LayerVectorImageComponent,
        FeatureListComponent,
        WidgetHostDirective,
        FeatureListContainerComponent,
        FeatureListCroppingschemeComponent,
        FeatureListCropfieldComponent,
        FeatureListObservationComponent,
        FeatureListFeatureContainerComponent,
        FeatureListFeatureComponent,
        FeatureListFeatureCroppingschemeComponent,
        FeatureListFeatureCropfieldComponent,
        SelectedItemContainerComponent,
        SelectedItemComponent,
        SelectedItemCropfieldComponent,
        SelectedItemGeotiffComponent,
        SelectedItemTemporalComponent,
        SelectedItemShapeComponent,
        ItemListItemComponent,
        ItemListItemContainerComponent,
        ItemListComponent,
        ItemWidgetListComponent,
        WidgetStatusComponent,
        GpsLocation,
        PanToLocation,
        LayerSwitcher,
        HistogramDetailsComponent,
        StatisticsDetailsComponent,
        ifZoomToShowDirective,
        ZoomToShowAlert,
        LayerValuesComponent,
        GeometryThumbnailComponent
    ],
    exports: [
        ItemVectorSourceComponent,
        ItemLayersComponent,
        FileDropTargetComponent,
        MetaDataModalComponent,
        MapComponent,
        GpsLocation,
        PanToLocation,
        LayerSwitcher,
        FeatureListFeatureComponent,
        FeatureListFeatureCropfieldComponent,
        FeatureListFeatureCroppingschemeComponent,
        SelectedItemContainerComponent,
        SelectedItemComponent,
        SelectedItemCropfieldComponent,
        SelectedItemGeotiffComponent,
        SelectedItemTemporalComponent,
        SelectedItemShapeComponent,
        ItemListItemComponent,
        ItemListItemContainerComponent,
        ItemListComponent,
        ItemWidgetListComponent,
        WidgetStatusComponent,
        RotationResetComponent,
        MapSearchComponent,
        SelectPeriodModalComponent,
        LayerListComponent,
        LegendComponent,
        LayerVectorImageComponent,
        FeatureListComponent,
        WidgetHostDirective,
        FeatureListContainerComponent,
        FeatureListCroppingschemeComponent,
        FeatureListCropfieldComponent,
        FeatureListObservationComponent,
        FeatureListFeatureContainerComponent,
        ZoomToExtentComponent,
        ifZoomToShowDirective,
        ZoomToShowAlert,
        GeometryThumbnailComponent
    ],
    providers: [
        FeatureIconService,
        GeolocationService,
        DeviceOrientationService,
        TemporalService,
        { provide: AbstractFeatureListComponent, useClass: FeatureListCroppingschemeComponent, multi: true },
        { provide: AbstractFeatureListComponent, useClass: FeatureListCropfieldComponent, multi: true },
        { provide: AbstractFeatureListComponent, useClass: FeatureListObservationComponent, multi: true },        
        { provide: AbstractFeatureListFeatureComponent, useClass: FeatureListFeatureComponent, multi: true },
        { provide: AbstractFeatureListFeatureComponent, useClass: FeatureListFeatureCroppingschemeComponent, multi: true },
        { provide: AbstractFeatureListFeatureComponent, useClass: FeatureListFeatureCropfieldComponent, multi: true },       
        { provide: AbstractSelectedItemComponent, useClass: SelectedItemComponent, multi: true },
        { provide: AbstractSelectedItemComponent, useClass: SelectedItemCropfieldComponent, multi: true },
        { provide: AbstractSelectedItemComponent, useClass: SelectedItemGeotiffComponent, multi: true },
        { provide: AbstractSelectedItemComponent, useClass: SelectedItemTemporalComponent, multi: true },
        { provide: AbstractSelectedItemComponent, useClass: SelectedItemShapeComponent, multi: true },
        { provide: AbstractItemListItemComponent, useClass: ItemListItemComponent, multi: true },
        { provide: AbstractItemListComponent, useClass: ItemListComponent, multi: true }
    ]
})


export class AppCommonMapModule {  
}
