unit CamRemote;

interface

{$INCLUDE CamRemote.inc}

uses
  SysUtils, Classes, CDTYPE, CamDefines
{$IFDEF PSDLL}
  ,CDSDKApi
{$ENDIF}
{$IFDEF EOSDLL}
  ,RCSDKApi
{$ENDIF}
  ;

const CALLBACK_REPAINT_DELAY_IN_MS = 10;

type
  TNotifyEvent=procedure(Event:EventCallbackType) of object;
  TNotifyViewfinderEvent=procedure(Jpegdata:TMemoryStream) of object;
  TNotifyRemoteEvent=procedure(Event:RemoteEventCallbackType) of object;
  TNotifyRemoteTakePictureEvent=procedure(PercentageDone:integer) of object;
  TNotifyRemoteGetPictureEvent=procedure(PercentageDone:integer) of object;
  TNotifyGetPictureEvent=procedure(PercentageDone:integer) of object;

type
  TCamRemote = class(TComponent)
  private
    mCameraInfo                   : ConnectInfoType;
    mRemoteModeEnabled            : boolean;
    mRemoteViewfinderEnabled      : boolean;
    mNotifyEvent                  : TNotifyEvent;
    mNotifyViewfinderEvent        : TNotifyViewfinderEvent;
    mNotifyRemoteEvent            : TNotifyRemoteEvent;
    mNotifyRemoteTakePictureEvent : TNotifyRemoteTakePictureEvent;
    mNotifyRemoteGetPictureEvent  : TNotifyRemoteGetPictureEvent;
    mNotifyGetPictureEvent        : TNotifyGetPictureEvent;
{$IFDEF PSDLL}
    mCDSDK : TCDSDK;
{$ENDIF}
{$IFDEF EOSDLL}
    mRCSDK : TRCSDK;
{$ENDIF}
  protected
    function GetOwnerName : string;
  public
    //Constructors, destructors
    constructor Create(AOwner:TComponent);override;
    destructor Destroy;override;
    //General camera operations
    function Connect : ConnectInfoType;
    procedure Disconnect;
    //Remote operations
    function  RemoteSupported : boolean;
    function  RemoteStart(ReleaseMode           : ReleaseModeType;
                          ReleaseDataKind       : ReleaseDataKindType;
                          ProbeRemoteParameters : boolean) : RemoteFuncType;
    procedure RemoteEnd;
    function  RemoteTakePicture(UseSyncMode : boolean) : integer;
    procedure RemoteGetPicture(FileName : string);
    function  RemoteGetRemoteParams : RemoteReleaseParametersType;
    procedure RemoteSetRemoteParams(RemoteParam : RemoteReleaseParametersType);
    function  RemoteGetZoomPos : RemoteZoomCapabilityType;
    procedure RemoteSetZoomPos(ZoomPos : integer);
    //Remote viewfinder operations
    procedure RemoteStartViewfinder;
    procedure RemoteStopViewfinder;
    procedure RemoteSetViewfinderOutput(ViewfinderOutput : RemoteViewFinderOutputType);
    procedure RemoteActivateViewfinderAuto;
    //Camera/PC image collecting operations
    function  OpenCameraCollection(TempDir : string) : ImageListType;
    procedure CloseCameraCollection(var ImageListToClear : ImageListType);
    procedure GetPicture(NrInList : integer;
                         FileName : string);
    procedure DeletePicture(var ImageList : ImageListType;
                            NrInList      : integer);
  published
    property OnViewfinderEvent:TNotifyViewfinderEvent               read mNotifyViewfinderEvent        write mNotifyViewfinderEvent;
    property OnEvent:TNotifyEvent                                   read mNotifyEvent                  write mNotifyEvent;
    property OnRemoteEvent:TNotifyRemoteEvent                       read mNotifyRemoteEvent            write mNotifyRemoteEvent;
    property OnRemoteTakePictureEvent:TNotifyRemoteTakePictureEvent read mNotifyRemoteTakePictureEvent write mNotifyRemoteTakePictureEvent;
    property OnRemoteGetPictureEvent:TNotifyRemoteGetPictureEvent   read mNotifyRemoteGetPictureEvent  write mNotifyRemoteGetPictureEvent;
    property OnGetPictureEvent:TNotifyGetPictureEvent               read mNotifyGetPictureEvent        write mNotifyGetPictureEvent;
  end;

var CamRemoteObj : TCamRemote;

function event_callback_function(EventID :	cdEventID;
                                 pData   : pointer;
	                               DataSize : cdUInt32;
	                               Context : cdContext
                                 ) : cdUInt32 cdecl {$IFDEF WIN32} stdcall {$ENDIF};

function remote_event_callback_function(EventID  : cdReleaseEventID;
                                        pData    : pointer;
	                                      DataSize : cdUInt32;
	                                      Context  : cdContext
                                        ) : cdUInt32 cdecl {$IFDEF WIN32} stdcall {$ENDIF};

function view_finder_callback_function(pBuf    : pointer;
 	                                     Size    : cdUInt32;
                                       Format  : cdUInt32;
 	                                     Context : cdContext
                                       ) : cdUInt32 cdecl {$IFDEF WIN32} stdcall {$ENDIF};

function remote_get_picture_callback_function(Progress : cdUInt32;			    //Percentage                            */
                                              Status   : cdProgressStatus;	//Type of process currently in progress */
	                                            Context  : cdContext					//Context                               */
                                              ) : cdUInt32 cdecl {$IFDEF WIN32} stdcall {$ENDIF};

function remote_take_picture_callback_function(Progress : cdUInt32;			    //Percentage                            */
                                               Status   : cdProgressStatus;	//Type of process currently in progress */
	                                             Context  : cdContext					//Context                               */
                                               ) : cdUInt32 cdecl {$IFDEF WIN32} stdcall {$ENDIF};

function get_picture_callback_function(Progress : cdUInt32;			    //Percentage                            */
                                       Status   : cdProgressStatus;	//Type of process currently in progress */
	                                     Context  : cdContext					//Context                               */
                                       ) : cdUInt32 cdecl {$IFDEF WIN32} stdcall {$ENDIF};

procedure Register;

implementation

{$R *.RES}

uses CDAPI, CDERRORCODES, CDEVENT, RCTYPE, RCAPI, Forms, Windows;

procedure Register;
begin
  RegisterComponents('Samples', [TCamRemote]);
end;

constructor TCamRemote.Create(AOwner:TComponent);
begin
  inherited Create(AOwner);
  mRemoteModeEnabled       := false;
  mRemoteViewfinderEnabled := false;
  mCameraInfo.CameraModel  := CamModNone;
  CamRemoteObj := Self;
  //Create the SDK objects
{$IFDEF PSDLL}
  mCDSDK := TCDSDK.Create;
{$ENDIF}
{$IFDEF EOSDLL}
  mRCSDK := TRCSDK.Create;
{$ENDIF}
end;

destructor TCamRemote.Destroy;
begin
  //Free the SDK objects
{$IFDEF PSDLL}
  mCDSDK.Free;
{$ENDIF}
{$IFDEF EOSDLL}
  mRCSDK.Free;
{$ENDIF}
  inherited Destroy;
end;

function TCamRemote.Connect : ConnectInfoType;
var connected  : boolean;
    error_mess : string;
begin
  if (mCameraInfo.CameraModel <> CamModNone) then
  begin
    raise ECamException.Create('Camera already connected.');
  end;
  connected := false;
{$IFDEF PSDLL}
  //Try to connect to the camera using PSDLL
  if (not connected) then
  begin
    try
      mCameraInfo := mCDSDK.Connect(@event_callback_function);
      connected   := true;
    except
      on E:ECamException do error_mess := E.Message
    end;
  end;
{$ENDIF}
{$IFDEF EOSDLL}
  //Try to connect to the camera using EOSDLL
  if (not connected) then
  begin
    try
      mCameraInfo := mRCSDK.Connect(@event_callback_function);
      connected   := true;
    except
      on E:ECamException do error_mess := E.Message;
    end;
  end;
{$ENDIF}
  //Check if connected or not. If not create ecxeption including error message
  if (not connected) then
  begin
    raise ECamException.Create(error_mess);
  end;
  result := mCameraInfo;
end;

procedure TCamRemote.Disconnect;
begin
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      mCDSDK.Disconnect
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      mRCSDK.Disconnect
{$ENDIF};
  end;
  mCameraInfo.CameraModel := CamModNone;
end;

function  TCamRemote.RemoteSupported : boolean;
begin
  result := false;
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      result := mCDSDK.RemoteSupported
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      result := mRCSDK.RemoteSupported
{$ENDIF};
  end;
end;

function  TCamRemote.RemoteStart(ReleaseMode           : ReleaseModeType;
                                 ReleaseDataKind       : ReleaseDataKindType;
                                 ProbeRemoteParameters : boolean) : RemoteFuncType;
begin
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        result := mCDSDK.RemoteStart(ReleaseMode,
                                     ReleaseDataKind,
                                     ProbeRemoteParameters,
                                     @remote_event_callback_function);
        mRemoteModeEnabled := true;
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      begin
        result := mRCSDK.RemoteStart(ReleaseMode,
                                     ReleaseDataKind,
                                     ProbeRemoteParameters,
                                     @remote_event_callback_function);
        mRemoteModeEnabled := true;
      end
{$ENDIF};
  end;
end;

procedure TCamRemote.RemoteEnd;
begin
  if (not mRemoteModeEnabled) then
  begin
    raise ECamException.Create('Camera not in remote mode');
  end;
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        mRemoteModeEnabled := false;
        mCDSDK.RemoteEnd
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      begin
        mRemoteModeEnabled := false;
        mRCSDK.RemoteEnd
      end
{$ENDIF};
  end;
end;

procedure TCamRemote.RemoteStartViewfinder;
begin
  if (not mRemoteModeEnabled) then
  begin
    raise ECamException.Create('Camera not in remote mode');
  end;
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        mCDSDK.RemoteStartViewfinder(@view_finder_callback_function);
        mRemoteViewfinderEnabled := true;
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      raise ECamException.Create('EOS cameras do not support Viewfinder mode')
{$ENDIF};
  end;
end;

procedure TCamRemote.RemoteStopViewfinder;
begin
  if (not mRemoteViewfinderEnabled) then
  begin
    raise ECamException.Create('Camera not in viewfinder mode');
  end;
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        mRemoteViewfinderEnabled := false;
        mCDSDK.RemoteStopViewfinder;
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      raise ECamException.Create('EOS cameras do not support Viewfinder mode')
{$ENDIF};
  end;
end;

procedure TCamRemote.RemoteSetViewfinderOutput(ViewfinderOutput : RemoteViewFinderOutputType);
begin
  if (not mRemoteViewfinderEnabled) then
  begin
    raise ECamException.Create('Camera not in viewfinder mode');
  end;
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      mCDSDK.RemoteSetViewfinderOutput(ViewfinderOutput)
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      raise ECamException.Create('EOS cameras do not support Viewfinder mode')
{$ENDIF};
  end;
end;

procedure TCamRemote.RemoteActivateViewfinderAuto;
begin
  if (not mRemoteViewfinderEnabled) then
  begin
    raise ECamException.Create('Camera not in viewfinder mode');
  end;
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      mCDSDK.RemoteActivateViewfinderAuto
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      raise ECamException.Create('EOS cameras do not support Viewfinder mode')
{$ENDIF};
  end;
end;


function event_callback_function(EventID :	cdEventID;
                                 pData   : pointer;
	                               DataSize : cdUInt32;
	                               Context : cdContext) : cdUInt32 cdecl {$IFDEF WIN32} stdcall {$ENDIF};
var event_callback_data : EventCallbackType;
    event_received      : cdEventID;
begin
  event_callback_data.Severity := EventSeverityNotUSed;
  event_callback_data.Event    := EventNotUsed;
  if assigned(CamRemoteObj.mNotifyEvent) then
  begin
    //Update Severity
    if ((EventID and cdEVENT_SEVERITY_MASK) = cdEVENT_SEVERITY_WARNING) then
      event_callback_data.Severity := EventSeverityWarning
    else if ((EventID and cdEVENT_SEVERITY_MASK) = cdEVENT_SEVERITY_SHUTDOWN) then
      event_callback_data.Severity := EventSeverityClosing
    else if ((EventID and cdEVENT_SEVERITY_MASK) = cdEVENT_SEVERITY_NONE) then
      event_callback_data.Severity := EventSeverityInfo;
     //Update event
    event_received := (EventID and cdEVENT_EVENTID_MASK);
    case event_received of
      cdEVENT_BATTERY_LEVEL_CHANGED:
        begin
          if ((cdUInt32(pData^) and BATTERY_LEVEL_MASK) = BATTERY_LEVEL_NORMAL) then
            event_callback_data.Event :=  EventBatteryLevelNormal
          else if ((cdUInt32(pData^) and BATTERY_LEVEL_MASK) = BATTERY_LEVEL_WEAK) then
            event_callback_data.Event := EventBatteryLevelWeak
          else if ((cdUInt32(pData^) and BATTERY_LEVEL_MASK) = BATTERY_LEVEL_SAFETY_LOW) then
            event_callback_data.Event := EventBatteryLevelSafetyLow
          else if ((cdUInt32(pData^) and BATTERY_LEVEL_MASK) = BATTERY_LEVEL_LB) then
            event_callback_data.Event := EventBatteryLevelLB
        end;
      cdEVENT_DIAL_CHANGE :
        event_callback_data.Event := EventDialChanged;
      cdEVENT_CF_GATE_CHANGED :
        event_callback_data.Event := EventCFGateOpened;
      cdEVENT_BATT_COVER_CHANGED :
        event_callback_data.Event := EventBatteryCoverOpened;
      cdEVENT_CONNECTION_TIME_OUT :
        //Timeout handled specially. When this event is received a simple
        //action is performed to cancel the automatic connection closing
        begin
          CamRemoteObj.GetOwnerName;
          result := 0;
          exit;
        end;
      cdEVENT_CONNECTION_DISAPPEARED :
        event_callback_data.Event := EventConnectionDisappeared;
      cdEVENT_UNRECOVERABLE_ERROR :
        event_callback_data.Event := EventUnrecoverableError;
      cdEVENT_UNKNOWN_COMMAND_RECEIVED :
        event_callback_data.Event := EventUnkonwnCommandReceived;
      cdEVENT_RELEASE_PARAM_CHANGED :
        event_callback_data.Event := EventRemoteParamterChanged;
    end;
    CamRemoteObj.mNotifyEvent(event_callback_data);
  end;
  result := cdOk;
end;

function remote_event_callback_function(EventID  : cdReleaseEventID;
                                        pData    : pointer;
	                                      DataSize : cdUInt32;
	                                      Context  : cdContext) : cdUInt32 cdecl {$IFDEF WIN32} stdcall {$ENDIF};
var remote_event : RemoteEventCallbackType;
begin
  remote_event := RemoteEventCallbackNotUsed;
  if assigned(CamRemoteObj.mNotifyRemoteEvent) then
  begin
    case EventID of
      cdRELEASE_EVENT_RELEASE_START :    remote_event := RemoteEventCallbackReleaseStart;
      cdRESEASE_EVENT_RELEASE_COMPLETE : remote_event := RemoteEventCallbackReleaseComplete;
      cdRELEASE_EVENT_RESET_HW_ERROR :   remote_event := RemoteEventCallbackResetHWError;
      cdRELEASE_EVENT_CHANGED_BY_UI :    remote_event := RemoteEventCallbackChangedByUI;
      cdRELEASE_EVENT_CAM_RELEASE_ON :   remote_event := RemoteEventCallbackCamReleaseOn;
      cdRELEASE_EVENT_ABORT_PC_EVF :     remote_event := RemoteEventCallbackViewfinderOff;
      cdRELEASE_EVENT_ENABLE_PC_EVF :    remote_event := RemoteEventCallbackViewfinderOn;
    end;
    CamRemoteObj.mNotifyRemoteEvent(remote_event);
  end;
  result := cdOk;
end;

function view_finder_callback_function(pBuf    : pointer;
 	                                     Size    : cdUInt32;
                                       Format  : cdUInt32;
 	                                     Context : cdContext) : cdUInt32 cdecl {$IFDEF WIN32} stdcall {$ENDIF};
var jpeg_mem_stream : TMemoryStream;

begin
  if Assigned(CamRemoteObj.mNotifyViewfinderEvent) then
  begin
    jpeg_mem_stream := TMemoryStream.Create;
    try
      jpeg_mem_stream.WriteBuffer(pBuf^, Size);
      jpeg_mem_stream.Position := 0;
      CamRemoteObj.mNotifyViewfinderEvent(jpeg_mem_stream);
    finally
      jpeg_mem_stream.Free;
    end;
  end;
  result := cdOk;
end;

function remote_get_picture_callback_function(Progress : cdUInt32;			    //Percentage                            */
                                              Status   : cdProgressStatus;	//Type of process currently in progress */
	                                            Context  : cdContext					//Context                               */
                                              ) : cdUInt32 cdecl {$IFDEF WIN32} stdcall {$ENDIF};
begin
  if Assigned(CamRemoteObj.mNotifyRemoteGetPictureEvent) then
  begin
    CamRemoteObj.mNotifyRemoteGetPictureEvent(Progress);
  end;
  //Not nice solution, but to let the main application thread update the VCL
  //this thread must be halted for a while before continuing.
  Sleep(CALLBACK_REPAINT_DELAY_IN_MS);
  result := cdOk;
end;

function remote_take_picture_callback_function(Progress : cdUInt32;			    //Percentage                            */
                                               Status   : cdProgressStatus;	//Type of process currently in progress */
	                                             Context  : cdContext					//Context                               */
                                               ) : cdUInt32 cdecl {$IFDEF WIN32} stdcall {$ENDIF};
begin
  if Assigned(CamRemoteObj.mNotifyRemoteTakePictureEvent) then
  begin
    CamRemoteObj.mNotifyRemoteTakePictureEvent(Progress);
  end;
  //Not nice solution, but to let the main application thread update the VCL
  //this thread must be halted for a while before continuing.
  Sleep(CALLBACK_REPAINT_DELAY_IN_MS);
  result := cdOk;
end;

function get_picture_callback_function(Progress : cdUInt32;			    //Percentage                            */
                                       Status   : cdProgressStatus;	//Type of process currently in progress */
	                                     Context  : cdContext					//Context                               */
                                       ) : cdUInt32 cdecl {$IFDEF WIN32} stdcall {$ENDIF};
begin
  if Assigned(CamRemoteObj.mNotifyGetPictureEvent) then
  begin
    CamRemoteObj.mNotifyGetPictureEvent(Progress);
  end;
  //Not nice solution, but to let the main application thread update the VCL
  //this thread must be halted for a while before continuing.
  Sleep(CALLBACK_REPAINT_DELAY_IN_MS);
  result := cdOk;
end;

function TCamRemote.RemoteTakePicture(UseSyncMode : boolean) : integer;
begin
  result := 0;
  if (not mRemoteModeEnabled) then
  begin
    raise ECamException.Create('Camera not in remote mode');
  end;
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        result := mCDSDK.RemoteTakePicture(UseSyncMode,
                                           @remote_take_picture_callback_function);
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      begin
        result := mRCSDK.RemoteTakePicture(UseSyncMode,
                                           @remote_take_picture_callback_function);
      end
{$ENDIF};
  end;
end;

procedure TCamRemote.RemoteGetPicture(FileName : string);
begin
  if (not mRemoteModeEnabled) then
  begin
    raise ECamException.Create('Camera not in remote mode');
  end;
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        mCDSDK.RemoteGetPicture(FileName,
                                @remote_get_picture_callback_function);
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      begin
        mRCSDK.RemoteGetPicture(FileName,
                                @remote_get_picture_callback_function);
      end
{$ENDIF};
  end;
end;

function  TCamRemote.RemoteGetRemoteParams : RemoteReleaseParametersType;
begin
  if (not mRemoteModeEnabled) then
  begin
    raise ECamException.Create('Camera not in remote mode');
  end;
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        result := mCDSDK.RemoteGetRemoteParams;
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      begin
        result := mRCSDK.RemoteGetRemoteParams;
      end
{$ENDIF};
  end;
end;

procedure TCamRemote.RemoteSetRemoteParams(RemoteParam : RemoteReleaseParametersType);
begin
  if (not mRemoteModeEnabled) then
  begin
    raise ECamException.Create('Camera not in remote mode');
  end;
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        mCDSDK.RemoteSetRemoteParams(RemoteParam);
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      begin
        mRCSDK.RemoteSetRemoteParams(RemoteParam);
      end
{$ENDIF};
  end;
end;

function  TCamRemote.RemoteGetZoomPos : RemoteZoomCapabilityType;
begin
  if (not mRemoteModeEnabled) then
  begin
    raise ECamException.Create('Camera not in remote mode');
  end;
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        result := mCDSDK.RemoteGetZoomPos;
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      begin
        result := mRCSDK.RemoteGetZoomPos;
      end
{$ENDIF};
  end;
end;

procedure TCamRemote.RemoteSetZoomPos(ZoomPos : integer);
begin
  if (not mRemoteModeEnabled) then
  begin
    raise ECamException.Create('Camera not in remote mode');
  end;
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        mCDSDK.RemoteSetZoomPos(ZoomPos);
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      begin
        mRCSDK.RemoteSetZoomPos(ZoomPos);
      end
{$ENDIF};
  end;
end;

//This function is used when perforing a task when the camera is
//closing a connection because it is idle.
function TCamRemote.GetOwnerName : string;
begin
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        result := mCDSDK.GetOwnerName;
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      begin
        result := mRCSDK.GetOwnerName;
      end
{$ENDIF};
  end;
end;

function TCamRemote.OpenCameraCollection(TempDir : string) : ImageListType;
begin
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        result := mCDSDK.OpenCameraCollection(TempDir);
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      begin
        result := mRCSDK.OpenCameraCollection(TempDir);
      end
{$ENDIF};
  end;
end;

procedure TCamRemote.CloseCameraCollection(var ImageListToClear : ImageListType);
begin
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        mCDSDK.CloseCameraCollection(ImageListToClear);
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      begin
        mRCSDK.CloseCameraCollection(ImageListToClear);
      end
{$ENDIF};
  end;
end;

procedure TCamRemote.GetPicture(NrInList : integer;
                                FileName : string);
begin
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        mCDSDK.GetPicture(NrInList,
                          FileName,
                          @get_picture_callback_function);
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      begin
        mRCSDK.GetPicture(NrInList,
                          FileName,
                          @get_picture_callback_function);
      end
{$ENDIF};
  end;
end;

procedure TCamRemote.DeletePicture(var ImageList : ImageListType;
                                   NrInList      : integer);
begin
  case (mCameraInfo.CameraModel) of
    CamModNone:
      raise ECamException.Create('No camera is connected');
    CamModPowerShot:
{$IFDEF PSDLL}
      begin
        mCDSDK.DeletePicture(ImageList, NrInList);
      end
{$ENDIF};
    CamModEOS:
{$IFDEF EOSDLL}
      begin
        mRCSDK.DeletePicture(ImageList, NrInList);
      end
{$ENDIF};
  end;
end;

end.
