#include <stdio.h>
#include <stdlib.h>

#include "../global.h"

#include "shared_util.h"  /* for cs_critical_error(), etc. */
#include "shared_lock.h"
#include "shared_cs_util.h"  /* for cs_critical_error(), etc. */

PERSON_NODE *person_head = 0;
ATTACHMENT_NODE *attachment_head = 0;

void
free_person_list (void)
{
  PERSON_NODE *ptr;

  while (person_head)
    {
      ptr = person_head;
      person_head = person_head->next;
      free (ptr);
    }
}


void
free_attachment_list (void)
{
  ATTACHMENT_NODE *ptr;

  while (attachment_head)
    {
      ptr = attachment_head;
      attachment_head = attachment_head->next;
      free (ptr);
    }
}



/** Caution: the following function does NOT add an attached website
*** to the attachment list!
**/

void
read_post_infofile (char *sender, char *info_fname, INFO * infofile_info,
                    CONFIG_STRUCT *conf)
{
  char infopath[MAX_PATH + 1];
  FILE *fp;
  ATTACHMENT_NODE *aptr = 0;
  PERSON_NODE *pptr = 0;
  int i;
  PERSON person_buffer;
  ATTACHMENT website_junker;
  
  snprintf (infopath, MAX_PATH + 1, "%s%s/%s/%s/%s", conf->course_path, PEOPLE_DIR,
	    sender, MAIL_DIR, info_fname);

  fp = fopen (infopath, "r");
  if (!fp)
    cs_critical_error (ERR_ERROR_OPENING_INFO, "");
    
  get_shared_lock(fileno(fp),1);   /* shared_lock.c */   

  if (fread (infofile_info, sizeof (INFO), 1, fp) != 1)
    cs_critical_error (ERR_ERROR_READING_INFO, "");


  /* process attachments */

  if(infofile_info->no_attachments == - 1)  /* then a website was attached  - read it and ignore it */
    {
      if (fread (&website_junker, sizeof (ATTACHMENT), 1, fp) != 1)
	cs_critical_error (ERR_ERROR_READING_ATTACHMENT, "");
    }
  else  	
   {
    for (i = 1; i <= infofile_info->no_attachments; i++)
      {
       if (!attachment_head)
	{
	  attachment_head =
	    (ATTACHMENT_NODE *) malloc (sizeof (ATTACHMENT_NODE));
	  if (!attachment_head)
	    cs_critical_error (ERR_MALLOC_FAILED, "");
	  aptr = attachment_head;
	}
       else
	{
	  aptr->next = (ATTACHMENT_NODE *) malloc (sizeof (ATTACHMENT_NODE));
	  if (!aptr->next)
	    cs_critical_error (ERR_MALLOC_FAILED, "");
	  aptr = aptr->next;
	}

      if (fread (&aptr->data, sizeof (ATTACHMENT), 1, fp) != 1)
	cs_critical_error (ERR_ERROR_READING_ATTACHMENT, "");
      aptr->next = 0;
    }
  }

  /* process list of people msg was sent to  */
  while (fread (&person_buffer, sizeof (PERSON), 1, fp) == 1)
    {
      if (!person_head)
	{
	  person_head = (PERSON_NODE *) malloc (sizeof (PERSON_NODE));
	  if (!person_head)
	    cs_critical_error (ERR_MALLOC_FAILED, "");
	  pptr = person_head;
	}
      else
	{
	  pptr->next = (PERSON_NODE *) malloc (sizeof (PERSON_NODE));
	  if (!pptr->next)
	    cs_critical_error (ERR_MALLOC_FAILED, "");
	  pptr = pptr->next;
	}

      pptr->data = person_buffer;
      pptr->next = 0;
    }
  release_lock(fileno(fp));   /* shared_lock.c */
  fclose (fp);
}



/*** The next function is used only read NEWS_INFO and
**** build a linked list of attachments.  It does NOT bother
**** building a list of people who have read the message.
***/

void
read_news_infofile (const char *sender, const char *info_fname,
		    NEWS_INFO * infofile_info, int grp, CONFIG_STRUCT *conf)
{
  char infopath[MAX_PATH + 1];
  FILE *fp;
  int fd;
  ATTACHMENT_NODE *aptr = 0;
  int i;
  int attachments;

  snprintf (infopath, MAX_PATH + 1, "%s%s/%s/%s/%s", 
            conf->course_path,
            PEOPLE_DIR,
	    sender,
	    grp == STUDENT_LOUNGE ? LOUNGE_DIR : 
	    grp == CLASS_DISCUSSION ? DISCUSSION_DIR : 
	    grp == ANONYMOUS_DISCUSSION ? ANONYMOUS_DIR : 
	    grp == TEAM_DISCUSSION ? TEAM_DIR : 
	    grp == TEAM_TEACH ? TEAM_TEACH_DIR : 
	    grp == ASSIGNMENTS ? ASSIGNMENTS_DIR : 
	    grp == SELFTEST ? SELFTEST_DIR : 
	    grp == LECTURES ? LECTURES_DIR : 
	    grp == SURVEYS ? SURVEYS_DIR:
	    grp == PODCASTS ? PODCASTS_DIR:
	    HANDOUTS_DIR,
	    info_fname);

  fp = fopen (infopath, "r");
  if (!fp)
    cs_critical_error (ERR_ERROR_OPENING_INFO, infopath);

  /** added file locking 11/2003 **/
  fd = fileno(fp);
  get_shared_lock(fd,1);     /* shared_lock.c */  
  
  if (fread (infofile_info, sizeof (NEWS_INFO), 1, fp) != 1)
    cs_critical_error (ERR_ERROR_READING_INFO, infopath);


  /** take the absolute value of attachments for the next
  *** loop, since a value of -1 is used to indicate an
  *** attached website - added 11/2003
  **/
  attachments = abs(infofile_info->attachments);
  /* process attachments */
  for (i = 1; i <= attachments; i++)
    {
      if (!attachment_head)
	{
	  attachment_head =
	    (ATTACHMENT_NODE *) malloc (sizeof (ATTACHMENT_NODE));
	  if (!attachment_head)
	    cs_critical_error (ERR_MALLOC_FAILED, "");
	  aptr = attachment_head;
	}
      else
	{
	  aptr->next = (ATTACHMENT_NODE *) malloc (sizeof (ATTACHMENT_NODE));
	  if (!aptr->next)
	    cs_critical_error (ERR_MALLOC_FAILED, "");
	  aptr = aptr->next;
	}

      if (fread (&aptr->data, sizeof (ATTACHMENT), 1, fp) != 1)
	cs_critical_error (ERR_ERROR_READING_ATTACHMENT, "");
      aptr->next = 0;
    }


  release_lock(fd);  
  fclose (fp);
}



int
get_clipboard_info (CLIPBOARD_INFO * clipboard_info, char *clipboard_path,
                     SESSION *user)
{
  char fullpath[MAX_PATH + 1];
  ATTACHMENT_NODE *aptr = 0;
  int i;
  FILE *fp;

  snprintf (clipboard_path, MAX_PATH + 1, "%s%s/", CLIPBOARD_PATH, user->id);
  snprintf (fullpath, MAX_PATH + 1, "%s%s", clipboard_path,
	    CLIPBOARD_INF_FNAME);
  fp = fopen (fullpath, "r");
  if (!fp)
    return 1;
  if (fread (clipboard_info, sizeof (CLIPBOARD_INFO), 1, fp) != 1)
    {
      fclose (fp);
      return 1;
    }

  /* now read attachment records */

  if (clipboard_info->attachments == -1)	/* -1 flags a website attached */
    clipboard_info->attachments = 1;	/* change -1 to 1 for the next 'for' loop */

  for (i = 1; i <= clipboard_info->attachments; i++)
    {
      if (!attachment_head)
	{
	  attachment_head =
	    (ATTACHMENT_NODE *) malloc (sizeof (ATTACHMENT_NODE));
	  if (!attachment_head)
	    cs_critical_error (ERR_MALLOC_FAILED, "");
	  aptr = attachment_head;
	}
      else
	{
	  aptr->next = (ATTACHMENT_NODE *) malloc (sizeof (ATTACHMENT_NODE));
	  if (!aptr->next)
	    cs_critical_error (ERR_MALLOC_FAILED, "");
	  aptr = aptr->next;
	}

      if (fread (&aptr->data, sizeof (ATTACHMENT), 1, fp) != 1)
	cs_critical_error (ERR_FREAD_FAILED, "");
      aptr->next = 0;
    }				/* for .. */



  fclose (fp);
  return 0;
}



