/****************************************************************************
Copyright 2007 Virginia Polytechnic Institute and State University
This file is part of the OSSIE __COMP_NAME__.
OSSIE __COMP_NAME__ is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
"(at your option) any later version
OSSIE __COMP_NAME__ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OSSIE __COMP_NAME__; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
****************************************************************************/

#include <string>
#include <iostream>
#include "voiceToPacket.h"

#include <cstdio>

voiceToPacket_i::voiceToPacket_i(const char *uuid, omni_condition *condition) :
    Resource_impl(uuid), component_running(condition)
{
    dataIn_0 = new standardInterfaces_i::complexShort_p("samplesIn");
    packetHeaderDataOut = new standardInterfaces_i::realChar_u("headerOut");
    packetPayloadDataOut = new standardInterfaces_i::realChar_u("payloadOut");
    start();

	header_len = 14;
	verbose = true;
	packet_delay = 1000;

	packet_id = 0;

}

voiceToPacket_i::~voiceToPacket_i(void)
{
    delete dataIn_0;
    delete packetHeaderDataOut;
    delete packetPayloadDataOut;
}

// Static function for omni thread
void voiceToPacket_i::Run( void * data )
{
    ((voiceToPacket_i*)data)->ProcessData();
}

CORBA::Object_ptr voiceToPacket_i::getPort( const char* portName ) throw (
    CORBA::SystemException, CF::PortSupplier::UnknownPort)
{
    DEBUG(3, voiceToPacket, "getPort() invoked with " << portName)

    CORBA::Object_var p;

    p = dataIn_0->getPort(portName);

    if (!CORBA::is_nil(p))
        return p._retn();

    p = packetHeaderDataOut->getPort(portName);

    if (!CORBA::is_nil(p))
        return p._retn();

    p = packetPayloadDataOut->getPort(portName);

    if (!CORBA::is_nil(p))
        return p._retn();

    /*exception*/
    throw CF::PortSupplier::UnknownPort();
}

void voiceToPacket_i::start() throw (CORBA::SystemException,
    CF::Resource::StartError)
{
    DEBUG(3, voiceToPacket, "start() invoked")
	omni_mutex_lock  l(processing_mutex);
	if( false == thread_started )
	{
		thread_started = true;
		// Create the thread for the writer's processing function
		processing_thread = new omni_thread(Run, (void *) this);

		// Start the thread containing the writer's processing function
		processing_thread->start();
	}
}

void voiceToPacket_i::stop() throw (CORBA::SystemException, CF::Resource::StopError)
{
    DEBUG(3, voiceToPacket, "stop() invoked")
	omni_mutex_lock l(processing_mutex);
	thread_started = false;
}

void voiceToPacket_i::releaseObject() throw (CORBA::SystemException,
    CF::LifeCycle::ReleaseError)
{
    DEBUG(3, voiceToPacket, "releaseObject() invoked")

    component_running->signal();
}

void voiceToPacket_i::initialize() throw (CF::LifeCycle::InitializeError,
    CORBA::SystemException)
{
    DEBUG(3, voiceToPacket, "initialize() invoked")
}

void voiceToPacket_i::query( CF::Properties & configProperties ) throw (CORBA::SystemException, CF::UnknownProperties)
{
	if( configProperties.length() == 0 )
	{
		configProperties.length( propertySet.length() );
		for( unsigned int i = 0; i < propertySet.length(); i++ )
		{
			configProperties[i].id = CORBA::string_dup( propertySet[i].id );
			configProperties[i].value = propertySet[i].value;
		}
		return;
	} else {
		for( unsigned int i = 0; i < configProperties.length(); i++ ) {
			for( unsigned int j = 0; j < propertySet.length(); j++ ) {
				if( strcmp(configProperties[i].id, propertySet[j].id) == 0 ) {
					configProperties[i].value = propertySet[j].value;
				}
			}
		}
	} // end if-else
}

void voiceToPacket_i::configure(const CF::Properties& props)
throw (CORBA::SystemException,
    CF::PropertySet::InvalidConfiguration,
    CF::PropertySet::PartialConfiguration)
{
    DEBUG(3, voiceToPacket, "configure() invoked")

    static int init = 0;
    if( init == 0 ) {
        if( props.length() == 0 ) {
            std::cout << "configure called with invalid props.length - " << props.length() << std::endl;
            return;
        }
        propertySet.length(props.length());
        for( unsigned int j=0; j < props.length(); j++ ) {
            propertySet[j].id = CORBA::string_dup(props[j].id);
            propertySet[j].value = props[j].value;
        }
        init = 1;
    }

    std::cout << "props length : " << props.length() << std::endl;

    for ( unsigned int i = 0; i <props.length(); i++)
    {
        std::cout << "Property id : " << props[i].id << std::endl;

        if (strcmp(props[i].id, "DCE:bce93bb6-d3de-11e0-94b5-001aa0b89dbf") == 0)
        {
            CORBA::Short simple_temp;
            props[i].value >>= simple_temp;
            simple_0_value = simple_temp;
            for( unsigned int k = 0; k < propertySet.length(); k++ ) {
                if( strcmp(propertySet[k].id, props[i].id) == 0 ) {
                    propertySet[k].value = props[i].value;
                    break;
                }
            }
        }

        if (strcmp(props[i].id, "DCE:cfa68aec-d3de-11e0-b0db-001aa0b89dbf") == 0)
        {
            CORBA::Short simple_temp;
            props[i].value >>= simple_temp;
            simple_1_value = simple_temp;
            for( unsigned int k = 0; k < propertySet.length(); k++ ) {
                if( strcmp(propertySet[k].id, props[i].id) == 0 ) {
                    propertySet[k].value = props[i].value;
                    break;
                }
            }
        }

        if (strcmp(props[i].id, "DCE:df88e05e-d3de-11e0-aeb7-001aa0b89dbf") == 0)
        {
            CORBA::Short simple_temp;
            props[i].value >>= simple_temp;
            simple_2_value = simple_temp;
            for( unsigned int k = 0; k < propertySet.length(); k++ ) {
                if( strcmp(propertySet[k].id, props[i].id) == 0 ) {
                    propertySet[k].value = props[i].value;
                    break;
                }
            }
        }

        if (strcmp(props[i].id, "DCE:ff76e0d2-d3de-11e0-9af0-001aa0b89dbf") == 0)
        {
            CORBA::Boolean simple_temp;
            props[i].value >>= simple_temp;
            simple_3_value = simple_temp;
            for( unsigned int k = 0; k < propertySet.length(); k++ ) {
                if( strcmp(propertySet[k].id, props[i].id) == 0 ) {
                    propertySet[k].value = props[i].value;
                    break;
                }
            }
        }

    }
}

void voiceToPacket_i::ProcessData()
{
    DEBUG(3, voiceToPacket, "ProcessData() invoked")

    PortTypes::CharSequence headerData;
    PortTypes::CharSequence payloadData;

    PortTypes::ShortSequence *I_in_0(NULL), *Q_in_0(NULL);

    while(continue_processing())
    {
        dataIn_0->getData(I_in_0, Q_in_0);

		payload_len = I_in_0->length();	

		headerData.length(header_len);
		payloadData.length(payload_len);

		// generate header data
		unsigned int i;
		for (i = 0; i<header_len; i++)
		{
			headerData[i] = (i == 0) ? packet_id & 0xff : 0;
		}

		// take voice samples, put into payload
		for (i = 0; i<payload_len; i++)
		{
			payloadData[i] = (*I_in_0)[i] & 0xff;
			printf("%d",payloadData[i]);

		}


        dataIn_0->bufferEmptied();
        packetHeaderDataOut->pushPacket(headerData);
        packetPayloadDataOut->pushPacket(payloadData);
    }
}

bool voiceToPacket_i::continue_processing()
{
	omni_mutex_lock l(processing_mutex);
	return thread_started;
}


