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

#if !defined MEDIADEFS_H
#define MEDIADEFS_H

#if _MSC_VER > 1000
#pragma once
#endif

#include <afxtempl.h>	// CArray
#include "strsafe.h"	// StringCbCopy
//#include "LavSetup.h"

#define STR_FAVS _T("Favorites")
#define STR_ERROR _T("ERROR")

// For moving topics 9/22-1
enum MOVE_TYPE{	MOVE_NONE,	// uninitialized
				MOVE_ON,	// insert topic into another topic array
				MOVE_ABOVE,	// move topic below sibling topic
				MOVE_BELOW	// move topic above sibling topic
				};

// Def media types. Media items have a MEDIA_TYPE which is used 
// to display icons, and is shown in the ListPane Type column.
enum MEDIA_TYPE{NONE,	// empty
				AUDU,	// audio url		- http, https
				VIDU,	// video url		- http, https
				VIDF,	// video file	- mp4,
				AUDF 	// audio file	- mp3,
				};

// Forwards
class CTopicStrAliasAr;
class CStdioFileEx;

/////////////////////////////////////////////////////////////////////////////
// CExtension - file and stream extensions and their Media Type 12/22-5
class CExtension
{
public:
	CExtension();
	~CExtension();
	CExtension(CString & strExtension, MEDIA_TYPE & type);
	void	operator=(const CExtension & extension);
	BOOL	operator==(const CExtension & extension);
	BOOL	operator!=(const CExtension & extension);
	void	Zero();
	void	CopyExtension(const CExtension & extension);
	CString m_strExtension;		// mp4 etc
	MEDIA_TYPE m_extType;		// VIDF etc
};
/////////////////////////////////////////////////////////////////////////////
// CExtensionArray.  
class CExtensionArray : public CArray<CExtension, CExtension&>   
{
public:
	CExtensionArray();
	~CExtensionArray();
	BOOL GetPathExtension(CString path, CExtension & extension);
	BOOL IsValidExtension(CString extStr);
	MEDIA_TYPE GetExtensionMediaType(CString strExtension, BOOL bIsUrl);
	void AddExtension(CString strExtension, MEDIA_TYPE type);
	void BuildExtensions();
};


/////////////////////////////////////////////////////////////////////////////
// CNodeItem - a Topic name and an array index.
class CNodeItem
{
public:
	CNodeItem();
	~CNodeItem();
	CNodeItem(const CNodeItem & nodeItem);
	void		operator=(const CNodeItem & nodeItem);
	BOOL		operator==(const CNodeItem & nodeItem);
	BOOL		operator!=(const CNodeItem & nodeItem);
	void		Read(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);
	void		Write(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);
	void		Test(CTopicStrAliasAr & ar);
	void		Zero();
	BOOL		IsValid() const; 
	CString m_topicName;
	int		m_arIndex;
};

/////////////////////////////////////////////////////////////////////
// CNodeArray.  
// The CNodeItems allow for faster tree traversal and positive topic 
// identification when duplicate topic names occur.  
class CNodeArray : public CArray<CNodeItem, CNodeItem&>   
{
public:
	CNodeArray();
	~CNodeArray();
	CNodeArray(const CNodeArray & ar);
	void		CopyNodeArray(const CNodeArray & ar);
	void		operator=(const CNodeArray & ar);
	BOOL 	operator==(const CNodeArray & ar);
	BOOL 	operator!=(const CNodeArray & ar);
	void		GetTopicNameStrings(CStringArray & strAr) const; // const no mod CNodeArray
	BOOL		IsParentNodeOf(const CNodeArray & ar, BOOL & equals) const;		// 9/22-1 add const
	BOOL		IsParentNodeOf(const CStringArray & ar, BOOL & equals) const;	// 9/22-1 add cosnst
	BOOL		IsSiblingNodeOf(const CNodeArray & ar, BOOL & bAreRoots) const; // 9/22-1
	BOOL		IsParentNodeOf(const CNodeArray & ar, BOOL & equals);
	BOOL		IsParentNodeOf(const CStringArray & ar, BOOL & equals);
	BOOL		GetParentNodes(CNodeArray & parentAr) const;
	BOOL		GetTopicNodeItem(CNodeItem & topicItem) const;
	void		UpdateTopicIndex(int index);
	void		UpdateTopicName(CString & topicName);
	CString GetTopicName() const;
	// Disks
	CString	GetFilePathFromNodes() const;
	void		SetNodesFromFilePath(CString filePath);
	// I/O
	void		Read(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);
	void		Write(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);
};
/////////////////////////////////////////////////////////////////////////////
// CNodesArArray - an array of CNodeArrays.
class CNodesArArray : public CArray <CNodeArray, CNodeArray&> 
{
	public:
	BOOL operator==(const CNodesArArray & ar)
	{
		for(int i = 0; i < GetSize(); i++)
		{
			if(GetAt(i) != ar.GetAt(i))
				return FALSE;
		}
		return TRUE;
	};
	void operator=(const CNodesArArray & ar)
	{
		Copy(ar);
	}
};

/////////////////////////////////////////////////////////////////////////////
// CMediaItem
class CMediaItem
{
public:
	CMediaItem();
	~CMediaItem();
	CMediaItem(const CMediaItem & video);

	void		operator=(const CMediaItem & item);
	BOOL		operator==(const CMediaItem & item);
	BOOL		operator!=(const CMediaItem & item);
	void		Copy(const CMediaItem & item);
	BOOL		SetMediaItem(MEDIA_TYPE mediaType, CString mediaName, 
						 CString mediaUrl, BOOL isFavorite, CString CsNodes);
	BOOL		SetMediaItem(MEDIA_TYPE mediaType, CString mediaName, 
						 CString mediaUrl, BOOL isFavorite, 
						 CString CsNodes, CTopicStrAliasAr * pAliasAr);
	BOOL		SetMediaItemTopicNodes(CString CsNodes);
	BOOL		SetMediaItemTopicNodes(CString CsNodes, CTopicStrAliasAr * pAliasAr);
	CString	GetStreamTypeString();
	CString	GetStreamTypeDefinitionString();
	CString	GetMediaTopicName();
	CString	GetDefaultMediaTopicName();
	CString GetMediaItemTopicCsNodes();
	BOOL		IsValidItem();
	void		Zero();
	void		Read(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);
	void		Write(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);
	MEDIA_TYPE GetMediaTypeFromString(CString typeStr);
	// Disc.
	void		SetNodesFromFilePath(CString filePath);

	MEDIA_TYPE	 m_mediaType;	// Code 0
	CString		 m_mediaName;	// Code 10
	CString		 m_mediaUrl;	// Code 11 for streaming per Media Type
	CStringArray m_nodesList;	// Code 6  topic tree name hierarchy 
	BOOL		 m_isFavorite;	// Code 7  optional - default false.

	// Note: m_nodesList could be eliminated, as the parent topic of
	// a media item contains those topics in its CNodeArray. It would 
	// take a fair amount of coding to do, and would save some memory
	// and add complexity.
};

/////////////////////////////////////////////////////////////////////////////
// CMediaArray - an array of CMedia items.
class CMediaArray : public CArray <CMediaItem, CMediaItem&> 
{
	public:
	BOOL operator==(const CMediaArray & ar);
	void operator=(const CMediaArray & ar);
	BOOL IsDuplicateItem(const CMediaItem & item);
	void Read(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);
	void Write(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);

	// Sort items
	void SortMediaName(BOOL ascend);
	protected:
	static int CompareMediaNameAscend(const void *, const void *);
	static int CompareMediaNameDescend(const void *, const void *);
};

/////////////////////////////////////////////////////////////////////////////
// CTopicStrAliasAr
//
struct TOPIC_STR_ALIAS
{
	CString str;
	CString alias;
};
// Def Topic Name aliases. Optional use provides for Tree uniformity, 
// reduced BYTES in text file lists and serialized files, and reduced 
// cycles when comparing topic strings.
//
// Single instance in CDsLavDoc.
// Aliases loaded from TopicAlias.txt in InitializeTopicAlias().
class CTopicStrAliasAr : public CArray <TOPIC_STR_ALIAS, TOPIC_STR_ALIAS&>
{
public:
	BOOL	AddTopicAlias(CString str, CString alias);
	BOOL	InitializeTopicAlias();
	BOOL	GetTopicAlias(CString & str);
	BOOL	GetTopicString(CString & str);
	CString TopicStringToAlias(CString & str);
	CString AliasToTopicString(CString & alias);
	BOOL	ConvertFromCsAlias(CStringArray & ar, CString csStr);
	BOOL	ConvertFromCsAlias(CMediaItem & item);
	BOOL	ConvertFromCsAlias(CString & csStr);
	BOOL	ConvertToCsAlias(const CStringArray & ar, CString & csStr);
};

/////////////////////////////////////////////////////////////////////
// CTopicArray - an array of CTopic items.
class CTopic;
class CTopicArray : public CArray <CTopic, CTopic&> 
{
public:
	BOOL operator==(const CTopicArray & ar);
	void Read(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);
	void Write(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);
};

////////////////////////////////////////////////////////////////////
// CTopic - A Topic with any number of MediaItems and Child Topics,
// all stored in CArrays.
//
// A Topic is initially created from the Topic Names in the nodesList 
// of a MediaItem. The entire TopicTree is formed in this way through
// calls to CTopicTree::AddMediaItemToTree().
//
// A topic saves it location in the TopicTree in its m_nodesAr member,
// which specifies the topic's TopicTree hierarchy including array
// indices for each node. This m_nodesAr is updated when the Topic is
// relocated/renamed.
//
// A Topic has a MEDIA_TYPE - the original intention was to have only
// media items of one type per topic hierarchy, but the user is 
// allowed mix and match types so it's not a hard and fast rule.
class CTopic
{
public:
	CTopic();
	~CTopic();
	CTopic(const CTopic & item);
	void		operator=(const CTopic & item);
	BOOL		operator==(const CTopic & item);
	BOOL		operator!=(const CTopic & item);
	void		Copy(const CTopic & item);
	void		Zero();
	BOOL		GetFavorites(CMediaArray & mediaAr, CNodesArArray & nodesAr, int & nFavsGotten);
	CTopic& GetTopicRef(const CNodeArray & nodesAr, int nodeElmt, CTopic & errTopic);
	BOOL		GetTopicMediaItems(CMediaArray & mediaAr);
	CString GetTopicName();
	CString GetTopicTypeString();
	BOOL		PrintTopicMediaItems(CTopicStrAliasAr & alias);
	BOOL		CountTopicsMediaItems(int & nTopics, int & nMediaItems);
	BOOL		WriteMediaRecordFormatEx(CStdioFileEx & file, CTopicStrAliasAr & alias, 
									 BOOL & excludeDisc, BOOL & writeAlias, int & nWritten);
	BOOL		WriteM3uStreamsEx(CStdioFileEx & file, int & nWritten);
	BOOL		DeleteMediaItem(const CMediaItem & mediaItem);
	BOOL		GetCreateTopicNodes(const CStringArray & nodesList, const MEDIA_TYPE & type,
								int listElmt, CNodeArray & nodesAr);
	void		SetTopicName(CString str);
	BOOL		IsParentNodeOf(const CNodeArray & ar, BOOL & equals);
	BOOL		IsParentNodeOf(const CStringArray & ar, BOOL & equals);
	BOOL		ResetChildTopicAndMediaNodes(int & nResets);
	void		Read(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);
	void		Write(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);

	CNodeArray	m_nodesAr;			// tree nodes - last node is topic name
	MEDIA_TYPE	m_topicMediaType;	// topic and media types match not mandatory
	CMediaArray m_topicMediaAr;		// CMediaItem array
	CTopicArray m_childTopicAr;		// CTopic array
};

////////////////////////////////////////////////////////////
// CTopicTree - An array of Root CTopics and their children.
class CTopicTree
{
public:
	CTopicTree();
	~CTopicTree();
	CTopicTree(const CTopicTree & tree);
	void		operator=(const CTopicTree & tree);
	BOOL		operator==(const CTopicTree & tree);
	BOOL		operator!=(const CTopicTree & tree);
	void		Copy(const CTopicTree & tree);
	void		Zero();
	BOOL		AddMediaItemToTree(CMediaItem & item, BOOL setResultsTopic = FALSE);
	BOOL		GetFavorites(CMediaArray & mediaAr, CNodesArArray & nodesAr, int & nFavsGotten);
	CTopic& GetTopicRef(const CNodeArray & nodesAr, CTopic & errTopic);
	BOOL		GetTopic(const CNodeArray & nodesAr, CTopic & topic);
	int		GetTopicChildTopicNamesNodes(CTopic & topic, CStringArray & namesAr, 
										 CNodesArArray & nodesAr);
	BOOL		DeleteTopic(const CNodeArray & nodesArray, BOOL setResultsTopic = FALSE);
	BOOL		MoveTopic(const CNodeArray & nodesArSrc, const CNodeArray & nodesArDest,		//9/22-1
					   MOVE_TYPE moveType, BOOL setResultsTopic = FALSE);
	BOOL		MoveTopicSibling(const CNodeArray & nodesArSrc, const CNodeArray & nodesArDest,
							 BOOL setAfter, BOOL setResultsTopic = FALSE);
	BOOL		MoveMediaItem(const CMediaItem & mediaItem, const CNodeArray & nodesArSrc, 
						  const CNodeArray & nodesArDest);
	BOOL		MoveMediaItemMulti(const CMediaArray & mediaAr, const CNodeArray & nodesArSrc,
							   const CNodeArray & nodesArDest, BOOL setResultsTopic = FALSE);

	BOOL		ReplaceMediaItem(const CNodeArray & nodesArOld, CMediaItem & mediaItemOld, 
							 CMediaItem & mediaItemNew, BOOL setResultsTopic = FALSE);
	BOOL		UpdateMediaItem(const CNodeArray & nodesAr, CMediaItem & mediaItemOld, 
							CMediaItem & mediaItemUpdate, BOOL setResultsTopic = FALSE);
	BOOL		SortMediaArray(const CNodeArray & nodesAr, BOOL ascend, BOOL setResultsTopic);
	BOOL		SetMediaItemFavorites(const CNodeArray & nodesAr, const CMediaItem & mediaItem, 
								  BOOL isFavorite, BOOL setResultsTopic = FALSE);
	BOOL		DeleteMediaItem(const CNodeArray & nodesAr, const CMediaItem & mediaItem,
							BOOL setResultsTopic = FALSE);
	BOOL		DeleteMediaItemMulti(const CNodeArray & nodesAr, const CMediaArray & mediaAr,
								 BOOL setResultsTopic = FALSE);
	BOOL		AddMediaItemToTopic(const CNodeArray & nodesAr, CMediaItem & mediaItem,
								BOOL setResultsTopic);
	BOOL		AddMediaItemsToTopic(const CNodeArray & nodesAr, CMediaArray & ar,
								 BOOL setResultsTopic);
	BOOL		GetCreateTopicNodes(const CStringArray & nodesList, const MEDIA_TYPE & type,
								CNodeArray & nodesAr);
	BOOL		InsertTopic(const CStringArray & nodesList, const MEDIA_TYPE & type, 
						BOOL setResultsTopic = FALSE);
	BOOL		InsertTopic(const CNodeArray & nodesArDest, CTopic & newTopic,
						BOOL setResultsTopic = FALSE);
	BOOL		UpdateTopic(const CNodeArray & nodesAr, CString topicName, 
						MEDIA_TYPE	type, BOOL setResultsTopic);
	// I/O
	void		PrintContentsMediaItems();
	void		CountTopicsMediaItems(int & nTopics, int & nMediaItems);
	BOOL		WriteTopicTreeMediaItemsxxx(CStdioFile & file, BOOL & bExcludeDiscFiles, int & nWritten);
	BOOL		WriteMediaRecordFormatEx(CStdioFileEx & file, CTopicStrAliasAr & alias,
									 BOOL writeAlias, BOOL & excludeDisc, 
									 int & nWritten);
	BOOL		WriteM3uStreamsEx(CStdioFileEx & file, int & nWritten);
	void		Read(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);
	void		Write(CArchive & ar, CTopicStrAliasAr & aliasAr, int & version);


	// Temp topic used as param with GetTopicRef. See Zero().
	CTopic m_errTopic;

	// Another temp topic initialized by functions with 
	// the BOOL setResultsTopic default param.
	// Alternative to passing CTopic ptr params.
	CTopic m_resultTopic;

	// An array of CTopics and their child topics, each of
	// a single MEDIA_TYPE.
	CTopicArray m_topicTreeAr;		
};

#endif // MEDIADEFS_H	