/*
 * See the README file for copyright information and how to reach the author.
 *
 */

#include "common.h"

#define FREQUENCY_OFFSET 1750
#define FREQUENCY_CENTER (70.0/100.0)

cRMChannel::cRMChannel(int _frequency)
{
    frequency=0;
    startFrequency=0;
    endFrequency=0;
    offset=0;
    channel=-1;
    name[0]=0;
    AddFrequency(_frequency);
    modified=false;
}

cRMChannel::cRMChannel(cRMChannel* _channel)
{
    frequency=_channel->frequency;
    startFrequency=_channel->startFrequency;
    endFrequency=_channel->endFrequency;
    offset=_channel->offset;
    channel=_channel->channel;
    strncpy(name, _channel->name, sizeof(tEditableTextBuffer));;
    modified=_channel->modified;
}

cRMChannel::cRMChannel(cChannel* _channel)
{
    frequency=_channel->Frequency();
    startFrequency=0;
    endFrequency=0;
    channel=_channel->Number();
    offset=_channel->Srate();
    SetName(_channel->Name());
    AddFrequency(_channel->Frequency());
    modified=false;
}

void cRMChannel::SetName(const char* _name)
{
    strncpy(name, _name, sizeof(tEditableTextBuffer));
    modified=true;
}

const char* cRMChannel::Name()
{
    if(!name[0]) {
        modified=true;
        snprintf(name, sizeof(tEditableTextBuffer), "C%03d", Index());
    }
    return name;
}

void cRMChannel::UpdateVdrChannel()
{
    for(cChannel* vdrChannel=Channels.First();
            vdrChannel; vdrChannel=Channels.Next(vdrChannel))
    {
        if(vdrChannel->GroupSep() || !cRMDevice::IsPvrUsb2Channel(vdrChannel))
        {
            continue;
        }
        if(IsChannel(vdrChannel->Frequency())) {
            if(channel<0) {
                SetName(vdrChannel->Name());
                frequency=vdrChannel->Frequency();
            }
            channel=vdrChannel->Number();
            return;
        }
    }
}

// if no frequency is set it will say yes to any frequency
bool cRMChannel::IsChannel(int _frequency)
{
    if(!startFrequency || !endFrequency) {
        return true;
    }
    if(_frequency>(startFrequency-FREQUENCY_OFFSET) && 
            _frequency<(endFrequency+FREQUENCY_OFFSET))
    {
        return true;
    }
    return false;
}

void cRMChannel::AddFrequency(int _frequency)
{
    if(!startFrequency) {
        startFrequency=_frequency;
        endFrequency=_frequency;
    } else if(_frequency<=startFrequency) {
        startFrequency=_frequency;
    } else if(_frequency>=endFrequency) {
        endFrequency=_frequency;
    }
    if(channel<0) {
        frequency=(int)(startFrequency+FREQUENCY_CENTER*
                (endFrequency-startFrequency));
        UpdateVdrChannel();
        modified=true;
    }
    return;
}

bool cRMChannel::Write2VdrChannel()
{
    if(HaveVdrChannel()) {
        cRMDevice::Pvr2VdrChannel(this, VdrChannel());
        Channels.SetModified(true);
    } else {
        cChannel* group=NULL;
        for(int groupIdx=Channels.GetNextGroup(-1); groupIdx>=0;
                groupIdx=Channels.GetNextGroup(groupIdx))
        {
            group=Channels.Get(groupIdx);
            if(strcmp(group->Name(), tr("Analog TV channels"))==0) {
                break;
            }
            group=NULL;
        }
        if(!group) {
            group=new cChannel();
            char tmp[255];
            snprintf(tmp, sizeof(tmp), ":%s", tr("Analog TV channels"));
            group->Parse(tmp);
            Channels.Add(group);
            cChannel* separator=new cChannel();
            snprintf(tmp, sizeof(tmp), ":%s", tr("Other TV channels"));
            separator->Parse(tmp);
            Channels.Add(separator);
            Channels.ReNumber();
        }
        cChannel* newChannel=cRMDevice::Pvr2VdrChannel(this);
        Channels.Add(newChannel, group);
        Channels.ReNumber();
        Channels.SetModified(true);
        SetVdrChannel(newChannel->Number());
    }
    modified=false;
    return true;
}

bool cRMChannel::DeleteVdrChannel() 
{
    if(!HaveVdrChannel()) {
        return false;
    }
    Channels.Del(VdrChannel());
    Channels.ReNumber();
    Channels.SetModified(true);
    return true;
}


