
/*	Copyright (C) G. Jespersen
	See Licence.txt.*/

#include "stdafx.h"
#include "DsLavSplit.h"

#include "Clipboard.h"
#include "afxpriv.h"	// for CSharedFile


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


CClipboard::CClipboard()
{
}

CClipboard::~CClipboard()
{
}

// Set
BOOL CClipboard::SetClipboardMediaItem(CMediaItem item)
{
	// Get format needed by this app.
	#ifdef UNICODE
	UINT TXT_FMT = CF_UNICODETEXT;
	#else
	UINT TXT_FMT = CF_TEXT;
	#endif

	// App ptr.
	CDsLavApp * pApp = (CDsLavApp*)AfxGetApp();
	if(!pApp)
		return FALSE;
	HWND hWnd = pApp->GetMainWnd()->GetSafeHwnd();

	// Get MediaItem as a CString in Media Record format.
	CString str = MediaItemToCbString(item);

	// Write
	if(OpenClipboard(hWnd))
	{
		// Clean up.
		EmptyClipboard();

		// Allocate - plus one for null teminator.
		int len = str.GetLength();
		HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(TCHAR) * (len + 1));
		if(!hData)
		{
			CloseClipboard();
			return FALSE;
		}

		// Get a ptr to clipboard mem.
		LPTSTR pData = (LPTSTR) GlobalLock(hData);

		// Copy to clipboard.
		//
		// Note GetBuffer() returns an LPTSTR pointer to the
		// strings (null-terminated) character buffer.
		//
		// Also, the length param is the minimum size of the 
		// character buffer in characters. This value does 
		// not include space for a null terminator.
		//
		// See msdn GetBuffer().
		//
		lstrcpy(pData, str.GetBuffer(len));

		// Release str buf.
		str.ReleaseBuffer();

		// Pass control of the mem to the clipboard.
		GlobalUnlock(hData);

		// Set the clipboard.
		SetClipboardData(TXT_FMT, hData);

		// Close.
		CloseClipboard();
		
		return TRUE;
	}
	// Clipboard not available.
	return FALSE;
}

// Get
BOOL CClipboard::GetClipboardMediaItem(CMediaItem & item)
{
	TRACE(_T("Entering CClipboard::GetClipboardText\n"));

	#ifdef UNICODE
	int TXT_FMT = CF_UNICODETEXT;
	#else
	int TXT_FMT = CF_TEXT;
	#endif

	// App ptr.
	CDsLavApp * pApp = (CDsLavApp*)AfxGetApp();
	if(!pApp)
		return FALSE;
	HWND hWnd = pApp->GetMainWnd()->GetSafeHwnd();

	CString str;

	// If we can get the clipboard.
	if(OpenClipboard(hWnd))
	{
		// Check for text.
		if(IsClipboardFormatAvailable(TXT_FMT))
		{
			// Get text as a CString.
			HANDLE hData = ::GetClipboardData(TXT_FMT);// HGLOBAL instead?

			// Use the T cast.
			str = (LPTSTR)::GlobalLock(hData);
			GlobalUnlock(hData);

			// Close Clipboard.
			CloseClipboard();

			// Bail if empty.
			if(str.IsEmpty())
				return FALSE;

			// Done.
		//	return TRUE;
		}
		// Close if not done above.
		CloseClipboard();
	}
	// Convert str to MediaItem;
	if(CbStringToMediaItem(str, item))
	{
		int g = 0;
	}
	//---

	// No go
	return FALSE;
}

// Get string for clipboard from MediaItem.
CString CClipboard::MediaItemToCbString(CMediaItem & item)
{
	// Build string in Media Record format:
	//
	CString newline = _T("\r\n"); // good notepad
	CString str;

	str += _T("0");								// Code 0
	str += newline;								// newline
	str += item.GetStreamTypeDefinitionString();// Type Def as string
	str += newline;								// newline
	str += _T("6");								// Code 6
	str += newline;								// newline
	str += item.GetMediaItemTopicCsNodes();		// Comma Separated topic nodes
	str += newline;								// newline
	str += _T("7");								// Code 7
	str += newline;								// newline
	if(item.m_isFavorite)						// Write fav yes or no.
		str += _T("yes");						// TRUE
	else
		str += _T("no");						// FALSE
	str += newline;								// newline
	str += _T("10");							// Code 10
	str += newline;								// newline
	str += item.m_mediaName;					// Name
	str += newline;								// newline
	str += _T("11");							// Code 11
	str += newline;								// newline
	str += item.m_mediaUrl;						// URL/Path
	str += newline;								// end newline - used when parsing 
												//  in CbStringToMediaItem().
	return str;
}

// Get a MediaItem from a clipboard string. 
// Note: Final chars on string should be \r\n.
BOOL CClipboard::CbStringToMediaItem(CString str, CMediaItem & item)
{
	CString newline = _T("\r\n");
	CString code, value;
	int nPos = 0;
	int len = 0;
	int gotten = 0;

	while(str.GetLength() > 0)
	{
		// Get code
		nPos = str.Find(newline);
		if(nPos == -1)
			break;
		code = str.Left(nPos);

		// Get remainder of string after newline.
		len = str.GetLength();
		if(nPos + 2 > len)			// valid test?
			break;
		str = str.Mid(nPos + 2);

		// Get value.
		nPos = str.Find(newline);
		if(nPos == -1)
		{
			// Ensure - will get here of no newline at end of string.
			if(code == _T("11"))	// Media URL 
			{
				item.m_mediaUrl = str;
				gotten ++;
			}
			// Bail - success or fail.
			break;
		}
		value = str.Left(nPos);

		// Get remainder of string after newline.
		len = str.GetLength();
		if(nPos + 2 > len)			// valid test?
			break;
		str = str.Mid(nPos + 2);

		// Process.
		if(code == _T("0"))			// Media Type
		{
			item.m_mediaType = item.GetMediaTypeFromString(value);
			gotten ++;
		}
		else if(code == _T("6"))	// Topic Hierarchy
		{
			item.SetMediaItemTopicNodes(value);
			gotten ++;
		}
		else if(code == _T("7"))	// Is Favorite
		{
			if(value == _T("yes"))
				item.m_isFavorite = TRUE;
			else
				item.m_isFavorite = FALSE;
			gotten ++;
		}
		else if(code == _T("10"))	// Media Name
		{
			item.m_mediaName = value;
			gotten ++;
		}
		else if(code == _T("11"))	// Media URL 
		{
			item.m_mediaUrl = value;
			gotten ++;
		}
	}
	if(gotten == 5)
		return TRUE;
	else
		return FALSE;
}

// Is CB Data available.
BOOL CClipboard::DataAvailable()
{
	BOOL available = FALSE;

	// Get format needed by this app.
	#ifdef UNICODE
	UINT TXT_FMT = CF_UNICODETEXT;
	#else
	UINT TXT_FMT = CF_TEXT;
	#endif

	// App ptr.
	CDsLavApp * pApp = (CDsLavApp*)AfxGetApp();
	if(!pApp)
		return FALSE;
	HWND hWnd = pApp->GetMainWnd()->GetSafeHwnd();

	// Get the custom GrObj clipboard format.
	UINT ITEM_FMT = pApp->m_uiCbMediaItem;


	// If we can get the clipboard.
	if(OpenClipboard(hWnd))
	{
		// Check for plain or unicode text, and this 
		// apps Registered Type.
		if(IsClipboardFormatAvailable(TXT_FMT)	&&
		   IsClipboardFormatAvailable(ITEM_FMT) )
			available = TRUE;

		// Close.
		CloseClipboard();
	}
	return available;
}
