package jp.co.yaskawa.rtc.dataDistributor;
// -*- Java -*-
/*!
 * @file  DataDistributorImpl.java
 * @brief ${rtcParam.description}
 * @date  $Date$
 *
 * $Id$
 */

import RTC.Time;
import RTC.TimedDoubleSeq;
import jp.go.aist.rtm.RTC.DataFlowComponentBase;
import jp.go.aist.rtm.RTC.Manager;
import jp.go.aist.rtm.RTC.port.ConnectorDataListenerT;
import jp.go.aist.rtm.RTC.port.ConnectorDataListenerType;
import jp.go.aist.rtm.RTC.port.InPort;
import jp.go.aist.rtm.RTC.port.OutPort;
import jp.go.aist.rtm.RTC.port.ConnectorBase.ConnectorInfo;
import jp.go.aist.rtm.RTC.util.DataRef;
import jp.go.aist.rtm.RTC.util.StringHolder;
import RTC.ReturnCode_t;

/*!
 * @class DataDistributorImpl
 * @brief ${rtcParam.description}
 *
 */
public class DataDistributorImpl extends DataFlowComponentBase {

  /*!
   * @brief constructor
   * @param manager Maneger Object
   */
	public DataDistributorImpl(Manager manager) {  
        super(manager);
        // <rtc-template block="initializer">
        m_data_in_val = new TimedDoubleSeq();
        m_data_in = new DataRef<TimedDoubleSeq>(m_data_in_val);
        m_data_inIn = new InPort<TimedDoubleSeq>("data_in", m_data_in);
        m_data_out1_val = new TimedDoubleSeq();
        m_data_out1 = new DataRef<TimedDoubleSeq>(m_data_out1_val);
        m_data_out1Out = new OutPort<TimedDoubleSeq>("data_out1", m_data_out1);
        m_data_out2_val = new TimedDoubleSeq();
        m_data_out2 = new DataRef<TimedDoubleSeq>(m_data_out2_val);
        m_data_out2Out = new OutPort<TimedDoubleSeq>("data_out2", m_data_out2);
        m_data_out3_val = new TimedDoubleSeq();
        m_data_out3 = new DataRef<TimedDoubleSeq>(m_data_out3_val);
        m_data_out3Out = new OutPort<TimedDoubleSeq>("data_out3", m_data_out3);
        // </rtc-template>
        
//        m_data_out1.v.data = new double[20];
        m_data_out1.v.data = new double[22];
        m_data_out1.v.tm = new Time();        
        m_data_out2.v.data = new double[20];
        m_data_out2.v.tm = new Time();        

    }

    /*!
     *
     * The initialize action (on CREATED->ALIVE transition)
     * formaer rtc_init_entry() 
     *
     * @return RTC::ReturnCode_t
     * 
     * 
     */
    @Override
    protected ReturnCode_t onInitialize() {
        // Registration: InPort/OutPort/Service
        // <rtc-template block="registration">
        // Set InPort buffers
        addInPort("data_in", m_data_inIn);
        
        // Set OutPort buffer
        addOutPort("data_out1", m_data_out1Out);
        addOutPort("data_out2", m_data_out2Out);
        addOutPort("data_out3", m_data_out3Out);
        // </rtc-template>

        m_data_inIn.addConnectorDataListener(
        		ConnectorDataListenerType.ON_BUFFER_WRITE,
        		new DataListener("ON_BUFFER_WRITE"),
        		false
        		);
        
        return super.onInitialize();
    }

    /***
     *
     * The finalize action (on ALIVE->END transition)
     * formaer rtc_exiting_entry()
     *
     * @return RTC::ReturnCode_t
     * 
     * 
     */
//    @Override
//    protected ReturnCode_t onFinalize() {
//        return super.onFinalize();
//    }

    /***
     *
     * The startup action when ExecutionContext startup
     * former rtc_starting_entry()
     *
     * @param ec_id target ExecutionContext Id
     *
     * @return RTC::ReturnCode_t
     * 
     * 
     */
//    @Override
//    protected ReturnCode_t onStartup(int ec_id) {
//        return super.onStartup(ec_id);
//    }

    /***
     *
     * The shutdown action when ExecutionContext stop
     * former rtc_stopping_entry()
     *
     * @param ec_id target ExecutionContext Id
     *
     * @return RTC::ReturnCode_t
     * 
     * 
     */
//    @Override
//    protected ReturnCode_t onShutdown(int ec_id) {
//        return super.onShutdown(ec_id);
//    }

    /***
     *
     * The activated action (Active state entry action)
     * former rtc_active_entry()
     *
     * @param ec_id target ExecutionContext Id
     *
     * @return RTC::ReturnCode_t
     * 
     * 
     */
    @Override
    protected ReturnCode_t onActivated(int ec_id) {
        return super.onActivated(ec_id);
    }

    /***
     *
     * The deactivated action (Active state exit action)
     * former rtc_active_exit()
     *
     * @param ec_id target ExecutionContext Id
     *
     * @return RTC::ReturnCode_t
     * 
     * 
     */
    @Override
    protected ReturnCode_t onDeactivated(int ec_id) {
        return super.onDeactivated(ec_id);
    }

    /***
     *
     * The execution action that is invoked periodically
     * former rtc_active_do()
     *
     * @param ec_id target ExecutionContext Id
     *
     * @return RTC::ReturnCode_t
     * 
     * 
     */
    @Override
    protected ReturnCode_t onExecute(int ec_id) {
 
    	if (m_data_inIn.isNew()) {
    		m_data_inIn.read();
/*    		
			for (int i=0; i<m_data_in_val.data.length; i++) {
				m_data_out1_val.data[i] = m_data_in_val.data[i];
				m_data_out2_val.data[i] = m_data_in_val.data[i];
			}
			m_data_out1Out.write();
			m_data_out2Out.write();
*/    		
    	}
    	
        return super.onExecute(ec_id);
    }

    /***
     *
     * The aborting action when main logic error occurred.
     * former rtc_aborting_entry()
     *
     * @param ec_id target ExecutionContext Id
     *
     * @return RTC::ReturnCode_t
     * 
     * 
     */
//  @Override
//  public ReturnCode_t onAborting(int ec_id) {
//      return super.onAborting(ec_id);
//  }

    /***
     *
     * The error action in ERROR state
     * former rtc_error_do()
     *
     * @param ec_id target ExecutionContext Id
     *
     * @return RTC::ReturnCode_t
     * 
     * 
     */
//    @Override
//    public ReturnCode_t onError(int ec_id) {
//        return super.onError(ec_id);
//    }

    /***
     *
     * The reset action that is invoked resetting
     * This is same but different the former rtc_init_entry()
     *
     * @param ec_id target ExecutionContext Id
     *
     * @return RTC::ReturnCode_t
     * 
     * 
     */
//    @Override
//    protected ReturnCode_t onReset(int ec_id) {
//        return super.onReset(ec_id);
//    }

    /***
     *
     * The state update action that is invoked after onExecute() action
     * no corresponding operation exists in OpenRTm-aist-0.2.0
     *
     * @param ec_id target ExecutionContext Id
     *
     * @return RTC::ReturnCode_t
     * 
     * 
     */
//    @Override
//    protected ReturnCode_t onStateUpdate(int ec_id) {
//        return super.onStateUpdate(ec_id);
//    }

    /***
     *
     * The action that is invoked when execution context's rate is changed
     * no corresponding operation exists in OpenRTm-aist-0.2.0
     *
     * @param ec_id target ExecutionContext Id
     *
     * @return RTC::ReturnCode_t
     * 
     * 
     */
//    @Override
//    protected ReturnCode_t onRateChanged(int ec_id) {
//        return super.onRateChanged(ec_id);
//    }
//
	// Configuration variable declaration
	// <rtc-template block="config_declare">
    /*!
     * 
     * - Name:  configFile
     * - DefaultValue: default.conf
     */
    protected StringHolder m_configFile = new StringHolder();
	// </rtc-template>

    // DataInPort declaration
    // <rtc-template block="inport_declare">
    protected TimedDoubleSeq m_data_in_val;
    protected DataRef<TimedDoubleSeq> m_data_in;
    /*!
     */
    protected InPort<TimedDoubleSeq> m_data_inIn;

    
    // </rtc-template>

    // DataOutPort declaration
    // <rtc-template block="outport_declare">
    protected TimedDoubleSeq m_data_out1_val;
    protected DataRef<TimedDoubleSeq> m_data_out1;
    /*!
     */
    protected OutPort<TimedDoubleSeq> m_data_out1Out;

    protected TimedDoubleSeq m_data_out2_val;
    protected DataRef<TimedDoubleSeq> m_data_out2;
    /*!
     */
    protected OutPort<TimedDoubleSeq> m_data_out2Out;

    protected TimedDoubleSeq m_data_out3_val;
    protected DataRef<TimedDoubleSeq> m_data_out3;
    /*!
     */
    protected OutPort<TimedDoubleSeq> m_data_out3Out;

    
    // </rtc-template>

    // CORBA Port declaration
    // <rtc-template block="corbaport_declare">
    
    // </rtc-template>

    // Service declaration
    // <rtc-template block="service_declare">
    
    // </rtc-template>

    // Consumer declaration
    // <rtc-template block="consumer_declare">
    
    // </rtc-template>

    class DataListener extends ConnectorDataListenerT<TimedDoubleSeq>{
        public DataListener(final String name){
            super(TimedDoubleSeq.class);
            m_name = name;
        }
        public String m_name;
		@Override
		public void operator(ConnectorInfo info, TimedDoubleSeq inData) {
			for (int i=0; i<13; i++) {
				m_data_out1_val.data[i] = inData.data[i];
			}
			for (int i=13; i<19; i++) {
				m_data_out1_val.data[i+1] = inData.data[i];
			}
			for (int i=0; i<inData.data.length; i++) {
//				m_data_out1_val.data[i] = inData.data[i];
				m_data_out2_val.data[i] = inData.data[i];
			}
			m_data_out1Out.write();
			m_data_out2Out.write();
		}
		
    }

}
