#include "../../config.h"

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <fcntl.h>
#include <unistd.h>

#include <math.h> //zaradi log hv

#include "mpegsound.h"

/* IOCTL */
#ifdef SOUND_VERSION
#define IOCTL(a,b,c)		ioctl(a,b,&c)
#else
#define IOCTL(a,b,c)		(c = ioctl(a,b,c) )
#endif

#include <QRegExp>//hv
//#include <QtGui>

#if defined _LINUX_
char *Rawplayer::defaultdevice=(char*)"pulse: default";//2.65  "pulse: default"  OSS="/dev/dsp"
int Rawplayer::buffering = 1000;
int Rawplayer::pa_sa_rate = 44100;
#endif
#if defined _WIN32_ //Primary Sound Driver or "0"
char *Rawplayer::defaultdevice=(char*)"Primary Sound Driver";
int Rawplayer::buffering = 1000;//1.42 600 to 1000 default
#endif

//bool Rawplayer::defaultdrv=false; //hv
 
//static char *saved_device;
static int buff_hv;
/*
#if defined _LINUX_
static int saved_volume_mixer;//hv zaradi smqnata na dsp
#endif
*/
// Volume 
/*
int Rawplayer::setvolume_all(int volume)
{
	vol_win = (4.615583-log(101-volume))/4.615583;  // to4nost 0.0001002;
	//qDebug()<<vol_win<<volume;
	return 0;
}
*/
/*
#if defined _LINUX_
int Rawplayer::setvolume_lin(int volume)
{ 
    int r = -1;
    saved_volume_mixer = volume;
    QString cardName_hv;
    QString dev = saved_device;//Rawplayer::defaultdevice;
    QRegExp rx("hw:(\\d+)");
    if (rx.indexIn(dev) != -1)
        cardName_hv = rx.cap(1);
    cardName_hv = "hw:"+cardName_hv;
    //qDebug()<<cardName_hv;
    int                   err;
    long                  mixerMin, mixerMax,setVol;
    double                mixerRange,volPercent;
    char                  *mName = (char*)"PCM";//cardName = "hw:1";//"PCM"
    snd_mixer_t           *mHandle;
    snd_mixer_elem_t      *mElem;
    snd_mixer_selem_id_t  *sId;

    snd_mixer_selem_id_alloca(&sId);
    snd_mixer_selem_id_set_name(sId, mName);
    if ((err = snd_mixer_open(&mHandle, 0)) < 0)
    {
        static int once = 0;
        if (!once)
        {
            fprintf (stderr,"[softdevice-audio]: cannot open mixer: %s (%s)",
                     mName,snd_strerror(err));
            once = 1;
        }
        return -1;
    }
    snd_mixer_attach(mHandle, cardName_hv.toLatin1()); //cardName_hv.toLatin1() -> cardName hv
    snd_mixer_selem_register(mHandle, NULL, NULL);
    snd_mixer_load(mHandle);
    mElem = snd_mixer_find_selem(mHandle,sId);
    if (mElem)
    {
        snd_mixer_selem_get_playback_volume_range(mElem,&mixerMin,&mixerMax);
        mixerRange = mixerMax - mixerMin;
        volPercent = (double) saved_volume_mixer / 100.0;//255.0
        setVol = (int) (((double)mixerMin+(mixerRange*volPercent))+0.5);
        snd_mixer_selem_set_playback_volume(mElem,SND_MIXER_SCHN_FRONT_LEFT,setVol);
        snd_mixer_selem_set_playback_volume(mElem,SND_MIXER_SCHN_FRONT_RIGHT,setVol);
        if (snd_mixer_selem_has_playback_switch(mElem))
        {
            snd_mixer_selem_set_playback_switch_all(mElem, (saved_volume_mixer) ? 1 : 0);
        }
    }
    //qDebug()<<mElem;
    snd_mixer_close(mHandle);
    return (r&0xFF);
}
#endif
*/
/*
short int *Rawplayer::win_vol_ctrl(short int *data, const int size)
{
    for (int i = 0; i < size; i+=2)
    {
        data[i] = data[i]*vol_win;
        data[i+1] = data[i+1]*vol_win;
    }
    return data;
}
*/

/*******************/
/* Rawplayer class */
/*******************/
// Rawplayer class
#include "../../HvRigControl/HvRigCat/network/network.h"
Rawplayer::~Rawplayer()
{
    //qDebug()<<"Destroy";
    if (ftci)
    {
        _SetTciBuffReset_();
        return;
    }
#if defined _WIN32_
    win_destroy();
#endif
#if defined _LINUX_
    lin_destroy();
#endif
}
bool Rawplayer::initialize(char *device_name)
{
    //qDebug()<<"initialize";
    audiobuffersize = 4096;//1024;//4096;
    //saved_device = Rawplayer::defaultdevice;
    buff_hv = Rawplayer::buffering;
    
    QString str_device_name = (QString)device_name;
    if (str_device_name=="TCI Client Output")
    {
        _SetTciBuffReset_();
        ftci = true; //audiobuffersize = 8192;
    }
    else ftci = false;

    if (ftci) return true;
#if defined _WIN32_
    return win_initialize(device_name);
#endif
#if defined _LINUX_
    return lin_initialize(device_name);
#endif
    return true;
}
/*
void Rawplayer::set_tx_filter_parm(int gain, double f0, double f1, bool type)
{
	THvRawFilter->filter_parm(gain,f0,f1,type);
}
*/
void Rawplayer::abort(void)
{
    //qDebug()<<"abort";
    if (ftci)
    {
        _SetTciBuffReset_();//exeption needed HV
        return;
    }
#if defined _WIN32_
    win_abort();
#endif
}
int Rawplayer::getprocessed(void)
{
    //qDebug()<<"gerprocessed";
    return 1;
}
bool Rawplayer::setsoundtype(int stereo,int samplesize,int speed)
{
    // pauza e prez tazi (procedura + resetsoundtype(void)) a stop e samo resetsoundtype(void)
    //THvRawFilter->set_rate((double)speed);
    rawstereo=stereo;
    rawsamplesize=samplesize;
    rawspeed=speed;
    if (stereo==0) rawchannels = 1;
    if (stereo==1) rawchannels = 2;
#if defined _LINUX_
    rawchannels = 2;
#endif
    //forcetomono=forceto8=false;
    //qDebug()<<"uuu"<<rawchannels<<rawspeed<<rawsamplesize;
    return resetsoundtype();
}
bool Rawplayer::resetsoundtype(void)
{
    //qDebug()<<"reset_sine_cw";
    if (ftci) return true;
#if defined _WIN32_
    return win_resetsoundtype(rawchannels,rawsamplesize,rawspeed,buff_hv);
#endif
#if defined _LINUX_
    return lin_resetsoundtype();
#endif
}
//void * fast_memcpy(void * to, const void * from, size_t len);
//#define fast_memcpy(a,b,c) memcpy(a,b,c)
//#include <QTime>
//QElapsedTimer ttt;
bool Rawplayer::putblock(void *buffer,int size)
{
    if (ftci)//tci
    {
    	/*ttt.start();
    	bool bbb = _SetTxAudioTci_((short*)buffer,size);
    	qDebug()<<ttt.elapsed();
        return bbb;*/
        return _SetTxAudioTci_((short*)buffer);
    }
    else
    {
#if defined _WIN32_
        return win_putblock(buffer,size);
#endif
#if defined _LINUX_
        return lin_putblock(buffer,size);
#endif
    }
    return 0;
}
int Rawplayer::getblocksize(void)
{
    return audiobuffersize;
}
/*short shortraw[16385];//tci=8192<-max
int j = 0;
unsigned char *uch = (unsigned char*)buffer;
for (int i = 0; i < size; i+=4)
{
	//little-endian form HV
    shortraw[j] = (uch[i+1] << 8);
    shortraw[j] |= uch[i];
    j++;
    shortraw[j] = (uch[i+3] << 8);
    shortraw[j] |= uch[i+2];
    j++;        
    //shortraw[j] = kkk;
    //j++;
    //shortraw[j] = kkk;
    //j++;        
}    
//kkk ++;    
return _SetTxAudioTci_(shortraw,size/2);*/



