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

#include "common.h"

class cRMSetupItem
{
    public:
        eSetupItem item;
        const char* name;
        eItemType type;
        const char* defaultValue;
        int value;
};

/* values that are stored in the config file */
static const eSetupItem configItems[]=
{
    eSetupResolution,
    eSetupVolume,
    eSetupAudioBitrate,
    eSetupBrightness,
    eSetupContrast,
    eSetupHue,
    eSetupSaturation,
    eSetupVideoBitrateAverage,
    eSetupVideoBitratePeak,
    eSetupVideoStandard,
    eSetupVbr,
    eSetupVideoDevice0,
    eSetupVideoDevice1,
    eSetupVideoDevice2,
    eSetupVideoDevice3
};

static const cRMSetupItem setupItemList[]=
{
    { eSetupResolution, "Resolution", eVideoResolutionItem, "720x576" },
    { eSetupVolume, "Volume", ePercentItem, "100" },
    { eSetupAudioBitrate, "AudioBitrate", eAudioBitrateItem, "224" },
    { eSetupBrightness, "Brightness", eSliderItem },
    { eSetupContrast, "Contrast", eSliderItem },
    { eSetupHue, "Hue", eOffsetItem },
    { eSetupSaturation, "Saturation", eSliderItem },
    { eSetupVideoBitrateAverage, "VideoBitrateAverage",
            eVideoBitrateItem, "3.6" },
    { eSetupVideoBitratePeak, "VideoBitratePeak", eVideoBitrateItem, "10.0" },
    { eSetupVideoStandard, "VideoStandard", eVideoStandardItem, "PAL-BG" },
    { eSetupVbr, "Vbr", eBoolItem, "1" },
    { eSetupVideoDevice0, "VideoDevice0", eVideoDeviceItem, "/dev/video1" },
    { eSetupVideoDevice1, "VideoDevice1", eVideoDeviceItem, "/dev/video2" },
    { eSetupVideoDevice2, "VideoDevice2", eVideoDeviceItem, "/dev/video3" },
    { eSetupVideoDevice3, "VideoDevice3", eVideoDeviceItem, "/dev/video4" },

    { eSetupResolutionHorizontal, "ResolutionHorizontal",
            eVideoResolutionHorizontalItem },
    { eSetupResolutionVertical, "ResolutionVertical",
            eVideoResolutionVerticalItem }
};

cRMSetup::cRMSetup()
{
    int numItems=ENTRIES(setupItemList, cRMSetupItem);

    eSetupItem maxItem=(eSetupItem)0;
    for(int i=0; i<numItems; i++) {
        if(setupItemList[i].item>maxItem) {
            maxItem=setupItemList[i].item;
        }
    }
    itemArraySize=maxItem+1;

    setupItems=new cRMSetupItem[itemArraySize]; 
    memset(setupItems, 0, sizeof(cRMSetupItem)*itemArraySize);
    for(int i=0; i<numItems; i++) {
        eSetupItem index=setupItemList[i].item;
        if(setupItems[index].name!=NULL) {
            cPvrUsb2Plugin::LogError("Duplicate setup index(%d): %s",
                    index, setupItemList[i].name);
        }
        setupItems[index]=setupItemList[i];
        setupItems[index].value=-1;
        if(setupItemList[i].defaultValue) {
            SetValue(index, setupItemList[i].defaultValue);
        }
    }
}

void cRMSetup::operator=(cRMSetup& _setup)
{
    itemArraySize=_setup.itemArraySize;
    setupItems=new cRMSetupItem[itemArraySize];   
    for(int i=0; i<itemArraySize; i++) {
        setupItems[i]=_setup.setupItems[i];
    }
}

cRMSetup::~cRMSetup()
{
    delete[] setupItems;
    setupItems=NULL;
}

void cRMSetup::SetDefaultIndex(eSetupItem _item, cRMDevice* _device)
{
    if(Index(_item)<0) {
        SetIndex(_item, DeviceValue2Index(_item, _device));
    }
}

void cRMSetup::SetDefaults(cRMDevice* _device)
{
    SetDefaultIndex(eSetupBrightness, _device);
    SetDefaultIndex(eSetupContrast, _device);
    SetDefaultIndex(eSetupHue, _device);
    SetDefaultIndex(eSetupSaturation, _device);
    SetIndex(eSetupVideoDevice0, _device->VideoDevice());
}

bool cRMSetup::SetupParse(const char* _name, const char* _value)
{
    for(int i=0; i<NumItems(); i++) {
        eSetupItem item=configItems[i];
        if(strcmp(_name, ItemName(item))==0) {
            SetValue(item, atoi(_value));
            return true;
        }
    }
    return false;
}

int cRMSetup::NumItems()
{
    return ENTRIES(configItems, eSetupItem);
}

eSetupItem cRMSetup::Item(int _iterIndex)
{
    if(_iterIndex<0 || _iterIndex>=NumItems()) {
        return (eSetupItem)-1;
    }
    return configItems[_iterIndex];
}

bool cRMSetup::IsValidItem(eSetupItem _item)
{
    if(_item<0 || _item>itemArraySize ||
            !setupItems || !setupItems[_item].name)
    {
        return false;
    }
    return true;
}

const char* cRMSetup::ItemName(eSetupItem _item)
{
    if(!IsValidItem(_item)) {
        return NULL;
    }
    return setupItems[_item].name;
}

eItemType cRMSetup::ItemType(eSetupItem _item)
{
    if(!IsValidItem(_item)) {
        return (eItemType)-1;
    }
    return setupItems[_item].type;
}

int cRMSetup::ClipIndex(eSetupItem _item, int _index)
{
    if(!IsValidItem(_item)) {
        return -1;
    }
    return cRMSetupTools::ClipIndex(ItemType(_item), _index);
}

int cRMSetup::Index(eSetupItem _item)
{
    int item=_item;
    switch(item) {
        case eSetupResolutionVertical:
        case eSetupResolutionHorizontal:
            item=eSetupResolution;
            break;
        default:
            break;
    }
    if(!IsValidItem(_item)) {
        return -1;
    }
    return setupItems[item].value;
}

int* cRMSetup::IndexReference(eSetupItem _item)
{
    if(!IsValidItem(_item)) {
        return NULL;
    }
    return &(setupItems[_item].value);
}

bool cRMSetup::SetIndex(eSetupItem _item, int _index)
{
    if(!IsValidItem(_item)) {
        return false;
    }
    setupItems[_item].value=ClipIndex(_item, _index);
    return true;
}

int cRMSetup::Value(eSetupItem _item, int _min, int _max) {
    return cRMSetupTools::Index2Value(ItemType(_item), Index(_item), _min, _max);
}

bool cRMSetup::SetValue(eSetupItem _item, const char* _value)
{
    int index=cRMSetupTools::Value2Index(ItemType(_item), _value);
    return SetIndex(_item, index);
}

bool cRMSetup::SetValue(eSetupItem _item,
        int _value, int _min, int _max)
{
    return SetIndex(_item, cRMSetupTools::Value2Index(ItemType(_item),
            _value, _min, _max));
}

int cRMSetup::DeviceValue2Index(eSetupItem _item, cRMDevice* _device)
{
    cPvrUsb2Plugin::LogDebug("Device value: %s=%d(%d,%d)",
            ItemName(_item), _device->CurrentValue(_item),
            _device->MinValue(_item), _device->MaxValue(_item)); 

    int retVal=cRMSetupTools::Value2Index(ItemType(_item),
           _device->CurrentValue(_item),
           _device->MinValue(_item),
           _device->MaxValue(_item));

    cPvrUsb2Plugin::LogDebug("Device index: %s=%d(0,%d)",
            ItemName(_item), retVal,
            cRMSetupTools::NumIndices(ItemType(_item))); 
    return retVal;
}

