/* Copyright (c) 1993 by Sanjay Ghemawat */

#ifndef _ITEMH
#define _ITEMH

#include <stdio.h>
#include "Date.h"
#include "List.h"

#include "dateset.h"
#include "smallintset.h"
#include "unparsed.h"

class Lexer;

class Notice;
class Appointment;
class Calendar;
struct Item_OldDates;

/*
 * Item
 *
 * Abstract components.
 *
 * Text: string			associated text
 * Dates: DateSet		occurrence dates
 * RemindStart: int		No. of days before item when reminder begins.
 * ReadOnly: bool		Is Item read-only
 *
 * AsNotice: Notice*		Typecast to Notice if legal.  Null otherwise.
 * AsAppointment: Appointment*	Typecast to Appointment if legal ... 
 *
 */

class Item {
  public:
    Item(Calendar*);
    virtual ~Item();

    virtual int Read(Lexer*);
    virtual int Parse(Lexer*, char const* keyword, Item_OldDates&);
    virtual void Write(FILE*) const;

    /* Get/Set containing calendar */
    Calendar* GetCalendar() const;
    void SetCalendar(Calendar*);

    virtual Item* Clone() const = 0;

    const char* GetText() const;
    void SetText(const char*);

    DateSet* Dates() const;

    int GetRemindStart() const;
    void SetRemindStart(int);

    int ReadOnly() const;

    virtual Notice* AsNotice();
    virtual Appointment* AsAppointment();

    /* Mark deleted */
    int Deleted();
    void MarkDeleted();

    static const int defaultRemindStart;
  protected:
    char*     text;
    int       remindStart;	/* Start reminding early */
    Calendar* calendar;		/* Containing calendar */
    int       deleted;
    DateSet*  dates;

    void CopyTo(Item*) const;

    static const int textSize;
  private:
    /* Unrecognized entries */
    UnparsedItems extra;
};

/*
 * Notice
 *
 * An Item with just a length.
 * The length is just an indication of how big a window the notice must
 * be displayed in.  The length field can be interpreted just as the length
 * field for Appointments, and if notice->length == appt->length, then
 * the notice will be displayed the same size as the appt.
 */
class Notice : public Item {
  public:
    Notice(Calendar*);
    ~Notice();

    virtual int Parse(Lexer*, char const* keyword, struct Item_OldDates&);
    virtual void Write(FILE*) const;

    virtual Item* Clone() const;

    int GetLength() const;
    void SetLength(int);

    virtual Notice* AsNotice();
  protected:
    int length;
};

/*
 * Appointment
 *
 * An Item with a start time and a length.
 * Both start and length are in minutes.
 * Start is measured from midnight.
 */
class Appointment : public Item {
  public:
    Appointment(Calendar*);
    ~Appointment();

    virtual int Parse(Lexer*, char const* keyword, struct Item_OldDates&);
    virtual void Write(FILE*) const;

    virtual Item* Clone() const;

    int GetStart() const;
    int GetLength() const;
    int GetFinish() const;
    void SetStart(int);
    void SetLength(int);

    virtual Appointment* AsAppointment();
  protected:
    int start;
    int length;
};

/*
 * List of items.
 */
declareList(ItemList,Item*)

#endif /* _ITEMH */
