/******************************************************************************
 *
 * Copyright (c) 1999	TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 *  
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 *	LineDevice.h
 *
 *****************************************************************************/

// SOL++2000

#ifndef _SOL_VIEW
#include <sol\View.h>
#endif
#include <tapi.h>

#ifndef _SOL_LINEDEVICE 
#define _SOL_LINEDEVICE

#define TAPI_BUFFER_SIZE	1024

typedef struct {
	DWORD dwDevice; 
	DWORD dwMsg;
	DWORD dwCallbackInst;
	DWORD dwParam1;
	DWORD dwParam2;
	DWORD dwParam3;
} TAPI_CALLBACK;


class LineDevice :public Object {
	int      extraSize;
	UINT	 callbackMessage;
	View*    view;
    HLINEAPP lineApp;
	HLINE    hLine;
	HCALL    hCall;
	DWORD	dwLineID;
	DWORD	dwNumDevices;
	DWORD	dwAPIVersion;

	DWORD   eCallState;
	DWORD  	dwRequestID;
	DWORD  	dwAddressID;
	LPCSTR 	lpszAddress;

	DWORD	dwNumAddress;

	char	dialString[TAPI_BUFFER_SIZE];  
	char	dialStringOriginal[TAPI_BUFFER_SIZE];
	char	dialStringCanonical[TAPI_BUFFER_SIZE];
	char	calledParty[TAPI_BUFFER_SIZE]; 
	DWORD	dwTranslateResults; 
	char	lineName[128];
	static	LineDevice* self;
	LINEEXTENSIONID	 ext;

	HWND    hdialog;
	DWORD	sizeDeviceConfig;
	void*   deviceConfig;

	static LRESULT CALLBACK lineCallbackProc(DWORD dwDevice, 
			DWORD dwMsg,
			DWORD dwCallbackInst, DWORD dwParam1,
			DWORD dwParam2,DWORD dwParam3);

public:						  
	LineDevice(View* view, UINT message);
	~LineDevice();

	long	accept(const char* userUserInfo, DWORD dwSize);
  
	long	addProvider(const char* providerFilename, HWND hwndOwner, 
				DWORD* dwPermanentProviderID);
	long	addToConference(HCALL hConsultCall);
  
	long	answer(const char* userUserInfo, DWORD dwSize);
	long	blindTransfer(const char* destAddress, DWORD dwCountryCode);

	long	close();
	long	completeCall(DWORD* dwCompletionID, 
				DWORD dwCompletionMode, DWORD dwMessageID);

	long	completeTransfer(HCALL hConsultCall, 
				HCALL* hConfCall, DWORD dwTransferMode);

	long	configDialogEdit (DWORD dwDeviceID, HWND hwndOwner, 
		  		const char* deviceClass, LPVOID const lpDeviceConfigIn, 
		  		DWORD dwSize, VARSTRING* deviceConfigOut);

	long	deallocateCall();
	long	devSpecific(DWORD dwAddressID, void* params, DWORD dwSize);

	long	devSpecificFeature(DWORD dwFeature, void* params, DWORD dwSize);

	long	dial(const char* destAddress, DWORD dwCountryCode);
	long	drop();

	long	forward(DWORD bAllAddresses, DWORD dwAddressID, 
				LPLINEFORWARDLIST const lpForwardList, DWORD dwNumRingsNoAnswer, 
				LPHCALL lphConsultCall, LPLINECALLPARAMS const lpCallParams);
  
	long	gatherDigits(DWORD dwDigitModes, char* digits, 
				DWORD dwNumDigits, const char* terminationDigits, 
				DWORD dwFirstDigitTimeout, DWORD dwInterDigitTimeout);

	long	generateDigits(DWORD dwDigitMode, const char* digits, 
				DWORD dwDuration);

	long	generateTone(DWORD dwToneMode, DWORD dwDuration, 
				DWORD dwNumTones, LPLINEGENERATETONE const lpTones);


	LINEADDRESSCAPS* getAddressCaps(DWORD dwDeviceID, DWORD dwAddressID,
				DWORD dwAPIVersion, DWORD dwExtVersion);

	long	getAddressID(LPDWORD lpdwAddressID, DWORD dwAddressMode, 
				LPCSTR lpsAddress, DWORD dwSize);
  
	LINEADDRESSSTATUS* getAddressStatus(DWORD dwAddressID);
  
	long	getAppPriority(LPCSTR lpszAppFilename, DWORD dwMediaMode, 
				LPLINEEXTENSIONID const lpExtensionID, DWORD dwRequestMode, 
				LPVARSTRING lpExtensionName, LPDWORD lpdwPriority) {
			return lineGetAppPriority(lpszAppFilename, dwMediaMode, 
		   		lpExtensionID, dwRequestMode, lpExtensionName, lpdwPriority);
	}

	UINT	getCallbackMessage() { return callbackMessage; }

	long	getCallInfo(LPLINECALLINFO lpCallInfo);
  
	LINECALLSTATUS* getCallStatus();

	long	getConfRelatedCalls(LPLINECALLLIST lpCallList);
	long	getCountry(DWORD dwCountryID, DWORD dwAPIVersion, 
				LPLINECOUNTRYLIST lpLineCountryList) {
			return lineGetCountry(dwCountryID, dwAPIVersion, 
					lpLineCountryList);
	}

	LINEDEVCAPS* getDevCaps();

	LINEDEVCAPS* getDevCaps(DWORD dwDeviceID, DWORD dwAPIVersion);

	long	getDevConfig(DWORD dwDeviceID, LPVARSTRING lpDeviceConfig, 
				LPCSTR lpszDeviceClass) {
			return lineGetDevConfig(dwDeviceID, lpDeviceConfig, 
				lpszDeviceClass);
	}

	long	getIcon(DWORD dwDeviceID, LPCSTR lpszDeviceClass, 
				LPHICON lphIcon) {
			return  lineGetIcon(dwDeviceID, lpszDeviceClass, lphIcon);
	}
	HANDLE	getID();

	DWORD	getNumOfDevice() { return dwNumDevices; }

	long	getID(DWORD dwAddressID, DWORD dwSelect, 
				LPVARSTRING lpDeviceID, LPCSTR lpszDeviceClass);
	long	getLineDevStatus(LINEDEVSTATUS* status);

	long	getNewCalls(DWORD dwAddressID, DWORD dwSelect, 
				LPLINECALLLIST lpCallList);

	long	getNumRings(DWORD dwAddressID, LPDWORD lpdwNumRings);

	long	getProviderList(DWORD dwAPIVersion, 
				LINEPROVIDERLIST* lpProviderList) {
			return lineGetProviderList(dwAPIVersion, lpProviderList);
	}
	long	getRequest(DWORD dwRequestMode, LPVOID lpRequestBuffer);

	DWORD	getRequestID() { return dwRequestID; }

	long	getStatusMessages(LPDWORD lpdwLineStates, LPDWORD lpdwAddressStates);
  
	long	getTranslateCaps(DWORD dwAPIVersion, 
				LPLINETRANSLATECAPS lpTranslateCaps);
	View*	getView() { return view; }

	long	handoff();	
  
	long	handoff(LPCSTR lpszFileName, DWORD dwMediaMode);

	BOOL	hangupCall();

	long	hold();
	long	initialize(HINSTANCE hInst);

	long	makeCall();

	long	makeCall(LPCSTR lpszDestAddress, DWORD dwCountryCode, 
				LPLINECALLPARAMS const lpCallParams);

	long	monitorDigits(DWORD dwDigitModes);
	long	monitorMedia(DWORD dwMediaModes);
	long	monitorTones(LPLINEMONITORTONE	const lpToneList, 
			DWORD dwNumEntries);
	long	negotiateAPIVersion(DWORD lowVersion, DWORD hiVersion);

	DWORD	negotiateLegacyAPIVersion(DWORD dwDeviceID);
  
	long	negotiateExtVersion(DWORD lowVersion, DWORD highVersion);

	long	open();

	long	open(DWORD dwDeviceID,  
				DWORD dwAPIVersion, DWORD dwExtVersion,
				DWORD dwPrivileges, DWORD dwMediaModes, 
				LPLINECALLPARAMS const lpCallParams);
 
	long	park(DWORD dwParkMode, LPCSTR lpszDirAddress, 
				LPVARSTRING lpNonDirAddress);

	long	pickup(DWORD dwAddressID, LPHCALL lphCall, 
				LPCSTR lpszDestAddress, LPCSTR lpszGroupID);

	long	prepareAddToConference(HCALL hConfCall, LPHCALL lphConsultCall, 
				LPLINECALLPARAMS const lpCallParams);

	long	redirect(LPCSTR lpszDestAddress, DWORD dwCountryCode);
  
	long	registerRequestRecipient(DWORD dwRegistrationInstance, 
				DWORD dwRequestMode, DWORD bEnable);
	long	releaseUserUserInfo();
	long	removeFromConference();

	long	removeProvider(DWORD dwPermanentProviderID, HWND hwndOwner);
	long	secureCall();
	long	sendUserUserInfo(LPCSTR lpsUserUserInfo, DWORD dwSize);

	long	setAppPriority(LPCSTR lpszAppFilename, DWORD dwMediaMode, 
				LPLINEEXTENSIONID const lpExtensionID, DWORD dwRequestMode, 
				LPCSTR lpszExtensionName, DWORD dwPriority);
	long	setAppSpecific(DWORD dwAppSpecific);
  
	long	setCallParams(DWORD dwBearerMode, DWORD dwMinRate, 
				DWORD dwMaxRate, LPLINEDIALPARAMS const lpDialParams);

	long	setCallPrivilege(DWORD dwCallPrivilege);
	long	setCurrentLocation(DWORD dwLocation);

	long	setDevConfig(DWORD dwDeviceID, LPVOID const lpDeviceConfig,
			int size, LPCSTR devClass); 

	long	setStatusMessages(DWORD devState, DWORD devAddr);

	long	shutdown();

	LINETRANSLATEOUTPUT* translateAddress(DWORD dwDeviceID, 
				DWORD dwAPIVersion, LPCSTR lpszDialAddress);

 	long	translateAddress(char* szNumber);

	LONG	translateDialog (DWORD dwDeviceID, DWORD dwAPIVersion, 
				HWND hwndOwner, LPCSTR lpszAddressIn);
	long	unhold();
};

#endif
