/*
 * 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.IlvManagerView;
import ilog.views.maps.IlvMapUtil;
import ilog.views.maps.datasource.IlvMapDataSource;
import ilog.views.maps.format.cadrg.IlvCADRGCoverage;
import ilog.views.maps.format.cadrg.IlvCADRGFrame;
import ilog.views.maps.format.cadrg.IlvCADRGTocReader;
import ilog.views.maps.raster.IlvRasterAbstractReader;
import ilog.views.maps.raster.datasource.IlvRasterDataSourceFactory;
import ilog.views.maps.raster.datasource.IlvThreadMonitoringData;
import ilog.views.maps.theme.IlvMapStyleController;
import ilog.views.maps.theme.IlvMapStyleControllerProperty;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import nodefense.CADRGDefLess;

/**
 * Class that manages CADRG import action.
 */
public class CADRGLoadAction extends ImportAction {
  class CADRGEnumeration implements Enumeration {
    int ns;
    final Object[] ids;
    Integer[] scales;
    Object covs;
    double basePct;

    //    CADRGEnumeration(String[] monitorID,IlvCADRGCoverageList covs)
    CADRGEnumeration(Object[] ids, Object covs) {
      this.scales = CADRGDefLess.getOrderedScaleList(covs);
      //this.scales=covs.getOrderedScaleList();
      this.ids = ids;
      this.covs = covs;
      basePct = 100.0 / (scales.length + 1);
      ns = 0;
    }

    /**
     * @see java.util.Enumeration#hasMoreElements()
     */
    public boolean hasMoreElements() {
      boolean hasMore=false;
      for (int i=ns;i<scales.length;i++) {
        if (scaleSelection[scales.length - 1 -i].isSelected()) {
          hasMore=true;
          break;
        }
      }
      if (!hasMore) {
        setAdvancement(RENDERING, ids, 100);
      }
      return hasMore;
    }

    /**
     * @see java.util.Enumeration#nextElement()
     */
    public Object nextElement() {
      if (hasMoreElements()) {
        IlvMapStyleController themeControl = IlvMapStyleControllerProperty.GetMapStyleController(view.getManager());
        boolean first=(ns==0);
        for (;ns<scales.length && !scaleSelection[scales.length - 1 -ns].isSelected();ns++){
          // do nothing.
        }
        int i = ns;
        ns++;
        int beg = (int) (basePct * (i + 0.1));
        int mid = (int) (basePct * (i + 0.8));
        int end = (int) (basePct * (i + 1));
        Integer scale = scales[scales.length - 1 - i];
        //        IlvCADRGCoverage[] scaleCovs = covs.getCoverageList(scale);
        IlvCADRGCoverage[] scaleCovs = CADRGDefLess.getCoverageList(covs, scale);
        setAdvancement(RENDERING, ids, beg);
        if (scaleCovs.length != 0) {
          IlvRasterAbstractReader frameReader = CADRGDefLess.newIlvRasterCADRGReader();
          //          IlvRasterCADRGReader frameReader = new IlvRasterCADRGReader();
          String scaleDesc = scaleCovs[0].getScaleDescription().trim();
          for (int iCov = 0; iCov < scaleCovs.length; iCov++) {
            int b1 = beg;
            int b2 = mid;
            //JV-4334
            if(scaleCovs.length!=1){
                b1=(int) (beg + (iCov / (double) (scaleCovs.length - 1)) * (mid - beg));
                b2=(int) (beg + ((iCov + 1) / (double) (scaleCovs.length - 1)) * (mid - beg));
            }
            setAdvancement(RENDERING, ids, b1);
            IlvCADRGCoverage cov = scaleCovs[iCov];
            int b = 0;
            int nRows = cov.getRows();
            int nCols = cov.getColumns();
            for (int row = 0; row < nRows; row++) {
              for (int column = 0; column < nCols; column++) {
                IlvCADRGFrame f = cov.getFrame(row, column);
                if (f != null) {
                  // frameReader.addCADRGFrame(f);
                  CADRGDefLess.addCADRGFrame(frameReader, f);
                }
                b++;
                setAdvancement(RENDERING, ids, (int) (b1 + (b2 - b1) * (double) b / (nRows * nCols)));
              }
            }
          }
          setAdvancement(RENDERING, ids, mid);
          IlvThreadMonitoringData monitorData = new IlvThreadMonitoringData(getMonitor(), ids, scaleDesc + " " + getActivityDescription(RENDERING), //$NON-NLS-1$
              mid, end);
          IlvMapDataSource ds = IlvRasterDataSourceFactory.buildTiledImageDataSource(view.getManager(), frameReader, false, true, monitorData);
          ds.setName(getFormatName() + " " + scaleDesc); //$NON-NLS-1$
          ds.getInsertionLayer().setName(ds.getName());

          float tscale = scale.intValue() * 4;
          if (!first) {
            themeControl.addTheme(1f / tscale, ds.getInsertionLayer(), IlvMapUtil.getString(CADRGLoadAction.class, "CADRGLoadAction.InvisibleStyleName")); //$NON-NLS-1$
            themeControl.getStyle(ds.getInsertionLayer(), 1f / tscale).setVisibleInView(false);
          }
          if(hasMoreElements()) {
             tscale = scale.intValue() / 4;
             themeControl.addTheme(1f / tscale, ds.getInsertionLayer(), IlvMapUtil.getString(CADRGLoadAction.class, "CADRGLoadAction.VisibleStyleName")); //$NON-NLS-1$
             themeControl.getStyle(ds.getInsertionLayer(), 1f / tscale).setVisibleInView(true);
             themeControl.getStyle(ds.getInsertionLayer(), 1).setVisibleInView(false);
          } else {
             if(!first) {
               themeControl.getStyle(ds.getInsertionLayer(), 1).setVisibleInView(true);
             }
          }
          return ds;
        }
      }
      return null;
    }

  }

  /**
   * Creates an action for the specified view
   * @param view view to add map data to.
   */
  public CADRGLoadAction(IlvManagerView view) {
    super(view);
  }

  /**
   * @see plugins.ImportAction#getSubDirectory()
   */
  protected String getSubDirectory() {
    return IlvMapUtil.getString(getClass(), "CADRGLoadAction.CDDirectory"); //$NON-NLS-1$
  }
  private JPanel accessory;
  private JScrollPane accessoryPane;
  private JCheckBox noData;
  private JCheckBox scaleSelection[];

  /** Returns null.
   * @see plugins.ImportAction#getAccessory()
   */
  public JComponent getAccessory() {
    if(accessoryPane==null) {
      accessory = new JPanel(new GridBagLayout());
      String msg=IlvMapUtil.getString(CADRGLoadAction.class,"CADRGLoadAction.scaleSelection"); //$NON-NLS-1$
      accessory.setBorder(BorderFactory.createTitledBorder(msg));
      noData=new JCheckBox(msg);
      noData.setEnabled(false);    
      accessory.add(noData);
      accessoryPane=new JScrollPane(accessory,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
      accessory.setBackground(Color.white);
   }
    return accessoryPane;
  }
  /**
   * @see plugins.ImportAction#selectedFileChanged(File)
   */ 
  public void selectedFileChanged(File file) {
    getAccessory(); // init accessories components
    accessory.removeAll();
    scaleSelection=new JCheckBox[0];
    if (file != null) {
      try {
        IlvCADRGTocReader tocReader = new IlvCADRGTocReader(file.getPath());
        // Get all coverage info
        Object list= CADRGDefLess.newIlvCADRGCoverageList();
         CADRGDefLess.addCoverages(list,file.getPath(), tocReader.getCoverages());
        String scaleDesc[] = CADRGDefLess.getOrderedScaleDescription(list);
        scaleSelection = new JCheckBox[scaleDesc.length];
        GridBagConstraints c=new GridBagConstraints();
        for (int i = 0; i < scaleDesc.length; i++) {
          scaleSelection[i] = new JCheckBox(scaleDesc[i],true);
          scaleSelection[i].setOpaque(false);
          c.gridy=scaleDesc.length-i;
          c.anchor=GridBagConstraints.LINE_START;
          accessory.add(scaleSelection[i], c);
        }
      } catch (IOException e) {
        // ignore
      }
    }
    if (accessory.getComponentCount() == 0) {
      accessory.add(noData);
    }
    accessoryPane.updateUI();
  }
  /**
   * @see plugins.ImportAction#selectedURLChanged(URL)
   */
  public void selectedURLChanged(URL url) {
    if (url != null) {
      selectedFileChanged(new File(url.getFile()));
    } else {
      selectedFileChanged(null);
    }
  }
  /**
   * @see plugins.ImportAction#approveSelection(File [])
   */
  public boolean approveSelection(File selection[]) {
    boolean ok = false;
    if (scaleSelection != null) {
      for (int i = 0; i < scaleSelection.length; i++) {
        if (scaleSelection[i].isSelected()) {
          ok = true;
          break;
        }
      }
    }
    if (!ok) {
      JOptionPane.showMessageDialog(view, IlvMapUtil.getString(VMAPLoadAction.class, "CADRGLoadAction.NoSelectionMessage"), //$NON-NLS-1$
          IlvMapUtil.getString(VMAPLoadAction.class, "CADRGLoadAction.NoSelectionTitle"),//$NON-NLS-1$
          JOptionPane.ERROR_MESSAGE);
      return false;
    }
    return super.approveSelection(selection);
  }
  /**
   * @see plugins.ImportAction#getDataSources(java.lang.String[])
   */
  public Enumeration getDataSources(String fileNames[]) throws IOException {
    // IlvCADRGCoverageList covs = new IlvCADRGCoverageList();
    Object covs = CADRGDefLess.newIlvCADRGCoverageList();
    IlvCADRGTocReader readers[] = new IlvCADRGTocReader[fileNames.length];
    for (int i = 0; i < fileNames.length; i++) {
      readers[i] = new IlvCADRGTocReader(fileNames[i]);
      //covs.addCoverages(fileNames[i], readers[i].getCoverages());
      CADRGDefLess.addCoverages(covs, fileNames[i], readers[i].getCoverages());
    }
    return new CADRGEnumeration(fileNames, covs);
  }
  /**
   * @see plugins.ImportAction#getDataSources(URL[])
   */
  public Enumeration getDataSources(URL urls[]) throws IOException {
    // IlvCADRGCoverageList covs = new IlvCADRGCoverageList();
    Object covs = CADRGDefLess.newIlvCADRGCoverageList();
    IlvCADRGTocReader readers[] = new IlvCADRGTocReader[urls.length];
    for (int i = 0; i < urls.length; i++) {
      readers[i] = new IlvCADRGTocReader(urls[i]);
      //covs.addCoverages(fileNames[i], readers[i].getCoverages());
      CADRGDefLess.addCoverages(covs, urls[i], readers[i].getCoverages());
    }
    return new CADRGEnumeration(urls, covs);
  }



  /**
   * @see plugins.ImportAction#getExtensions()
   */
  public String[] getExtensions() {
    return new String[] { ".toc"}; //$NON-NLS-1$
  }

  /**
   * @see plugins.ImportAction#getFormatName()
   */
  public String getFormatName() {
    return ilog.views.maps.IlvMapUtil.getString(getClass(), "CADRGLoadAction.FormatName"); //$NON-NLS-1$
  }
  
  /**
   * @see plugins.ImportAction#isAvailable()
   */
  public boolean isAvailable() {
    return super.isAvailable() && CADRGDefLess.isAvailable();
  }
}