/*
 * pvrusb2.c: A plugin for the Video Disk Recorder
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id$
 */

#include "common.h"

int cPvrUsb2Plugin::debug=2;

cPvrUsb2Plugin* PvrUsb2=NULL;

cPvrUsb2Plugin::cPvrUsb2Plugin()
{
    // Initialize any member variables here.
    // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
    // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!

    PvrUsb2=this;

    commandLineHelp=NULL;
    setupMenu=NULL;
}

cPvrUsb2Plugin::~cPvrUsb2Plugin()
{
    LogInfo("Unload Plugin");

    if(commandLineHelp) {
        free(commandLineHelp);
        commandLineHelp=NULL;
    }
    delete setupMenu;
    setupMenu=NULL;

    PvrUsb2=NULL;

    LogInfo("Plugin Unloaded");
}

const char* cPvrUsb2Plugin::CommandLineHelp()
{
    // Return a string that describes all known command line options.
    LogInfo("CommandLineHelp");

    if(commandLineHelp) {
        free(commandLineHelp);
    }

    asprintf(&commandLineHelp,
        "  -v,  --verbose          increment debug level\n"
        );
    return commandLineHelp;
}

bool cPvrUsb2Plugin::ProcessArgs(int _argc, char* _argv[])
{
    // Implement command line argument processing here if applicable.
    LogInfo("ProcessArgs: %d", _argc);
    return true;
}

bool cPvrUsb2Plugin::Initialize()
{
    // Initialize any background activities the plugin shall perform.
    LogInfo("Initialize");
    cReadDir* dir=new cReadDir(cPvrUsb2Device::DeviceBase());
    if(!dir->Ok()) {
        delete dir;
        return false;
    }
    int index=0;
    for(dirent* device=dir->Next(); device!=NULL; device=dir->Next()) {
        if(!strcmp(".", device->d_name) || !strcmp("..", device->d_name)) {
            continue;
        }
        devices.Add(new cPvrUsb2Device(index, device->d_name));
        index++;
    }
    delete dir;
    if(devices.First()) {
        setup.SetDefaults(devices.First());
    }
    SetupDevices(&setup);
    return true;
}

bool cPvrUsb2Plugin::Start()
{
    // Start any background activities the plugin shall perform.
    LogInfo("Start");
    RegisterI18n(pvrusb2Phrases);
    return true;
}

void cPvrUsb2Plugin::Stop()
{
    LogInfo("Stop");
    // Stop any background activities the plugin shall perform.
}

void cPvrUsb2Plugin::Housekeeping()
{
//    LogInfo("Housekeeping");
    // Perform any cleanup or other regular tasks.
}

cOsdObject* cPvrUsb2Plugin::MainMenuAction()
{
    // Perform the action when selected from the main VDR menu.
    LogInfo("MainMenuAction");
    return NULL;
}

cMenuSetupPage* cPvrUsb2Plugin::SetupMenu()
{
    // Return a setup menu in case the plugin supports one.
    LogInfo("SetupMenu");
    if(!setupMenu) {
        setupMenu=new cRMSetupMenu();
    }

    return setupMenu;
}

bool cPvrUsb2Plugin::UpdateSetup(cRMSetup* _newSetup)
{
    setup=*_newSetup;

    return SetupDevices(&setup);
}

cRMDevice* cPvrUsb2Plugin::FirstDevice()
{
    return devices.First();
}

cRMDevice* cPvrUsb2Plugin::Device(int _index)
{
    return devices.Get(_index);
}

bool cPvrUsb2Plugin::SetupDevices(cRMSetup* _newSetup)
{
    bool retVal=true;
    
    cRMDevice* device=devices.First();
    for(int i=0;
            device!=NULL; device=devices.Next(device), i++)
    {
        int videoDevice=_newSetup->Value((eSetupItem)(eSetupVideoDevice0+i));
        device->SetVideoDevice(videoDevice);
        retVal=device->Setup(_newSetup) && retVal;
    }
    return retVal;
}

bool cPvrUsb2Plugin::SetupParse(const char *_name, const char *_value)
{
    // Parse your own setup parameters and store their values.
    LogInfo("SetupParse: %s, %s", _name, _value);
    return setup.SetupParse(_name, _value);
}

void cPvrUsb2Plugin::LogError(const char* _format, ...)
{
    if(!_format) {
        return;
    }
    char* header="pvrusb2 plugin: ERROR: ";
    int length=strlen(_format)+strlen(header)+2;
    char* format=(char*)alloca(length);

    va_list argList;
    va_start(argList, _format);

    snprintf(format, length, "%s%s", header, _format);
    vsyslog(LOG_ERR, format, argList);
    snprintf(format, length, "%s%s\n", header, _format);
    vfprintf(stderr, format, argList);
}

void cPvrUsb2Plugin::LogInfo(const char* _format, ...)
{
    if(debug<1) {
        return;
    }
    if(!_format) {
        return;
    }
    char* header="pvrusb2 plugin: INFO: ";
    int length=strlen(_format)+strlen(header)+2;
    char* format=(char*)alloca(length);

    va_list argList;
    va_start(argList, _format);

    snprintf(format, length, "%s%s", header, _format);
    vsyslog(LOG_INFO, format, argList);
}

void cPvrUsb2Plugin::LogDebug(const char* _format, ...)
{
    if(debug<2) {
        return;
    }
    if(!_format) {
        return;
    }
    char* header="pvrusb2 plugin: DEBUG: ";
    int length=strlen(_format)+strlen(header)+2;
    char* format=(char*)alloca(length);

    va_list argList;
    va_start(argList, _format);

    snprintf(format, length, "%s%s", header, _format);
//    dsyslog(format, argList);
    vsyslog(LOG_DEBUG, format, argList);
}

void cPvrUsb2Plugin::DeviceDestroyed(cRMDevice* _device)
{
    devices.Del(_device, false);
}

void cPvrUsb2Plugin::SetupMenuDestroyed()
{
    setupMenu=NULL;
}

VDRPLUGINCREATOR(cPvrUsb2Plugin); // Don't touch this!
