/*
 * CorbaHist1DAdapter.java
 *
 * Created on June 12, 2003, 5:54 PM
 */

package hep.aida.ref.remote.testRemote.converters;

//import hep.aida.dev.IConverter;
import hep.aida.IAnnotation;
import hep.aida.IAxis;
import hep.aida.IDataPoint;
import hep.aida.IDataPointSet;
import hep.aida.IMeasurement;
import hep.aida.IManagedObject;
import hep.aida.ref.Annotation;

import hep.aida.ref.histogram.DataPointSet;
import hep.aida.ref.remote.RemoteDataPointSet;

/**
 * Converts Hist1DData to RemoteHistogram1D
 * @author  serbo
 */
public final class TestDataPointSetConverter extends TestConverter {
    
    private static TestDataPointSetConverter converter = null;
    
    /** Creates a new instance of CorbaHist1DAdapter */
    public static TestDataPointSetConverter getInstance() {
        if (converter == null) converter = new TestDataPointSetConverter();
        return converter;
    }
    
    private TestDataPointSetConverter() {
        super();
        dataType = "IDataPointSet";
        aidaType = "IDataPointSet";
    }
    
    
    /**
     * Creates new instance of type "type".
     */
    public Object createAidaObject(String name) {
        RemoteDataPointSet result = new RemoteDataPointSet(name);        
        return result;
    }
    
    /**
     * Updates data contained by object.
     * Input must be IHistogram1D.
     */
    public boolean updateAidaObject(Object aidaObject, Object newData) {
        IDataPointSet data = null;
        if (newData instanceof IDataPointSet) {
            data = (IDataPointSet) newData;
        }
        
        if (!(aidaObject instanceof hep.aida.ref.remote.RemoteDataPointSet))
            throw new IllegalArgumentException("Not supported object type: "+aidaObject.getClass().getName());
        if (!(data instanceof IDataPointSet))
            throw new IllegalArgumentException("Not supported data type: "+(data == null ? "null" : newData.getClass().getName()));

        updateData((RemoteDataPointSet) aidaObject, data);
        return true;
    }
  
    /**
     * Returns IHistogram1D object
     */
    public Object extractData(Object aidaObject) {
        if (!(aidaObject instanceof hep.aida.IDataPointSet))
            throw new IllegalArgumentException("Not supported data type: "+aidaObject.getClass().getName());

        IDataPointSet data = null;
        synchronized (aidaObject) {
            data = createData((hep.aida.IDataPointSet) aidaObject);
        }
        
        return data;
    }
  
    
   /**
    * Update data in RemoteHistogram1d from IHistogram1D
    * and calls setDataValid(true) method.
    */ 
   public IManagedObject updateData(RemoteDataPointSet hist, IDataPointSet data)
   {
       hist.setFillable(true);
       
      
      // Check and set Annotation
      if (data.annotation() != null && data.annotation().size() > 0) {
          boolean sticky = false;
          IAnnotation localAnnotation = hist.annotation();
          if (localAnnotation instanceof Annotation)  
              ((Annotation) localAnnotation).setFillable(true);
          for (int i=0; i<data.annotation().size(); i++) {
              String key = data.annotation().key(i);
              String newValue = data.annotation().value(key);
              String oldValue = null;
              try {
                  oldValue = localAnnotation.value(key);
              } catch (IllegalArgumentException e) {}
              if (oldValue == null) localAnnotation.addItem(key, newValue, sticky);
              else if (!newValue.equals(oldValue)) {
                  localAnnotation.setValue(key,  newValue);
                  localAnnotation.setSticky(key,  sticky);
              }
          }
          if (localAnnotation instanceof Annotation)  
              ((Annotation) localAnnotation).setFillable(false);          
      }
      
         int dimension    = 0;
         double[] upperExtent = null;
         double[] lowerExtent = null;
         double[] values      = null;
         double[] plusErrors  = null;
         double[] minusErrors = null;

         int nPoints = data.size();
        dimension = data.dimension();

        // Get information
        if (nPoints > 0) {
            upperExtent = new double[dimension];
            lowerExtent = new double[dimension];
            values = new double[dimension*nPoints];
            plusErrors = new double[dimension*nPoints];
            minusErrors = new double[dimension*nPoints];

            for (int dim=0; dim<dimension; dim++) {
                upperExtent[dim] = data.upperExtent(dim);
                lowerExtent[dim] = data.lowerExtent(dim);
            }

            int index = 0;
            for (int ip=0; ip<nPoints; ip++) {
                IDataPoint p = data.point(ip);
                for (int dim=0; dim<dimension; dim++) {
                    index = ip*dimension+dim;
                    IMeasurement m = p.coordinate(dim);
                    values[index]      = m.value();
                    plusErrors[index]  = m.errorPlus();
                    minusErrors[index] = m.errorMinus();
                }                     
            }
        }
      
      synchronized (hist) {
        // Set all the information
        hist.setDimension(dimension);
        hist.setUpperExtent(upperExtent);
        hist.setLowerExtent(lowerExtent);
        hist.setValues(values);
        hist.setPlusErrors(plusErrors);
        hist.setMinusErrors(minusErrors);

        hist.setFillable(false);
        hist.setDataValid(true);
      }

      System.out.println("TestDataPointSetConverter: Data: name="+data.title()+", dim="+data.dimension()+", size="+data.size());
      System.out.println("TestDataPointSetConverter: Hist: name="+hist.title()+", dim="+hist.dimension()+", size="+hist.size());
      return hist;
   }
   
   /**
    * Create Hist1DData structure from an IHistogram1D
    */
    public IDataPointSet createData(IDataPointSet hist) {
        IDataPointSet data = hist;

        return data;
    } 
    
}
