import RTIcap.*;

/**
*
* Simulated Country object. This object knows the state of Country Object
* and it can produce the necessary state update messages for required
* attributes to the RTI so that other interested federates can receive 
* these updates.
*
* @date May 11, 1998 ( Updated May 11, 1998 )
* @author H. Timucin Ozdemir
*
*/
public class
SimCountry extends Country
{
 
   double grRate = 0.5;
   RTIcap.RTIambassador rtiAmb;
   HelloWorld   boss;
   boolean  sendNameUpdateFlag = true;
   boolean  sendPopuUpdateFlag = true;
   boolean  nameChanged = true;
   boolean  popuChanged = true;

   /**
   */
   public 
   SimCountry( RTIcap.RTIambassador _rtiAmb, HelloWorld _father, int _ObjectID) 
   { 
      rtiAmb = _rtiAmb;
      setObjectID(_ObjectID);
      boss = _father;
      resetNameChanged(); resetPopuChanged();

   }// end of CONSTRUCTOR

   /**
   */
   public 
   SimCountry( RTIcap.RTIambassador _rtiAmb, HelloWorld _father, String _name, 
               double _initialPopulation , int _ObjectID)
   {
      rtiAmb = _rtiAmb;
      setName(_name);
      setPopulation(_initialPopulation);
      setObjectID(_ObjectID);
      boss = _father;
      setNameChanged(); setPopuChanged();

   }// end of CONSTRUCTOR

   /**
   *
   * After each time adavancement in the Main simulation loop,
   * this method will be invoked. So that object can update its state,
   * and broadcast its updates if it is necessary.
   *
   */
   public final void
   UpdateTime( double time )
   {
      double diff = time - currentTime;

      if( diff > 0 )
      {
         setCurrentTime(time);
       
         /*******************************/
         /** Set the population changed */
         /*******************************/
         setPopuChanged();
         UpdatePopulation(myPopulation+diff*grRate);

         UpdateName( getName() );

      }// end of if

   }// end of Update()

   /**
   */
   public final void
   UpdateName( String cntName )
   {

      setName(cntName);

      /********************************************************************/
      /** If we are allowed to send this update and name is changed, then */
      /** we will send this update message to the RTI.                    */
      /********************************************************************/
      if( rtiAmb != null && sendNameUpdateFlag && isNameChanged() )
      {
           
          RTIcap.AttributeHandleValuePair[] eles = new RTIcap.AttributeHandleValuePair[1];
                
              
          eles[0] = new RTIcap.AttributeHandleValuePair(boss.getNameAttributeId(), 
                                                     myCountryName.getBytes()); 
          try
          {   
              rtiAmb.updateAttributeValues(ObjectID,eles,"name");

              /******************************************************/
              /** Since we sent this update, we no longer required  */
              /** to send it again. Unless we are asked to do so    */
              /** ( Look at provideAttributesUpdates )              */ 
              /******************************************************/
              resetNameChanged();

          } catch (RTIcap.ObjectNotKnown onk) {}
            catch (RTIcap.AttributeNotDefined onk) {}
            catch (RTIcap.AttributeNotOwned onk) {}
            catch (RTIcap.FederateNotExecutionMember onk) {}
            catch (RTIcap.SaveInProgress onk) {}
            catch (RTIcap.RestoreInProgress onk) {}
            catch (RTIcap.RTIinternalError onk) {}

      }// end of if

   }// end of Update()

   /**
   */
   public final void
   UpdatePopulation( double newPop )
   {
      myPopulation = newPop ;

      /********************************************************************/
      /** If we are allowed to send this update and population is changed,*/ 
      /** then we will send this update message to the RTI.               */
      /********************************************************************/
      if( rtiAmb != null && sendPopuUpdateFlag && isPopuChanged() )
      {
           
          RTIcap.AttributeHandleValuePair[] eles = new RTIcap.AttributeHandleValuePair[1];
              
          eles[0] = new RTIcap.AttributeHandleValuePair(
                        boss.getPopuAttributeId(),
                        Double.toString(myPopulation).getBytes()); 
          try
          {   
            rtiAmb.updateAttributeValues(ObjectID,eles,"population");

            resetPopuChanged();

          } catch (RTIcap.ObjectNotKnown onk) {}
            catch (RTIcap.AttributeNotDefined onk) {}
            catch (RTIcap.AttributeNotOwned onk) {}
            catch (RTIcap.FederateNotExecutionMember onk) {}
            catch (RTIcap.SaveInProgress onk) {}
            catch (RTIcap.RestoreInProgress onk) {}
            catch (RTIcap.RTIinternalError onk) {}

      }// end of if

   }// end of Update()

   /**
   *
   * turnUpdates[On/Off]ForObjectInstance in HwFederateAmbassador uses 
   * this method to tell this object to start sending attribute updates.
   *
   */
   public final void
   UpdateControls( boolean status, short[] theAttributes )
   {
      for(int i=0;i < theAttributes.length;i++)
         if( theAttributes[i] == boss.getPopuAttributeId() )
                sendPopuUpdateFlag = status;
         else if( theAttributes[i] == boss.getNameAttributeId() )
                sendNameUpdateFlag = status;

   }// end of UpdateControls()

   public final void setNameChanged()   { nameChanged = true; }
   public final void resetNameChanged() { nameChanged = false; }
   public final boolean isNameChanged() { return nameChanged ; }

   public final void setPopuChanged()   { popuChanged = true; }
   public final void resetPopuChanged() { popuChanged = false; }
   public final boolean isPopuChanged() { return popuChanged ; }

}// end of SimCountry