/*
 * digitalcamera.c: A plugin for the Video Disk Recorder
 *
 * See the README file for copyright information and how to reach the author.
 *   
 * based on the image plugin
 *
 * This code is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 * $Id: digitalcamera.c,v 1.7 2004/11/26 21:18:53 peter Exp $
 */

 
/*

File	: digitalcamera.c
Autor	: Peter Juszack

Description
-----------------------------------------------------------------
wrapper class for libgphoto2

*/
#include <string.h>

#include <gphoto2/gphoto2.h>

#include <vdr/plugin.h>

#include "digicam.h"
#include "digitalcamera.h"

DigitalCamera::DigitalCamera(void) {
    camera = NULL;
    
    lastError = DIGICAM_NO_ERROR;
    // Init gphoto2 camera handle
    //bind();
}

DigitalCamera::~DigitalCamera() {
    // free gphoto2 camera handle
#ifdef DEBUG
    printf("DigitalCamera:~DigitalCamera\n");
#endif
    release();
#ifdef DEBUG
    printf("DigitalCamera:~DigitalCamera OK\n");
#endif
}


int DigitalCamera::bind(void) {
    lastError = DIGICAM_NO_ERROR;
    
    if (camera == NULL) {
	// initialization for working directory on the camera
	strncpy(cameraDirectory, "/", CAMERA_PATH_MAXLENGTH);

	// Init gphoto2 camera handle
	gp_camera_new( &camera );
	if (camera == NULL) {
	    lastError = DIGICAM_CLASS_ERROR;
	    return lastError;
	}
	    
	gp_camera_init( camera, NULL );    
    } else
	lastError = DIGICAM_CLASS_ERROR;
	
    return lastError;
}

int DigitalCamera::release(void) {
#ifdef DEBUG
    printf("DigitalCamera:Release\n");
#endif
    lastError = DIGICAM_NO_ERROR;
    
    if (camera != NULL) {
	// release gphoto2 camera handle
        gp_camera_exit( camera, NULL );
	gp_camera_free( camera );	
    } else
	lastError = DIGICAM_CLASS_ERROR;

    camera = NULL;
#ifdef DEBUG
    printf("DigitalCamera:Release OK\n");
#endif
    
    return lastError;
}

bool DigitalCamera::isAvailable(void) {
    return ( camera != NULL );
}

// Fill the passed structure with a camera summary
int DigitalCamera::getSummary( CameraText *summ ) {    
    if (summ != NULL)	// init text to avoid conflicts when
	summ->text[0] = 0;	// error occurs
	
    if (camera != NULL && summ != NULL) {
	lastError = gp_camera_get_summary( camera, summ, NULL);
    } else
	lastError = DIGICAM_CLASS_ERROR;
    
    return lastError;
}

// Fill the passed structure with folderlist of current directory
int DigitalCamera::getFolderList(CameraList *list) {
#ifdef DEBUG
    printf("%s\n", cameraDirectory);
#endif
    if (list != NULL)	// init result count to avoid conflicts
	list->count = 0; // when error occurs

    if (camera != NULL && list != NULL) {
	lastError = gp_camera_folder_list_folders( camera, cameraDirectory, list, NULL);
    } else
	lastError = DIGICAM_CLASS_ERROR;
    
    return lastError;
} 

// Fill the passed structure with filelist of current directory
int DigitalCamera::getFileList(CameraList *list) {
    if (list != NULL)	// init result count to avoid conflicts
	list->count = 0; // when error occurs

    if (camera != NULL && list != NULL) {
	lastError = gp_camera_folder_list_files( camera, cameraDirectory, list, NULL);
    } else
	lastError = DIGICAM_CLASS_ERROR;
    
    return lastError;
}

// Fill the passed structure with filelist of current directory
int DigitalCamera::getFileInformation(CameraFileInfo *info, const char* file) {
    if (info != NULL) {
	info->file.name[0] = 0;
	info->file.size = 0;
	info->file.status = GP_FILE_STATUS_NOT_DOWNLOADED;
    }
    if (camera != NULL && info != NULL && file != NULL) {
	lastError = gp_camera_file_get_info( camera, cameraDirectory, file, info, NULL);
    } else
	lastError = DIGICAM_CLASS_ERROR;
    
    return lastError;
}

// Fill the passed camera file with a file from the camera
int DigitalCamera::getFile( const char* fileName, CameraFile *file) {
    if (camera != NULL && fileName != NULL && file != NULL) {
	lastError = gp_camera_file_get( camera, cameraDirectory, fileName, 
	    GP_FILE_TYPE_NORMAL, file, NULL);
    } else
	lastError = DIGICAM_CLASS_ERROR;
    
    return lastError;
}

// Save the passed CameraFile to disc
int DigitalCamera::saveFileToDisc( CameraFile *file, const char* fileName) {
    if (fileName != NULL && file != NULL) {
	lastError = gp_file_save( file, fileName );
    } else
	lastError = DIGICAM_CLASS_ERROR;
    
    return lastError;
}

void DigitalCamera::buildPath( char* target, const char* path1, const char* path2) {
    // If path1 is NULL switch path2 to path1
    if (path1 == NULL) {
	path1 = path2;
	path2 = NULL;
    }

    if (path2 != NULL) { // There are 2 not NULL components
	if ( path1[strlen(path1) - 1] == '/') // If path1 ends with '/'
	    // we don't need a '/' between components
	    snprintf(target, CAMERA_PATH_MAXLENGTH, "%s%s", path1, path2 );
	else
	    // we need a seperating '/'
	    snprintf(target, CAMERA_PATH_MAXLENGTH, "%s/%s", path1, path2 );
    } else { // path2 = NULL
	if (path1 == NULL) // path1=NULL, too
	    // set root path = '/'
	    snprintf(target, CAMERA_PATH_MAXLENGTH, "/" );
	else
	    // set path from path1
	    snprintf(target, CAMERA_PATH_MAXLENGTH, "%s", path1 );
    }
}

void DigitalCamera::setDirectory( const char* path1, const char* path2) {
    buildPath( cameraDirectory, path1, path2 );
}

int DigitalCamera::deleteFile(const char* fileName) {
    if (camera != NULL && fileName != NULL) {
	lastError = gp_camera_file_delete( camera, cameraDirectory, fileName, NULL);
    } else
	lastError = DIGICAM_CLASS_ERROR;
    
    return lastError;    
}

int DigitalCamera::deleteFolder(const char* folderName, bool deleteFiles) {
    if (camera != NULL && folderName != NULL) {
	lastError = DIGICAM_NO_ERROR;
	
	if (deleteFiles) { // if force delete of all files in folder
	    // build complete path to folder
	    char completePath[CAMERA_PATH_MAXLENGTH];
	    buildPath(completePath, cameraDirectory, folderName );	    
	    
	    // delete all files in the folder
	    lastError = gp_camera_folder_delete_all( camera, completePath, NULL);
	}
	
	printf("DEBUG: '%s' '%s'\n", cameraDirectory, folderName );
	
	if (lastError == DIGICAM_NO_ERROR) // Files were deleted or deleteFiles = false
	    // delete the folder itself
	    lastError = gp_camera_folder_remove_dir( camera, cameraDirectory, folderName, NULL);
    } else
	lastError = DIGICAM_CLASS_ERROR;
    
    return lastError;    
}

int DigitalCamera::getErrNo(void) {
    return lastError;
}
