// FileHead.h: interface for the FileHead class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_FILEHEAD_H__72CED654_11DE_4A6F_9FF7_2F71B375A41E__INCLUDED_)
#define AFX_FILEHEAD_H__72CED654_11DE_4A6F_9FF7_2F71B375A41E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "filelog.h"
#include "strbuf.h"
#include "listnode.h"
#include "clientloguser.h"
#include "clientapi.h"
#include "cbase.h"
#include <stdlib.h>

/* These are different filetypes and integ types, respectively.
 * Note that TYPE_BRANCH is both - it was necessary to differentiate
 * adds and branches in order to properly detect "add from" vs "branch from".
 */

#define TYPE_EDIT 1
#define TYPE_DEL 2
#define TYPE_INTEG 3
#define TYPE_ADD 4

#define TYPE_BRANCH 5

#define TYPE_DIRTY 1
#define TYPE_MERGE 2
#define TYPE_COPY 3
#define TYPE_IGNORE 4

/* A FileHead object represents a file and all its revision history.  Its name comes
 * from the fact that it's the head of a linked list of FileRev objects.  The FileHead
 * is a part of a FileLogCache. */

class FileHead  
{
public:
	FileHead(StrBuf, FileLogCache*);
	virtual ~FileHead();

	FileHead* next; //This is the next FileHead in a "from" or "into" chain.
					//See FileLogCache for more info about its structure.

	FileRev* head; //The FileRev corresponding to the head revision of this file.
	FileRev* tail; //The last created FileRev - in a complete FileHead this will be rev #1.

	FileLogCache* parent; //The FileLogCache that this FileHead is a part of.
	
	StrBuf file; //The Perforce path to this file, eg "//depot/foo/file".

	/* addRev adds a new revision to this FileHead, at the tail position.  As 
	 * arguments it takes the revision number, the change number, and the file 
	 * type.  addRev is called once by ClientLogUser for each revision record 
	 * in a filelog.  It is assumed that the revisions will be added in order 
	 * from head to first. */
	void addRev(StrBuf newrev, StrBuf newchange, short);

	/* scanInto is used to follow "into" integration records - it's a command for
	 * this FileHead to locate the revision indicated by the 'startrev' argument,
	 * and set its 'from' pointer to the 'caller' argument.  This is its primary function.
	 * Once this is done, it checks that revision and its successors to see if they were
	 * integrated into other files, and calls scanInto on those files where necessary.  In
	 * this way, all of the children of children are found.  The startrev argument is of
	 * the form "14", and the caller argument is a pointer to the revision that was the source
	 * of the integration that created revision 14. */
	void scanInto(StrBuf startrev, FileRev* caller);

	/* scanFrom is similar to scanInto, but it does roughly the opposite.  It returns the
	 * FileRev object corresponding to the 'endrev' argument - this pointer is used
	 * to establish a 'from' pointer from the caller file to this one.  scanFrom also
	 * checks all of the revisions before the endrev for "from" integration records, and
	 * calls scanFrom on the referenced files. */
	FileRev* scanFrom(StrBuf endrev);
};

/* A FileRev object represents a single file revision.  */
class FileRev  
{
public:
	/* Constructor -  initializes the named variables. */
	FileRev(StrBuf rev, FileHead* file, StrBuf change, short type);
	virtual ~FileRev();

	FileRev* next; //the next FileRev in the linked list.
	FileHead* file; //the FileHead this FileRev is a part of.

	StrBuf rev; //the rev number, eg "14".
	StrBuf change; //the change number, eg "123".
	short type; //the rev type, eg TYPE_EDIT.

	FileRev* from; //if this rev was created by integration, this is its parent.

	bool fromcheck; //Has this rev been touched by scanFrom()?
	bool intocheck; //Has this rev been touched by scanInto()?

	StrBuf fromfile; //The path to the integration parent, if any.
	StrBuf fromrev; //Rev number of the integration parent, if any.
	short fromtype; //Integration type, if any, eg TYPE_COPY.

	ListList intofiles; //List of StrBuf paths to integration children.
	ListList intorevs; //List of StrBuf revs of integration children.

	CBaseEntity* ent; //The CObjectRev created from this FileRev, if any.
};


#endif // !defined(AFX_FILEHEAD_H__72CED654_11DE_4A6F_9FF7_2F71B375A41E__INCLUDED_)
