/*
 * Licensed Materials - Property of Rogue Wave Software, Inc. 
 * © Copyright Rogue Wave Software, Inc. 2014, 2015 
 * © Copyright IBM Corp. 2009, 2014
 * © Copyright ILOG 1996, 2009
 * All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:
 * The Software and Documentation were developed at private expense and
 * are "Commercial Items" as that term is defined at 48 CFR 2.101,
 * consisting of "Commercial Computer Software" and
 * "Commercial Computer Software Documentation", as such terms are
 * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
 * as applicable.
 */
package plugins;

import ilog.views.IlvManagerLayer;
import ilog.views.maps.IlvMapLayerTreeProperty;
import ilog.views.maps.IlvMapUtil;
import ilog.views.maps.beans.IlvExceptionMessage;
import ilog.views.maps.beans.IlvMapLayer;
import ilog.views.maps.beans.IlvMapLayerTreeModel;
import ilog.views.maps.datasource.IlvMapDataSource;
import ilog.views.maps.datasource.IlvMapDataSourceModel;
import ilog.views.maps.datasource.IlvMapDataSourceProperty;
import ilog.views.maps.graphic.style.IlvMapCompositeStyle;
import ilog.views.maps.graphic.style.IlvMapStyle;
import ilog.views.maps.theme.IlvMapDynamicStyle;
import ilog.views.maps.theme.IlvMapStyleController;
import ilog.views.maps.theme.IlvMapStyleControllerProperty;
import ilog.views.tiling.IlvTiledLayer;

import java.net.URL;
import java.util.Enumeration;
import javax.swing.SwingUtilities;


/**
 * Thread loading files in background.
 */
public class LoadDataRunnable extends Thread {
  private final String[] fileNames;
  private final URL[] url;
  IlvMapLayerTreeModel ltm ;
  IlvMapDataSourceModel model;
  private boolean interrupted=false;
  private final ImportAction importer;
  /**
   * 
   * @param importer
   * @param fileNames
   */
  public LoadDataRunnable(ImportAction importer,String[] fileNames) {
    super();
    if(importer instanceof LoadAnythingAction){
      LoadAnythingAction ls=(LoadAnythingAction)importer;
      this.importer = ls.getSelectedAction();
    } else {
      this.importer=importer;
    }
    if(importer.getStopButton()!=null){
      importer.getStopButton().addThread(this);
    }
    ltm = IlvMapLayerTreeProperty.GetMapLayerTreeModel(importer.getView().getManager());
    model = IlvMapDataSourceProperty.GetMapDataSourceModel(importer.getView().getManager());
    setName("LoadInBackround"); //$NON-NLS-1$
    setPriority(Thread.MIN_PRIORITY);
    this.fileNames = fileNames;
    this.url = null;
  }
  
  /**
   * Creates a loading thread for the import action.
   * @param importer
   * @param url
   */
  public LoadDataRunnable(ImportAction importer, URL[] url) {
    super();
    fileNames = null;
    this.url = url;
    if(importer instanceof LoadAnythingAction){
      LoadAnythingAction ls=(LoadAnythingAction)importer;
      this.importer = ls.getSelectedAction();
    } else {
      this.importer = importer;
    }
    if(importer.getStopButton()!=null){
      importer.getStopButton().addThread(this);
    }
    ltm = IlvMapLayerTreeProperty.GetMapLayerTreeModel(importer.getView().getManager());
    model = IlvMapDataSourceProperty.GetMapDataSourceModel(importer.getView().getManager());
    setName("LoadInBackround"); //$NON-NLS-1$
    setPriority(Thread.MIN_PRIORITY);
  }
  
  void stopCleanly()
  {
    interrupted=true;
    interrupt();
  }
  void insertDataSource(IlvMapLayer parent,IlvMapDataSource d)
  {
    if(d==null) {
      return;
    }
    IlvMapLayer layer = d.getInsertionLayer(); 
    layer.setName(d.getName()); 
    IlvMapStyleController themeControl=IlvMapStyleControllerProperty.GetMapStyleController(importer.getView().getManager());
    IlvMapStyle childStyle = layer.getStyle();
    if(parent!=null) {
    IlvMapDynamicStyle []t=themeControl.getThemes(layer);
    for (int i = 0; i < t.length; i++) {
      t[i].getStyle().setParent(parent.getStyle());
    }
    if(childStyle != null) {
        childStyle.setParent(parent.getStyle());
      }
    }      
    if(layer.getParent() == null) {
      ltm.addChild(parent, layer);
    }
    model.insert(d);
  }
  void refreshTiles()
  {
    int nl=importer.getView().getManager().getLayersCount();
    for (int i = 0; i < nl; i++) {
      IlvManagerLayer l=importer.getView().getManager().getManagerLayer(i);
      if (l instanceof IlvTiledLayer) {
        ((IlvTiledLayer) l).getTileController().updateView(importer.getView());
      }
    }
    
  }
  /** 
   * Main thread running method. 
   * Will go through all datasources returned by {@link ImportAction#getDataSources(String[])} and add them, and their layers, to the different tree models.
   */
  public void run() {
    try {
        IlvMapStyleController themeController = IlvMapStyleControllerProperty.GetMapStyleController(importer.getView().getManager());
        IlvMapLayer parent = ltm.findChildLayer(null,importer.getFormatName());
        if(parent==null) {
          parent = new IlvMapLayer();
          parent.setName(importer.getFormatName());
          IlvMapCompositeStyle parentStyle= new IlvMapCompositeStyle();
          //parentStyle.addStyle(new IlvRasterStyle());
          parent.setStyle(parentStyle);
          ltm.addChild(null, parent);
        }
        if(interrupted) {
          end();
          return;
        }
        Enumeration e = null;
        if(fileNames != null)
          e = importer.getDataSources(fileNames);
        else if(url != null)
          e = importer.getDataSources(url);
        Object o = fileNames;
        if(o == null)
          o = url;
        importer.setAdvancement(ImportAction.LOADING, o,100);
        importer.setAdvancement(ImportAction.RENDERING,o,1);
        if(e==null){
          end();
          return;
        }
        while (e.hasMoreElements()) {
          if(interrupted) {
            end();
            return;
          }
          IlvMapDataSource d=(IlvMapDataSource)e.nextElement();
          if(d!=null && !interrupted){
            insertDataSource(parent,d);
            themeController.updateTheme(importer.getView(),d.getInsertionLayer());
            d.start();
          } else {
            end();
            return;
          }
          if(interrupted) {
            end();
            return;
          }
        }
     } catch (Throwable th) {
      new IlvExceptionMessage(th,IlvMapUtil.getString(ImportAction.class,"ImportAction.Error")); //$NON-NLS-1$
     }
     end();
   }
  /**
   * Called after the run, wether of not it has been interrupted, to refresh the tiles and the views.
   */
  public void end() {
    SwingUtilities.invokeLater(new Runnable() {public void run(){
    ltm.arrangeLayers();
    IlvMapStyleController themeController = IlvMapStyleControllerProperty.GetMapStyleController(importer.getView().getManager());
    themeController.updateCurrentTheme();
    refreshTiles();
    importer.getView().getManager().reDraw();
    Object o = fileNames;
    if(o == null)
      o = url;
    importer.setAdvancement(ImportAction.RENDERING,o,100);
    if(importer.getStopButton()!=null){
      importer.getStopButton().removeThread(LoadDataRunnable.this);
    }
    }});
  }
/**
 * @return Returns the interrupted.
 */
public boolean wasStoppedCleanly() {
    return interrupted;
}
}