#include <unistd.h>

#include "directory-loader.h"
#include "digicam.h"
#include "facts-base.h"
#include "digicam-logger.h"

cDirectoryLoader::cDirectoryLoader()
#if VDRVERSNUM > 10300 
:cThread("download")
#else
:cThread()
#endif
{
#ifdef DEBUG
	printf("cDirectoryLoader::cDirectoryLoader\n" );
#endif
	fileCount = 0;
	currentFile = 0;
	
	PathOnCamera[0] = 0;
	Message[0] = 0;
}

int cDirectoryLoader::GetFileCount(void) {
    return fileCount;
}

int cDirectoryLoader::GetCurrentFile(void) {
    return currentFile;
}

void cDirectoryLoader::Download(void) {
    CameraList files;
    files.count = 0;    
    CameraFile *file = NULL;
    char buf[FACTSHEET_BUFLEN];
    
#ifdef DEBUG
    printf("cDirectoryLoader::Download\n" );
#endif
    Message[0] = 0;
        
    if (Running() && dCam->isAvailable() && PathOnCamera != NULL ) {
#ifdef DEBUG
	printf("cFactsheetDirectory::SaveDirectoryToDisc: directory = %s\n", PathOnCamera );
#endif
	dCam->setDirectory( "/", PathOnCamera );
	// Get filelist
	if (dCam->getFileList( &files ) == DIGICAM_NO_ERROR) {
	    // Avoid any output in case of no files found (VDR crashes)
	    fileCount = files.count;
	    
	    if (files.count > 0) {
		// walk through file list and download files
    		for (currentFile=0; currentFile<files.count; currentFile++) {
		    if ( !Running() )	// Cancel thread?
	    		break;

		    gp_file_new(&file);
	    	    
		    OSDStatus("Loading file");
		
		    dsyslog("Digicam: Loading file '%s'", files.entry[currentFile].name );
				
		    // get file from camera
		    if ( dCam->getFile(  files.entry[currentFile].name, file ) != DIGICAM_NO_ERROR) {
			break;
		    }

		    dsyslog("Digicam: file loaded");
		
		    if (!Running()) // Cancel thread?
			break;
	    
		    // print status message
		    OSDStatus("Storing file");
	    
	    	    // Saving file to disc
		    snprintf( buf, 100, "%s/%s", cFactsheetBase::getCopyDestination(), files.entry[currentFile].name );

		    dsyslog("Saving image to disc");
		
		    if (dCam->saveFileToDisc( file, buf ) != DIGICAM_NO_ERROR) {
			break;
		    }
		
		    dsyslog("saved\n");
		
		    // release file object
		    gp_file_free(file);
		    file = NULL;
		}    	
	
		if (!Running()) {// Cancelled or error
		    if (file != NULL) { // Free file object
			gp_file_free(file);
			file = NULL;
		    }
		}

#if VDR_VERSNUM >= 10337
		Skins.QueueMessage( tr("Download complete"), 0 , -1);
#endif
	
		// Final output for user
		if (Running()) // normal ending
		    OSDStatus( tr("Download complete"), false );
		else // threat was aborted
		    OSDStatus( tr("Download cancelled"), false );
		    
	    } else { // No files found
		isyslog("Digicam: Listing returned no files");
	    }
	    
	    fileCount = 0;
	    currentFile = 0;
	    
	} // listing != DIGICAM_NO_ERROR
	

	
	// If camera error occured => report	
	if (dCam->getErrNo() != DIGICAM_NO_ERROR)
	    cDigicamLogger::reportCameraError( dCam->getErrNo() );
    }
}

void cDirectoryLoader::OSDStatus(const char* prefix, bool printFileCount) {
    // build status message
    if (printFileCount) {
	snprintf( Message, FACTSHEET_BUFLEN, "%s %d %s %d...", 
	    tr(prefix), currentFile+1 , tr("of"), fileCount );
    } else {
	snprintf( Message, FACTSHEET_BUFLEN, "%s", tr(prefix) );    
    }
    
    // if not a background thread: Display message in OSD
    if ( !Running() ) {
	OSD_StatusMsg( Message );
    }
}

void cDirectoryLoader::StartNoThread(DigitalCamera *camera, const char* pathOnCamera) {
#ifdef DEBUG
    printf("cDirectoryLoader::StartNoThread\n" );
#endif

    if (camera != NULL) {
	// Set directory to download	
	strncpy( PathOnCamera, pathOnCamera, DL_BUFLEN);	
	dCam = camera;
	
	Download();
    }
}

void cDirectoryLoader::Start(const char* pathOnCamera) {
#ifdef DEBUG
	printf("cDirectoryLoader::Start\n" );
#endif
	// Set directory to download	
	strncpy( PathOnCamera, pathOnCamera, DL_BUFLEN);
	
	dCam = new DigitalCamera();
	
	if (dCam != NULL) {
	    dCam->bind();

	    // Start the threat
	    cThread::Start();
	}
}

// Stop download
void cDirectoryLoader::Stop(void) {
#ifdef DEBUG
	printf("cDirectoryLoader::Stop\n" );
#endif
	Cancel(30);
}


void cDirectoryLoader::Action(void) {
#ifdef DEBUG
    printf("cDirectoryLoader::Action\n" );
#endif
    Download();
    
    if (dCam != NULL)
        dCam->release();
}

const char* cDirectoryLoader::GetMessage() {
    return (const char*) Message;
}
