Contributor: SWAG SUPPORT TEAM        

UNIT CalUnit;
{ Object oriented calander unit }

INTERFACE

USES CRT,DOS;

TYPE
  Calendar = OBJECT
    ThisMonth, ThisYear : Word;
    CONSTRUCTOR Init(Month, Year: Integer);
    PROCEDURE        DrawCalendar;
    PROCEDURE        SetMonth(Month: Integer);
    PROCEDURE        SetYear(Year: Integer);
    FUNCTION        GetMonth: Integer;
    FUNCTION        GetYear: Integer;
    DESTRUCTOR        Done;
  END;

IMPLEMENTATION

CONSTRUCTOR Calendar.Init(Month, Year: Integer);
BEGIN
   SetYear(Year);
   SetMonth(Month);
   DrawCalendar;
END;

PROCEDURE Calendar.DrawCalendar;

VAR
  CurYear,CurMonth,CurDay,CurDow,
  ThisDay,ThisDOW    : Word;
  I,DayPos,NbrDays   : Byte;

CONST
  DOM: ARRAY[1..12] OF Byte =
       (31,28,31,30,31,30,31,31,30,31,30,31);
  MonthName: ARRAY[1..12] OF String[3] =
       ('Jan','Feb','Mar','Apr','May','Jun',
        'Jul','Aug','Sep','Oct','Nov','Dec');

BEGIN

  GetDate(CurYear,CurMonth,CurDay,CurDow);

  {Set to day 1 so we can use GetDate function}
  ThisDay := 1;

  SetDate(ThisYear,ThisMonth,ThisDay);

  {ThisDOW stands for This day of the week}

  GetDate(ThisYear,ThisMonth,ThisDay,ThisDOW);

  SetDate(CurYear,CurMonth,CurDay);

  WriteLn('           ',MonthName[ThisMonth],
          ' ',ThisYear);
  WriteLn;
  WriteLn('   S   M   T   W   R   F   S');

  NbrDays := DOM[ThisMonth];

  {Check for leap year, which occurs when the
   year is evenly divisible by 4 and not evenly
   divisable by 100 or if the year is evenly
   divisable by 400}

  IF ((ThisMonth = 2) AND
     ((ThisYear MOD 4 = 0) AND
      (ThisYear MOD 100 <> 0))
     OR (ThisYear MOD 400 = 0))
   THEN NbrDays := 29;

  FOR I:= 1 TO NbrDays DO
    BEGIN
      DayPos := ThisDOW * 4 + 2;  {Position day #}
      GotoXY(DayPos,WhereY);
      Inc(ThisDOW);
      Write(I:3);
      IF ThisDOW > 6 THEN
        BEGIN
          ThisDOW := 0;
          WriteLn
        END
    END;
    WriteLn
END;

PROCEDURE Calendar.SetMonth(Month: Integer);
BEGIN
   ThisMonth := Month;
   WHILE ThisMonth < 1 DO
   BEGIN
      Dec(ThisYear);
      Inc(ThisMonth, 12);
   END;
   WHILE ThisMonth > 12 DO
   BEGIN
      Inc(ThisYear);
      Dec(ThisMonth, 12);
   END;
END;

PROCEDURE Calendar.SetYear(Year: Integer);
BEGIN
   ThisYear := Year;
END;

FUNCTION Calendar.GetMonth: Integer;
BEGIN
   GetMonth := ThisMonth;
END;

FUNCTION Calendar.GetYear: Integer;
BEGIN
   GetYear := ThisYear;
END;

DESTRUCTOR Calendar.Done;
BEGIN
   {for dynamic object instances,
     the Done method still works even
     though it contains nothing except
     the destructor declaration              }
END;

END.

{ ---------------------------    TEST PROGRAM ---------------------}
PROGRAM CalTest;

USES DOS,CRT,CalUnit;

VAR
   MyCalendar: Calendar;
   TYear,TMonth,Tday,TDOW: Word;

BEGIN
   ClrScr;
   GetDate(TYear,TMonth,Tday,TDOW);
   WITH MyCalendar DO
   BEGIN
      WriteLn('    Current Month''s Calendar');
      WriteLn;
      Init(TMonth, TYear);
      WHILE (TMonth <> 0) DO
        BEGIN
          WriteLn;
          WriteLn('   Enter a Month and Year');
          WriteLn('(Separate values by a space)');
          WriteLn;
          WriteLn('      exm.      3 1990');
          WriteLn;
          Write         ('   or 0 0 to quit: ');
          ReadLn(TMonth, TYear);
          IF TMonth <> 0 THEN
             BEGIN
               ClrScr;
               SetYear(TYear);
               SetMonth(TMonth);
               DrawCalendar
             END
        END
   END;
   ClrScr
END.