#ifndef LIBRCS__FILE_H
#define LIBRCS__FILE_H

/*
 * Copyright (c) 2003  Petr Baudis.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials
 *     provided with the distribution.
 *   * Neither the name of the author nor the names of the product's
 *     contributors may be used to endorse or promote products
 *     derived from this software without specific prior written
 *     permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS
 * 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.
 */

#ifdef __cplusplus
extern "C" {
#endif


#include <stdio.h> /* FILE */

#include <librev/inode.h>
#include <librev/list.h>

#include <librcs/librcs.h>


/* This file describes the librcs' basic object: {struct rcs_file}. It describes
 * the physical RCS file and some data which are too specific to fit inside of
 * {struct rev_inode}. The object is back-reachable from rev_inode.data. */

rcs_object (file,
	/* Public attributes */

	/* The physical filename of the file. */
	/* {rcs_file_get_name()}, {rcs_file_set_name()} */
	char *filename;

	/* A linked list of users permitted to access this file. Note that this
	 * isn't a regular object as it is not expected to occur outside of the
	 * rcs_file context at all, you should implement own object if you want
	 * to store it separately. */
	/* {rcs_file_get_accesslist()} */
	struct rcsaccess {
		char *user;
		struct rev_list_item accesses; /* accesslist */
	};
	struct rev_list_head accesslist; /* (struct rcsacces *) */

	/* A linked list of locks being hold. Note that this isn't a regular
	 * object as it is not expected to occur outside of the rcs_file context
	 * at all, you should implement own object if you want to store it
	 * separately. */
	/* {rcs_file_get_lockslist()} */
	struct rcslock {
		char *user;
		struct rev_revision *rev;
		struct rev_list_item locks; /* lockslist */
	};
	struct rev_list_head lockslist; /* (struct rcslock *) */

	/* Comment string. */
	/* {rcs_file_get_comment()}, {rcs_file_set_comment()} */
	char *comment;

	/* File description. */
	/* {rcs_file_get_desc()}, {rcs_file_set_desc()} */
	char *desc;

	/* The rev_inode object, containing the rest of information in a
	 * generic form. */
	/* {rcs_file_get_inode()} */
	struct rev_inode *inode;

	/* Private attributes */

	/* The stream associated with the file. */
	FILE *file;
);

/* Constructor */

/* This creates the object associated with given filename. It doesn't actually
 * load the file yet. */
/* Returns the pointer on success, NULL otherwise. */
struct rcs_file *rcs_file_init (struct rev_inode *inode, char *filename);

/* Attributes */

#include <assert.h>
#include <stdlib.h>

/* This returns the filename string. */
static inline char *
rcs_file_get_filename (struct rcs_file *obj)
{
	assert (obj);
	return obj->filename;
}

/* This sets the filename string (freeing the old one, if any). */
static inline void
rcs_file_set_filename (struct rcs_file *obj, char *filename)
{
	assert (obj);
	if (obj->filename) free (obj->filename);
	obj->filename = filename ? strdup (filename) : NULL;
}

/* This returns the accesslist of the given file, a linked list of username
 * strings. You can freely add/remove from this list. */
static inline struct rev_list_head *
rcs_file_get_accesslist (struct rcs_file *obj)
{
	assert (obj);
	return &obj->accesslist;
}

/* This returns the list of locks held on the given file, a linked list of
 * {struct rcslock} instances. You can freely add/remove from this list. */
static inline struct rev_list_head *
rcs_file_get_lockslist (struct rcs_file *obj)
{
	assert (obj);
	return &obj->lockslist;
}

/* This returns the comment string. */
static inline char *
rcs_file_get_comment (struct rcs_file *obj)
{
	assert (obj);
	return obj->comment;
}

/* This sets the comment string. */
static inline void
rcs_file_set_comment (struct rcs_file *obj, char *comment)
{
	assert (obj);
	if (obj->comment) free (obj->comment);
	obj->comment = comment ? strdup (comment) : NULL;
}

/* This returns the desc string. */
static inline char *
rcs_file_get_desc (struct rcs_file *obj)
{
	assert (obj);
	return obj->desc;
}

/* This sets the desc string. */
static inline void
rcs_file_set_desc (struct rcs_file *obj, char *desc)
{
	assert (obj);
	if (obj->desc) free (obj->desc);
	obj->desc = desc ? strdup (desc) : NULL;
}

/* This returns the generic file object, containing further information (mainly
 * the history itself). You can freely manipulate this object. */
static inline struct rev_inode *
rcs_file_get_inode (struct rcs_file *obj)
{
	assert (obj);
	return obj->inode;
}


#ifdef __cplusplus
}
#endif

#endif
