/* Copyright (c) 1993 by Sanjay Ghemawat */
/*
 * Routines to speed up dateeditor.
 */
#include <stdio.h>
#include <tcl.h>

#include "Date.h"
#include "Month.h"
#include "WeekDay.h"

#include "arrays.h"
#include "commands.h"

#include "cal_tcl.h"
#include "calendar.h"
#include "calfile.h"
#include "item.h"
#include "misc_tcl.h"

/*
 * requires	argc/argv === <cmd> <canvas> <date>
 *		Canvas has 42 text items with tags ranging from
 *		=1 to =42.  The text items are arranged in a grid
 *		7 wide by 6 high.  The numbers increase from left to
 *		right and then top to bottom.  Therefore, the top-left
 *		item has tag =1, rop-right item has tag =7, and the
 *		bottom-right item tag =42.  Each one of these 42 items
 *		also has the tag "Day".
 *
 * effects	Configures items so that their text contents correspond
 *		to the day of the month that should be displayed at that
 *		item (under the assumption that the month  named by <date>
 *		is being displayed).
 */
int Cmd_MonthDays(ClientData, Tcl_Interp* tcl, int argc, char* argv[]) {
    if (argc != 3) {
	TCL_Error(tcl, "illegal number of arguments");
    }

    char* canvas = argv[1];

    int dateDays;
    if (Tcl_GetInt(tcl, argv[2], &dateDays) != TCL_OK) {
	return TCL_ERROR;
    }
    Date date(dateDays);
    Date first(1, date.GetMonth(), date.GetYear());
    int start = first.GetWDay().Index();
    int finish = start + first.GetMonth().Size(first.GetYear()) - 1;

    if (Tcl_VarEval(tcl, canvas, " itemconfig Day -text {}", NULL) != TCL_OK) {
	return TCL_ERROR;
    }

    for (int i = start; i <= finish; i++) {
	char str[100];
	sprintf(str, "=%d -text {%4d}", i, i - start + 1);
	if (Tcl_VarEval(tcl, canvas, " itemconfig ", str, NULL) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    TCL_Return(tcl, "");
}

/*
 * requires	argc/argv === <cmd> <canvas> <date>
 *		Canvas has 42 text items with tags ranging from
 *		=1 to =42.  The text items are arranged in a grid
 *		7 wide by 6 high.  The numbers increase from left to
 *		right and then top to bottom.  Therefore, the top-left
 *		item has tag =1, rop-right item has tag =7, and the
 *		bottom-right item tag =42.  Each one of these 42 items
 *		also has the tag "Day".
 *
 * effects	Configures items so that they have tag "interest" iff
 *		the corresponding date has interesting items.  Any
 *		items which initially had interest, but no longer,
 *		are tagged with "oldinterest".
 */
int Cmd_InterestTags(ClientData, Tcl_Interp* tcl, int argc, char* argv[]) {
    if (argc != 3) {
	TCL_Error(tcl, "illegal number of arguments");
    }

    char* canvas = argv[1];

    int dateDays;
    if (Tcl_GetInt(tcl, argv[2], &dateDays) != TCL_OK) {
	return TCL_ERROR;
    }
    Date date(dateDays);
    Date first(1, date.GetMonth(), date.GetYear());
    int size = first.GetMonth().Size(first.GetYear());
    Date last = first + size - 1;

    /* Number of initial blank entries in display */
    int blanks = first.GetWDay().Index() - 1;

    int interest[43];
    for (int i = 1; i <= 42; i++) {
	interest[i] = 0;
    }

    Calendar_Tcl* cal = calendar_instance;
    for (i = 0; i <= cal->includes->size(); i++) {
	Calendar* calendar;
	if (i >= cal->includes->size()) {
	    calendar = cal->main->GetCalendar();
	}
	else {
	    calendar = cal->includes->slot(i)->GetCalendar();
	}

	for (int j = 0; j < calendar->Size(); j++) {
	    Item* item = calendar->Get(j);
	    Date date = first-1;
	    while (item->Dates()->next(date, date) && (date <= last)) {
		interest[(date - first) + blanks + 1] = 1;
	    }
	}
    }

    /* Rename interest to oldinterest */
    if (Tcl_VarEval(tcl, canvas, " addtag oldinterest withtag interest", NULL)
	!= TCL_OK) {
	return TCL_ERROR;
    }
    if (Tcl_VarEval(tcl, canvas, " dtag interest interest", NULL) != TCL_OK) {
	return TCL_ERROR;
    }

    /* Add interest to everything that we are still interested in */
    for (i = 1; i <= 42; i++) {
	if (interest[i]) {
	    char str[100];
	    sprintf(str, "=%d", i);
	    if (Tcl_VarEval(tcl,
			    canvas,
			    " addtag interest withtag ",
			    str,
			    NULL) != TCL_OK) {
		return TCL_ERROR;
	    }
	}
    }

    /* Remove oldinterest for items with interest */
    if (Tcl_VarEval(tcl, canvas, " dtag interest oldinterest", NULL)
	!= TCL_OK) {
	return TCL_ERROR;
    }

    TCL_Return(tcl, "");
}
