module DVD {
  typedef string datec;
  interface MEMBERSHIP { // Methods to manipulate DVD Store MEMBERS
    exception NOSUCHMEMBER {};
    typedef long memberidt;
    typedef sequence<memberidt> memberidList;
    struct storemembers  {
      memberidt memberid;                /* internal id [1..] */
      string memberno;   /* the number the member knows */
      string title;        /* Mr Mrs Ms Dr Sir */
      string fname;               /* first name */
      string lname;               /* last name */
      string houseflatref;        /* i.e. 5, or 'The birches' etc. */
      string address1;         /* Address line 1 */
      string address2;         /* Address line 2 */
      string town;             /* Town/City */
      string state;              /* needed in US only */
      string phone;            /* +44(0)123 456789 */
      string zipcode;          /* LE1 1AA or whatever */
    };
    void set(in storemembers recordtoupdate);
    void get(in memberidt memberid,
             out storemembers recordtocomplete)
      raises (NOSUCHMEMBER);
    void create (in storemembers recordtoadd, 
                 out memberidt memberid);
    void delete (in memberidt memberid) 
      raises (NOSUCHMEMBER);
    void search (in string lname, 
                 out memberidList resultids);
    void idfromnumber (in string memberno, 
                       out memberidt memberid)
      raises (NOSUCHMEMBER);
  }; 
 
  interface TITLING { // Methods to manipulate DVD Store TITLES
    exception NOSUCHTITLE {};
    exception NOSUCHGENRE {};     
    typedef string classif;
    typedef sequence<classif> classList;
    typedef string genres ;
    typedef sequence<genres> genreList;
    typedef long titlet;
    typedef sequence<titlet> titleList;
    struct dvdtitles {
      titlet titleid;             /* internal ID [1..] */
      string titletext;   /* 'The silence of the lambs' */
      string asin;            /* 10 digit reference number */
      string director;        /* restricted to a single name */
      genres genre;                  /* 'Horror', 'comedy', etc. API for
                                        standard list later */
      classif classification;
      string actor1;          /*  'Jeremy Irons' */
      string actor2;          /* 'Ingmar Bergman' */
      datec releasedate;             /* YYYYMMDD plus the null */
      string rentalcost;      /* cost of a day rental for this title 
                                 $$$.cc */
      string image;          /* Image Reference */
    };
  
    void set (in dvdtitles recordtoupdate);
    void get (in titlet titleid, 
              out dvdtitles recordtocomplete) 
      raises (NOSUCHTITLE);
    void create (in dvdtitles recordtoadd, 
                 out titlet titleid);
    void delete (in titlet titleid) 
      raises (NOSUCHTITLE);
    void search (in string title, in string name, 
                 out titleList resultids);
  };
  interface DISKS { // Methods to manipulate DVD DISKS
    exception NOSUCHDISK {};
    typedef long dvdidt;
    typedef sequence<dvdidt> dvdList;
    struct dvddisks {
      dvdidt diskid;   /* internal ID [1..] (not related to title_id) */
      TITLING::titlet titleid;  
    } ;
    void    set (in dvddisks recordtoupdate);
    void    get (in dvdidt diskid, 
                 out dvddisks recordtocomplete)
      raises (NOSUCHDISK);
    void    create (in dvddisks recordtoadd, 
                    out dvdidt diskid);
    void    delete (in dvdidt diskid) 
      raises (NOSUCHDISK);
    void    search (in TITLING::titlet titleid, 
                    out dvdList resultids);
  };
  interface RENTAL { // Methods for processing disk RENTALs and returns
    struct rentinfo {   // Structure used by server...
	DISKS::dvdidt diskid;
	MEMBERSHIP::memberidt memberid;
	datec drented;
    };
    exception FORBIDDENRATING {}; // Kids trying to rent porn
    void set (in DISKS::dvdidt diskid, in rentinfo info)
	raises (DISKS::NOSUCHDISK, MEMBERSHIP::NOSUCHMEMBER);
    void get (in DISKS::dvdidt diskid, out rentinfo info)
	raises (DISKS::NOSUCHDISK);
    void renttitle (in MEMBERSHIP::memberidt memberid, 
                    in TITLING::titlet titleid,
                    out DISKS::dvdidt diskid) 
      raises (DISKS::NOSUCHDISK, MEMBERSHIP::NOSUCHMEMBER, 
              TITLING::NOSUCHTITLE, FORBIDDENRATING);
    void rentdiskinfo (in DISKS::dvdidt diskid, 
                       out MEMBERSHIP::memberidt memberid, 
                       out datec daterented)
      raises (DISKS::NOSUCHDISK);
    void diskreturn (in DISKS::dvdidt diskid, 
                     in datec returndate, 
                     out MEMBERSHIP::memberidt memberid)
      raises (DISKS::NOSUCHDISK);
    long titleavailable (in TITLING::titlet titleid, in datec date)
      raises (TITLING::NOSUCHTITLE);
    void overduedisks (in datec fromdate, in datec todate,
                       out DISKS::dvdList latedisks);
  };
  interface RESERVATIONS { // Methods for managing reserving TITLES
    exception NOSUCHRESERVATION {}; // Kids trying to rent porn
    struct reservation {  // Private data structure
      MEMBERSHIP::memberidt memberid;
      TITLING::titlet titleid;
      datec dwanted;
    };
    void set (in MEMBERSHIP::memberidt memberid, in reservation res)
	raises (MEMBERSHIP::NOSUCHMEMBER, TITLING::NOSUCHTITLE);
    void get (in MEMBERSHIP::memberidt memberid, out reservation res)
	raises (MEMBERSHIP::NOSUCHMEMBER);
    void countavailable (in TITLING::titlet titleid, in datec wanted,
                         out long count);
    void reservetitle (in datec needed, in TITLING::titlet titleid,
                       in MEMBERSHIP::memberidt memberid)
      raises (TITLING::NOSUCHTITLE, MEMBERSHIP::NOSUCHMEMBER, 
              RENTAL::FORBIDDENRATING);
    void cancelreservation (in MEMBERSHIP::memberidt memberid)
      raises (MEMBERSHIP::NOSUCHMEMBER);
    void queryreservationbymember (in MEMBERSHIP::memberidt memberid, 
                                      out TITLING::titlet titleid)
      raises (MEMBERSHIP::NOSUCHMEMBER);
    void queryreservationbytitle (in TITLING::titlet titleid, 
                                     in datec date,
                                  out MEMBERSHIP::memberidList memberids)
      raises (TITLING::NOSUCHTITLE);
  };
  interface UTILITIES { // Other methods that don't fit well elsewhere
    void getgenres(out TITLING::genreList genrelist);
    void getclassifications (out TITLING::classList classlist);
    void errortext(in long errnumber, out string messagetoshow);
    void today(out datec date); // This could be managed via the Time Service...
  };
  interface FACTORY {
    MEMBERSHIP MEMBERSHIPFactory ();
    TITLING TITLINGFactory ();
    DISKS DISKSFactory ();
    RENTAL RENTALFactory ();
    RESERVATIONS RESERVATIONSFactory ();
    UTILITIES UTILITIESFactory ();
 };
};
