/////////////////////////////////////////////////////////////////////////
//
// © University of Southampton IT Innovation Centre, 2004
//
// Copyright in this library belongs to the IT Innovation Centre of
// 2 Venture Road, Chilworth Science Park, Southampton, SO16 7NP, UK.
//
// This software may not be used, sold, licensed, transferred, copied
// or reproduced in whole or in part in any manner or form or in or
// on any media by any person other than in accordance with the terms
// of the Licence Agreement supplied with the software, or otherwise
// without the prior written consent of the copyright owners.
//
// This software is distributed WITHOUT ANY WARRANTY, without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE, except where stated in the Licence Agreement supplied with
// the software.
//
//      Created by:             Stuart E. Middleton
//      Created date:           2004/04/30
//      Created for project:    GEMSS
//
/////////////////////////////////////////////////////////////////////////
//
//      Dependencies: ISS, NEC and IT Innovation jointly designed this
//      interface class as part of the GEMSS project design discussions.
//      The code itself was written by IT Innovation alone.
//
/////////////////////////////////////////////////////////////////////////
//
//      Last commit info:       $Author: $
//                              $Date: $
//                              $Revision: $
//
/////////////////////////////////////////////////////////////////////////

package eu.gemss.signals.negotiation;

import java.util.Vector;
import eu.gemss.signals.Signal;

/**
 * A signal for requesting QoS parameters
 */
public class GetQoSParametersRequest extends Signal {

      // request type
      public static final String SIGNAL_TYPE = "eu.gemss.signals.negotiation.GetQoSParametersRequest";
//      public static final String mstaticSignalType = SIGNAL_TYPE;
      public static final int mstaticBooleanUnitFlag = 1;
      public static final int mstaticGMT2000DateOffsetUnitFlag = 2;
      public static final int mstaticDoubleUnitFlag = 3;
      public static final int mstaticLongUnitFlag = 4;

      // request data
      private Vector mvectorProperties;    // vector of vectors of properties vector
      // properties vector contains (name, desc, unit type, unit desc, weight, min, max) all strings except unit type which is an Integer
      private String mstrOverallDescription;
      private boolean mbFailed; // true if signal handler fails to process request for some reason

      /**
       * Default constructor
       * @param source object that generated the request
       */
      public GetQoSParametersRequest( Object source )
      {
            super(source);
            // init
            mvectorProperties = new Vector();
            mbFailed = false;
      }


      /**
       * Add properties to a label. You can have multiple properties of the same name, but it is not advised.
       * @param strName name of the property
       * @param strDesc Human readable description for this property
       * @param nUnitType Flag to indicate unit type (default should be 0 - text)
       * @param strUnitDesc unit description
       * @param strWeight default weight (importance 0 .. 1) for this property
       * @param strMin default min value for this property
       * @param strMax default max value for this property
       */
      public void addProperty( String strName, String strDesc, Integer nUnitType, String strUnitDesc, String strWeight, String strMin, String strMax ) throws Exception
      {
            Vector vector;

            // checks
            if( mvectorProperties == null ) throw new Exception("property vector is null");

            // make and add property to main vector
            vector = new Vector();
            vector.addElement( strName );
            vector.addElement( strDesc );
            vector.addElement( nUnitType );
            vector.addElement( strUnitDesc );
            vector.addElement( strWeight );
            vector.addElement( strMin );
            vector.addElement( strMax );
            mvectorProperties.addElement( vector );
      }

      /**
       * Get number of properties.
       * @return number of properties in the current list
       */
      public int getSize() throws Exception
      {
            if( mvectorProperties == null ) throw new Exception("property vector is null");
            return mvectorProperties.size();
      }

      /**
       * Set failed flag
       */
      public void setFailed()
      {
            mbFailed = true;
      }

      /**
       * Get the failed flag
       * @return true if the signal handler explictly failed to handle the signal
       */
      public boolean getFailed()
      {
            return mbFailed;
      }

      /**
       * Get property by index - will throw exception if i > size
       * @param nIndex index for the required property
       * @return property vector (name, desc, unit type, unit desc, weight, min, max) all strings except unit type which is an Integer
       */
      public Vector getPropertyByIndex( int nIndex ) throws Exception
      {
            if( mvectorProperties == null ) throw new Exception("property vector is null");
            if( mvectorProperties.size() <= nIndex ) throw new Exception("index "+nIndex+" is greater than property vector's size");
            return (Vector) mvectorProperties.elementAt( nIndex );
      }

      /**
       * Get property by name - returns null if no match found
       * @param strName name of the required property
       * @return property vector (name, desc, unit type, unit desc, weight, min, max) all strings except unit type which is an Integer
       */
      public Vector getPropertyByName( String strName ) throws Exception
      {
            int i;
            Vector vector;

            // checks
            if( mvectorProperties == null ) throw new Exception("property vector is null");

            // find first match
            for( i=0;i<mvectorProperties.size();i++ ) {
                  vector = (Vector) mvectorProperties.elementAt( i );

                  // checks
                  if( vector == null ) throw new Exception("null property found");
                  if( vector.size() != 7 ) throw new Exception("invalid property size of "+vector.size()+" (should be 7)");

                  // do match
                  if( strName.equals( (String) vector.elementAt(0) ) ) {
                        // found it
                        return vector;
                  }
            }

            // no match
            return null;
      }

      /**
       * Set an existing properties value
       * @param strName of the existing property
       * @param strDesc new human readable description for this property
       * @param nUnitType Unit type flag
       * @param strUnitDesc Unit description
       * @param strWeight new weight
       * @param strMin new min
       * @param strMax new max
       */
      public void setProperty( String strName, String strDesc, Integer nUnitType, String strUnitDesc, String strWeight, String strMin, String strMax ) throws Exception
      {
            Vector vector;

            // get the proprty vector
            vector = getPropertyByName( strName );
            if( vector == null ) throw new Exception("property "+strName+" not found");
            if( vector.size() != 7 ) throw new Exception("invalid property size of "+vector.size()+" (should be 7)");

            // update this properties value
            vector.setElementAt( strDesc,1 );
            vector.setElementAt( nUnitType,2 );
            vector.setElementAt( strUnitDesc,3 );
            vector.setElementAt( strWeight,4 );
            vector.setElementAt( strMin,5 );
            vector.setElementAt( strMax,6 );
      }

      /**
       * Get the overall description, for example the job name
       * @return overall description string [null if there is none]
       */
      public String getOverallDescription()
      {
            return mstrOverallDescription;
      }

      /**
       * Get the overall description, for example the job name
       * @param strDesc overall description string [null if there is none]
       */
      public void setOverallDescription( String strDesc )
      {
            mstrOverallDescription = strDesc;
      }

      /**
       * Return the signal type - override of the base class
       * @return Signal type
       */
      public String getSignalType()
      {
            return SIGNAL_TYPE;
      }
}