/*=========================================================================

Program:   Orbit Visualization Tool
Source:    $Source: /stor/devel/ovt2g/ovt/object/DataModule.java,v $
Date:      $Date: 2001/03/24 16:55:47 $
Version:   $Revision: 1.7 $


Copyright (c) 2000 OVT Team (Kristof Stasiewicz, Mykola Khotyaintsev,
Yuri Khotyaintsev)
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification is permitted provided that the following conditions are met:

 * No part of the software can be included in any commercial package without
written consent from the OVT team.

 * Redistributions of the source or binary code must retain the above
copyright notice, this list of conditions and the following disclaimer.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT OR
INDIRECT DAMAGES  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE.

OVT Team (http://ovt.irfu.se)   K. Stasiewicz, M. Khotyaintsev, Y.
Khotyaintsev

=========================================================================*/

/*
 * DataModule.java
 *
 * Created on 14 Ноябрь 2000 г., 23:52
 */

package ovt.object;

import vtk.*;

import ovt.*;
import ovt.gui.*;
import ovt.mag.*;
import ovt.beans.*;
import ovt.util.*;
import ovt.event.*;
import ovt.datatype.*;
import ovt.interfaces.*;

import java.beans.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.io.*;

/**
 *
 * @author  ko
 * @version 
 */
public class DataModule extends AbstractSatModule {
    private static final int TIME  = 0;
    private static final int VALUE = 1;
    private static final int X = 0;
    private static final int Y = 1;
    private static final int Z = 2;
    double[][] data = null;
    double max = Double.NEGATIVE_INFINITY;
    double min = Double.POSITIVE_INFINITY;
    
    /** Holds value of property file. */
    private File file = null;
    
    /** Timeset of Data */
    TimeSet dataTimeSet = new TimeSet();
    DataModuleCustomizer customizer;
    
    /** Paint data on fieldlines */
    private boolean onFieldlines = true;
    OrbitDataModule orbitDataModule;
    FieldlineDataModule fieldlineDataModule;
    
    /** Creates new DataModule */
public DataModule(Sat sat) {
  super(sat,  "Data", OVTCore.getImagesDir() + "orbit.gif");
  try {
    descriptors = new Descriptors();
    
    BasicPropertyDescriptor pd = new BasicPropertyDescriptor("file", this);
        pd.setDisplayName("Load ...");
        
    GUIPropertyEditor editor = new FileEditor(pd);
    addPropertyChangeListener("file", editor);
    pd.setPropertyEditor(editor);

    descriptors.put(pd);
    
    setDescriptors(descriptors);
    
    if (!OVTCore.isServer()) {
            customizer = new DataModuleCustomizer(this);
            // can be (visible, customizer). think about it, MAN ;)
            /*pd = new BasicPropertyDescriptor("customizerVisible", this);
            pd.setDisplayName("Customizer Visibility");
        
            editor = new VisibilityEditor(pd);
            editor.setTags(new String[]{"Properties ...", "Hide Properties"});
            addPropertyChangeListener("customizerVisible", editor);
            pd.setPropertyEditor(editor);
            descriptors.put(pd);*/
    }
        
  } catch (IntrospectionException e2) {
        e2.printStackTrace(); System.exit(0);
  }
  
  orbitDataModule  = new OrbitDataModule(this);
  addChild(orbitDataModule);
  
  fieldlineDataModule  = new FieldlineDataModule(this);
  addChild(fieldlineDataModule);
  
}

public double getMax() {
    return max;
}

public double getMin() {
    return min;
}

public TimeSet getDataTimeSet() {
    return dataTimeSet;
}

public double[][] getData() {
    if (data == null) 
        try {
            loadData();
        } catch (IOException e2) {
            getCore().sendErrorMessage("Error Loading Data", e2.getMessage());
        }
    return data;
}

private void loadData() throws IOException {
    if (file == null) {
        if (OVTCore.isGuiPresent()) showFileOpenDialog();
    }
    
    if (file == null) throw new IOException("File is not specified");
    
    max = Double.NEGATIVE_INFINITY;
    min = Double.POSITIVE_INFINITY;
    
    BufferedReader inData = new BufferedReader(new FileReader(this.file));
    StringTokenizer st;
    String line;
    String s1, s2;
      double sec, val;
      double first_mjd = getMjd();
      final double sec_in_day = 24*60*60; //
      Timetable tt = new Timetable();
      while((line = inData.readLine()) != null) {
          //System.out.println(line);
        if (line.startsWith("#")) { // coment
            
            if (line.startsWith("# Time start at:")) { // parse the data start time
                String time = "";
                try {
                    time = line.substring(17, 36);
                    System.out.println("Found Time: '" + time + "'");
                    first_mjd = new Time(time).getMjd();
                } catch (NumberFormatException e2) {
                    throw new IOException("Invalid Time Format : " + time);
                }
            }
        } else {
          st = new StringTokenizer(line, " ");
            
          s1 = st.nextToken();
          s2 = st.nextToken();
            try {
                sec = new Double(s1).doubleValue();
                val = new Double(s2).doubleValue();
                //System.out.println("val = " + val + " max = " + max + " min = " + min);
                tt.put(first_mjd + sec/sec_in_day, new Double(val));
                // set minimum and maximum values
                if (val > max) max = val;
                if (val < min) min = val;
            } catch (NumberFormatException e2) {
                System.err.println("Invalid entrty in " + file + " : " + e2);
            }
        }
      }
      inData.close();
      System.out.println("min=" + min + " max="+ max +" done.");
      data = new double[tt.size()][2];
      Enumeration e = tt.keys();
      int i=0;
      while (e.hasMoreElements())
          data[i++][TIME] = ((Double)e.nextElement()).doubleValue();
      e = tt.elements();
      i=0;
      while (e.hasMoreElements())
          data[i++][VALUE] = ((Double)e.nextElement()).doubleValue(); 
      
      dataTimeSet.setStartMjd(data[0][TIME]);
      dataTimeSet.setIntervalMjd(data[data.length - 1][TIME] - data[0][TIME]);
      dataTimeSet.setStepMjd((dataTimeSet.getStopMjd() - dataTimeSet.getStartMjd()) / 30.);
      System.out.println("Data Time Set: " + dataTimeSet);
      
      if (!getTimeSet().contains(dataTimeSet)) { // set global time set to data time set.
        //try {
            System.out.println("NOT !!!! Seting global time set to Data Time Set");
           // getCore().getTimeSettings().setTimeMap(dataTimeSet);
        //} catch (PropertyVetoException ignore) { ignore.printStackTrace(); }
      }
}

/** Getter for property file.
 * @return Value of property file.
 */
public File getFile() {
  return file;
}

/** Sets the DataFile and Loads the Data
 * @param file New value of property file.
 */
public void setFile(File file) {
  File oldFile = this.file;
  if (!file.exists()) {
      getCore().sendErrorMessage("File '"+ file +"'doesnot exist", "Error Loading Data");
      return;
  }
  this.file = file;
  data = null;
  System.gc(); // run garbage collector
  propertyChangeSupport.firePropertyChange ("file", oldFile, file);
}

private void showFileOpenDialog() {
    if (OVTCore.isGuiPresent()) {
        FileEditor editor = (FileEditor)getDescriptors().getDescriptor("file").getPropertyEditor();
        editor.setOpenDialogVisible(true);
    }
}

/** Getter for property customizerVisible.
 * @return Value of property customizerVisible.
 */
public boolean isCustomizerVisible() {
  if (!OVTCore.isServer()) return customizer.isVisible();
  else return false; 
}

/** Setter for property customizerVisible.
 * @param customizerVisible New value of property customizerVisible.
 */
public void setCustomizerVisible(boolean customizerVisible) {
  if (!OVTCore.isServer()) { 
        boolean oldCustomizerVisible = isCustomizerVisible();
        if (oldCustomizerVisible == customizerVisible) return; // nothing is changed
        customizer.setVisible(customizerVisible);
        propertyChangeSupport.firePropertyChange ("customizerVisible", new Boolean (oldCustomizerVisible), new Boolean (customizerVisible));
  }
}

}