--- openwebmail-cal.pl	Tue Aug 26 08:20:18 2003
+++ openwebmail-cal.pl	Mon Sep  1 12:37:14 2003
@@ -164,7 +164,10 @@
    update_item($index, $string,
                $starthour, $startmin, $startampm,
                $endhour, $endmin, $endampm,
+               $dayfreq,
+               $thisandnextndays, $ndays, $monthfreq, $everyyear,
                $link, $email, $eventcolor);
+
    if (defined(param('callist'))) {
       listview($year);
    } else {
@@ -618,6 +621,7 @@
    $year=2037 if ($year>2037); $year=1970 if ($year<1970);
    $month=12 if ($month>12); $month=1 if ($month<1);
    $day=$days_in_month[$month] if ($day>$days_in_month[$month]); $day=1 if ($day<1);
+   if ($day != $main::day) { $main::day = $day }; # affect the global $day var or CGI.pm gets confused
 
    my ($html, $temphtml);
    $html = applystyle(readtemplate("weekview.template"));
@@ -878,6 +882,7 @@
    $year=2037 if ($year>2037); $year=1970 if ($year<1970);
    $month=12 if ($month>12); $month=1 if ($month<1);
    $day=$days_in_month[$month] if ($day>$days_in_month[$month]); $day=1 if ($day<1);
+   if ($day != $main::day) { $main::day = $day }; # affect the global $day var or CGI.pm gets confused
 
    my ($html, $temphtml);
    $html = applystyle(readtemplate("dayview.template"));
@@ -1222,22 +1227,103 @@
             } else {
                # event in this cell has been drawed, nothing to do
             }
-            
+
          } else {
             # no event in this cell
             $temphtml .= qq|<td bgcolor=$bgcolor[$colornum]>&nbsp;</td>|;
          }
-      }      
+      }
       $temphtml .= qq|</tr>|;
    }
 
    $temphtml .= qq|</table></td></tr>\n|;
 
-
    $html =~ s/\@\@\@CALENDARITEMS\@\@\@/$temphtml/;
 
-   $temphtml = startform(-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl",
-                         -name=>'AddItemForm');
+   #--------------------------
+   # Add Calander Form
+   #--------------------------
+   my %jslabels = ('thisdayonly'=>$lang_text{'thisday_only'},
+                   'thewdayofthismonth'=>$lang_text{'the_wday_of_thismonth'},
+                   'everywdaythismonth'=>$lang_text{'every_wday_thismonth'},
+                   'everyoddmonththisyear'=>$lang_text{'every_oddmonth_thisyear'},
+                   'everyevenmonththisyear'=>$lang_text{'every_evenmonth_thisyear'},
+                   'daydoesnotexist'=>$lang_text{'day_does_not_exist'});
+
+   # replace label variables with javascript code
+   $jslabels{thewdayofthismonth} =~ s/\@\@\@ORDER\@\@\@/"+wOrder[(weekOrder-1)]+"/;
+   $jslabels{thewdayofthismonth} =~ s/\@\@\@WDAY\@\@\@/"+wDay[(checkDate.getDay())]+"/;
+   $jslabels{everywdaythismonth} =~ s/\@\@\@WDAY\@\@\@/"+wDay[(checkDate.getDay())]+"/;
+   $jslabels{daydoesnotexist} =~ s/\@\@\@MONTH_STR\@\@\@/"+document.AddItemForm.month.options[document.AddItemForm.month.selectedIndex].text+"/;
+   $jslabels{daydoesnotexist} =~ s/\@\@\@DAYS_IN_MONTH\@\@\@/"+(formDay-checkDate.getDate())+"/g;
+   $jslabels{daydoesnotexist} =~ s/\@\@\@YEAR\@\@\@/"+formYear+"/;
+
+   $temphtml = qq|
+      <script type="text/javascript" language="javascript">
+      <!--
+      function valiDate() {
+         var formYear = document.AddItemForm.year.options[document.AddItemForm.year.selectedIndex].value;
+         var formMonth = document.AddItemForm.month.options[document.AddItemForm.month.selectedIndex].value;
+         var formDay = document.AddItemForm.day.options[document.AddItemForm.day.selectedIndex].value;
+         var dayfreqSelection = document.AddItemForm.dayfreq.selectedIndex;
+         var monthfreqSelection = document.AddItemForm.monthfreq.selectedIndex;
+         var checkDate = new Date(formYear,formMonth-1,formDay);
+
+         wDay = new Array('$lang_wday{0}','$lang_wday{1}','$lang_wday{2}','$lang_wday{3}','$lang_wday{4}','$lang_wday{5}','$lang_wday{6}');
+         wOrder = new Array('$lang_order{1}','$lang_order{2}','$lang_order{3}','$lang_order{4}','$lang_order{5}');
+
+         if (formMonth < checkDate.getMonth()+1) {
+           alert("$jslabels{daydoesnotexist}");
+           document.AddItemForm.day.selectedIndex = formDay-checkDate.getDate()-1;
+           // reset our vars
+           formDay = formDay-checkDate.getDate();
+           checkDate = new Date(formYear,formMonth-1,formDay);
+         }
+
+         var weekOrder = parseInt((parseInt(formDay)+6)/7);
+
+         // update the day recurrance
+         if (weekOrder<=4) {
+            if (! document.AddItemForm.dayfreq[2]) {  // coming from 2 choice menu
+               if (dayfreqSelection==1) {
+                  dayfreqSelection++;
+               }
+            }
+            document.AddItemForm.dayfreq.options.length =0; // clear popup
+            document.AddItemForm.dayfreq[0] = new Option("$jslabels{thisdayonly}","thisdayonly");
+            document.AddItemForm.dayfreq[1] = new Option("$jslabels{thewdayofthismonth}","thewdayofthismonth");
+            document.AddItemForm.dayfreq[2] = new Option("$jslabels{everywdaythismonth}","everywdaythismonth");
+         } else {
+            if (document.AddItemForm.dayfreq[2]) {  // coming from 3 choice menu
+               dayfreqSelection--;
+               if (dayfreqSelection < 0) {
+                  dayfreqSelection = 0;
+               }
+            }
+            document.AddItemForm.dayfreq.options.length =0; // clear popup
+            document.AddItemForm.dayfreq[0] = new Option("$jslabels{thisdayonly}","thisdayonly");
+            document.AddItemForm.dayfreq[1] = new Option("$jslabels{everywdaythismonth}","everywdaythismonth");
+         }
+
+         // update the month recurrance
+         if (formMonth%2) {
+            document.AddItemForm.monthfreq[1] = new Option("$jslabels{everyoddmonththisyear}","everyoddmonththisyear");
+         } else {
+            document.AddItemForm.monthfreq[1] = new Option("$jslabels{everyevenmonththisyear}","everyevenmonththisyear");
+         }
+
+         document.AddItemForm.dayfreq.selectedIndex = dayfreqSelection;
+         document.AddItemForm.monthfreq.selectedIndex = monthfreqSelection;
+      }
+
+      function nothing() { ; } // for the colorpicker to work properly
+      // -->
+      </script>
+   |;
+
+   $temphtml .= startform(-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl",
+                          -name=>'AddItemForm',
+                          -override=>'1');
    $temphtml .= hidden(-name=>'sessionid',
                        -value=>$thissession,
                        -override=>'1');
@@ -1250,18 +1336,34 @@
    $temphtml .= hidden(-name=>'action',
                        -value=>'caladd',
                        -override=>'1');
-   $temphtml .= hidden(-name=>'year',
-                       -value=>$year,
-                       -override=>'1');
-   $temphtml .= hidden(-name=>'month',
-                       -value=>$month,
-                       -override=>'1');
-   $temphtml .= hidden(-name=>'day',
-                       -value=>$day,
-                       -override=>'1');
    $html =~ s/\@\@\@STARTADDITEMFORM\@\@\@/$temphtml/;
 
-   $temphtml = textfield(-name=>'string',
+
+   $temphtml = popup_menu(-name=>'month',
+                          -values=>[1..12],
+                          -default=>$month,
+                          -onChange=>"valiDate()",
+                          -labels=>\%lang_month,
+                          -override=>1);
+
+   $temphtml .= popup_menu(-name=>'day',
+                           -values=>[1..31],
+                           -default=>$day,
+                           -onChange=>"valiDate()",
+                           -override=>'1');
+
+   $temphtml .= popup_menu(-name=>'year',
+                           -values=>[1970..2037],
+                           -onChange=>"valiDate()",
+                           -default=>$year,
+                           -override=>'1');
+
+   # ideally there would be a portion of the add form
+   # template reserved for the day/month/year. But
+   # since there is not...
+   $temphtml .= qq|<br>|;
+
+   $temphtml .= textfield(-name=>'string',
                          -default=>'',
                          -size=>'32',
                          -accesskey=>'I',
@@ -1283,18 +1385,21 @@
    $temphtml2 = popup_menu(-name=>'starthour',
                            -values=>\@hourlist,
                            -default=>'none',
-                           -labels=>\%numlabels);
+                           -labels=>\%numlabels,
+                           -override=>'1');
    $temphtml2 .= " <B>:</B> ";
    $temphtml2 .= popup_menu(-name=>'startmin',
                             -values=>[0,5,10,15,20,25,30,35,40,45,50,55],
                             -default=>0,
-                            -labels=>\%numlabels);
+                            -labels=>\%numlabels,
+                            -override=>'1');
    $temphtml =~ s/\@\@\@HOURMIN\@\@\@/$temphtml2/;
    if ($prefs{'hourformat'}==12) {
       $temphtml2 = popup_menu(-name=>'startampm',
                               -values=>['am','pm'],
                               -default=>'am',
-                              -labels=>{ am=>$lang_text{'am'}, pm=>$lang_text{'pm'} } );
+                              -labels=>{ am=>$lang_text{'am'}, pm=>$lang_text{'pm'} },
+                              -override=>'1' );
    } else {
       $temphtml2 ="";
    }
@@ -1305,26 +1410,31 @@
    $temphtml2 = popup_menu(-name=>'endhour',
                            -values=>\@hourlist,
                            -default=>'none',
-                           -labels=>\%numlabels);
+                           -labels=>\%numlabels,
+                           -override=>'1');
    $temphtml2 .= " <B>:</B> ";
    $temphtml2 .= popup_menu(-name=>'endmin',
                             -values=>[0,5,10,15,20,25,30,35,40,45,50,55],
                             -default=>0,
-                            -labels=>\%numlabels);
+                            -labels=>\%numlabels,
+                            -override=>'1');
    $temphtml =~ s/\@\@\@HOURMIN\@\@\@/$temphtml2/;
    if ($prefs{'hourformat'}==12) {
       $temphtml2 = popup_menu(-name=>'endampm',
                               -values=>['am','pm'],
                               -default=>'am',
-                              -labels=>{ am=>$lang_text{'am'}, pm=>$lang_text{'pm'} } );
+                              -labels=>{ am=>$lang_text{'am'}, pm=>$lang_text{'pm'} },
+                              -override=>'1' );
    } else {
       $temphtml2 ="";
    }
    $temphtml =~ s/\@\@\@AMPM\@\@\@/$temphtml2/;
    $html =~ s/\@\@\@ENDHOURMINMENU\@\@\@/$temphtml/;
 
-   my %wdaynum = qw (Sun 0 Mon 1 Tue 2 Wed 3 Thu 4 Fri 5 Sat 6);
+
+   # recurrance event section
    my $weekorder=int(($day+6)/7);
+   my %wdaynum = qw (Sun 0 Mon 1 Tue 2 Wed 3 Thu 4 Fri 5 Sat 6);
    my %dayfreqlabels = ('thisdayonly'       =>$lang_text{'thisday_only'},
                         'thewdayofthismonth'=>$lang_text{'the_wday_of_thismonth'},
                         'everywdaythismonth'=>$lang_text{'every_wday_thismonth'});
@@ -1333,23 +1443,25 @@
    $dayfreqlabels{'everywdaythismonth'}=~s/\@\@\@WDAY\@\@\@/$lang_wday{$wdaynum{$dow}}/;
 
    if ($weekorder<=4) {
-      $temphtml .= hidden(-name=>'weekorder',
-                          -value=>$weekorder,
-                          -override=>'1');
       $temphtml = popup_menu(-name=>'dayfreq',
                              -values=>['thisdayonly', 'thewdayofthismonth', 'everywdaythismonth'],
-                             -labels=>\%dayfreqlabels);
+                             -default=>'thisdayonly',
+                             -labels=>\%dayfreqlabels,
+                             -override=>'1');
    } else {
       $temphtml = popup_menu(-name=>'dayfreq',
                              -values=>['thisdayonly', 'everywdaythismonth'],
-                             -labels=>\%dayfreqlabels);
+                             -default=>'thisdayonly',
+                             -labels=>\%dayfreqlabels,
+                             -override=>'1');
    }
    $html =~ s/\@\@\@FREQMENU\@\@\@/$temphtml/;
 
    $temphtml = checkbox(-name=>'thisandnextndays',
                         -value=>'1',
                         -checked=>0,
-                        -label=>'');
+                        -label=>'',
+                        -override=>'1');
    $html =~ s/\@\@\@THISANDNEXTNDAYSCHECKBOX\@\@\@/$temphtml/g;
 
    $temphtml = textfield(-name=>'ndays',
@@ -1371,13 +1483,16 @@
    push(@monthfreq, 'everymonththisyear');
    $temphtml = popup_menu(-name=>'monthfreq',
                           -values=>\@monthfreq,
-                          -labels=>\%monthfreqlabels);
+                          -default=>'thismonthonly',
+                          -labels=>\%monthfreqlabels,
+                          -override=>'1');
    $html =~ s/\@\@\@MONTHFREQMENU\@\@\@/$temphtml/g;
 
    $temphtml = checkbox(-name=>'everyyear',
                         -value=>'1',
                         -checked=>0,
-                        -label=>'');
+                        -label=>'',
+                        -override=>'1');
    $html =~ s/\@\@\@EVERYYEARCHECKBOX\@\@\@/$temphtml/g;
 
    $temphtml = textfield(-name=>'link',
@@ -1407,13 +1522,15 @@
                           -override=>'1');
    $html =~ s/\@\@\@EVENTCOLORMENU\@\@\@/$temphtml/;
 
-   $temphtml = qq|<table height=25>|;
+   $temphtml = qq|<table align="center" height="25">|;
+   my $eventcolornum = 1;
    foreach (sort keys %eventcolors) {
       $temphtml .= qq|<td width=14 align=center bgcolor="#$eventcolors{$_}">|.
-                   qq|<a onclick="JavaScript:document.AddItemForm.eventcolor.value='$_'">$_</a></td>\n|;
+                   qq|<a href="javascript:nothing()" onClick='javascript:document.AddItemForm.eventcolor.selectedIndex="$eventcolornum"'>$_</a></td>\n|;
+      $eventcolornum++;
    }
    $temphtml .= qq|<td width=14 align=center">|.
-                qq|<a onclick="JavaScript:document.AddItemForm.eventcolor.value='none'">--</a></td>\n|;
+                qq|<a href="javascript:nothing()" onClick='javascript:document.AddItemForm.eventcolor.selectedIndex="0"'>--</a></td>\n|;
    $temphtml .= qq|</tr></table>|;
    $html =~ s/\@\@\@COLORTABLE\@\@\@/$temphtml/;
 
@@ -1828,11 +1945,87 @@
       writehistory("edit calitem error - item missing, index=$index");
    }
 
-   $temphtml = formatted_date($year, $month, $day);
-   $html =~ s/\@\@\@DATE\@\@\@/$temphtml/;
+   my %jslabels = ('thisdayonly'=>$lang_text{'thisday_only'},
+                   'thewdayofthismonth'=>$lang_text{'the_wday_of_thismonth'},
+                   'everywdaythismonth'=>$lang_text{'every_wday_thismonth'},
+                   'everyoddmonththisyear'=>$lang_text{'every_oddmonth_thisyear'},
+                   'everyevenmonththisyear'=>$lang_text{'every_evenmonth_thisyear'},
+                   'daydoesnotexist'=>$lang_text{'day_does_not_exist'});
+
+   # replace label variables with javascript code
+   $jslabels{thewdayofthismonth} =~ s/\@\@\@ORDER\@\@\@/"+wOrder[(weekOrder-1)]+"/;
+   $jslabels{thewdayofthismonth} =~ s/\@\@\@WDAY\@\@\@/"+wDay[(checkDate.getDay())]+"/;
+   $jslabels{everywdaythismonth} =~ s/\@\@\@WDAY\@\@\@/"+wDay[(checkDate.getDay())]+"/;
+   $jslabels{daydoesnotexist} =~ s/\@\@\@MONTH_STR\@\@\@/"+document.editcalendar.month.options[document.editcalendar.month.selectedIndex].text+"/;
+   $jslabels{daydoesnotexist} =~ s/\@\@\@DAYS_IN_MONTH\@\@\@/"+(formDay-checkDate.getDate())+"/g;
+   $jslabels{daydoesnotexist} =~ s/\@\@\@YEAR\@\@\@/"+formYear+"/;
+
+   $temphtml = qq|
+      <script type="text/javascript" language="javascript">
+      <!--
+      function valiDate() {
+         var formYear = document.editcalendar.year.options[document.editcalendar.year.selectedIndex].value;
+         var formMonth = document.editcalendar.month.options[document.editcalendar.month.selectedIndex].value;
+         var formDay = document.editcalendar.day.options[document.editcalendar.day.selectedIndex].value;
+         var dayfreqSelection = document.editcalendar.dayfreq.selectedIndex;
+         var monthfreqSelection = document.editcalendar.monthfreq.selectedIndex;
+         var checkDate = new Date(formYear,formMonth-1,formDay);
+
+         wDay = new Array('$lang_wday{0}','$lang_wday{1}','$lang_wday{2}','$lang_wday{3}','$lang_wday{4}','$lang_wday{5}','$lang_wday{6}');
+         wOrder = new Array('$lang_order{1}','$lang_order{2}','$lang_order{3}','$lang_order{4}','$lang_order{5}');
+
+         if (formMonth < checkDate.getMonth()+1) {
+           alert("$jslabels{daydoesnotexist}");
+           document.editcalendar.day.selectedIndex = formDay-checkDate.getDate()-1;
+           // reset our vars
+           formDay = formDay-checkDate.getDate();
+           checkDate = new Date(formYear,formMonth-1,formDay);
+         }
+
+         var weekOrder = parseInt((parseInt(formDay)+6)/7);
+
+         // update the day recurrance
+         if (weekOrder<=4) {
+            if (! document.editcalendar.dayfreq[2]) {  // coming from 2 choice menu
+               if (dayfreqSelection==1) {
+                  dayfreqSelection++;
+               }
+            }
+            document.editcalendar.dayfreq.options.length =0; // clear popup
+            document.editcalendar.dayfreq[0] = new Option("$jslabels{thisdayonly}","thisdayonly");
+            document.editcalendar.dayfreq[1] = new Option("$jslabels{thewdayofthismonth}","thewdayofthismonth");
+            document.editcalendar.dayfreq[2] = new Option("$jslabels{everywdaythismonth}","everywdaythismonth");
+         } else {
+            if (document.editcalendar.dayfreq[2]) {  // coming from 3 choice menu
+               dayfreqSelection--;
+               if (dayfreqSelection < 0) {
+                  dayfreqSelection = 0;
+               }
+            }
+            document.editcalendar.dayfreq.options.length =0; // clear popup
+            document.editcalendar.dayfreq[0] = new Option("$jslabels{thisdayonly}","thisdayonly");
+            document.editcalendar.dayfreq[1] = new Option("$jslabels{everywdaythismonth}","everywdaythismonth");
+         }
 
-   $temphtml = startform(-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl",
-                         -name=>'editcalendar');
+         // update the month recurrance
+         if (formMonth%2) {
+            document.editcalendar.monthfreq[1] = new Option("$jslabels{everyoddmonththisyear}","everyoddmonththisyear");
+         } else {
+            document.editcalendar.monthfreq[1] = new Option("$jslabels{everyevenmonththisyear}","everyevenmonththisyear");
+         }
+
+         document.editcalendar.dayfreq.selectedIndex = dayfreqSelection;
+         document.editcalendar.monthfreq.selectedIndex = monthfreqSelection;
+      }
+
+      function nothing() { ; } // for the colorpicker to work properly
+      // -->
+      </script>
+   |;
+
+   $temphtml .= startform(-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl",
+                          -name=>'editcalendar',
+                          -override=>'1');
    $temphtml .= hidden(-name=>'sessionid',
                        -value=>$thissession,
                        -override=>'1');
@@ -1845,15 +2038,6 @@
    $temphtml .= hidden(-name=>'action',
                        -value=>'calupdate',
                        -override=>'1');
-   $temphtml .= hidden(-name=>'year',
-                       -value=>$year,
-                       -override=>'1');
-   $temphtml .= hidden(-name=>'month',
-                       -value=>$month,
-                       -override=>'1');
-   $temphtml .= hidden(-name=>'day',
-                       -value=>$day,
-                       -override=>'1');
    $temphtml .= hidden(-name=>'index',
                        -value=>$index,
                        -override=>'1');
@@ -1864,6 +2048,33 @@
    }
    $html =~ s/\@\@\@STARTFORM\@\@\@/$temphtml/;
 
+   my @days_in_month = qw(0 31 28 31 30 31 30 31 31 30 31 30 31);
+   $days_in_month[2]++ if ( ($year%4)==0 && (($year%100)!=0||($year%400)==0) );
+   $day=$days_in_month[$month] if ($day>$days_in_month[$month]); $day=1 if ($day<1);
+   if ($day != $main::day) { $main::day = $day }; # affect the global $day var or CGI.pm gets confused
+
+   $temphtml = popup_menu(-name=>'month',
+                          -values=>[1..12],
+                          -default=>$month,
+                          -onChange=>"valiDate()",
+                          -labels=>\%lang_month,
+                          -override=>'1');
+
+   $temphtml .= popup_menu(-name=>'day',
+                           -values=>[1..31],
+                           -onChange=>"valiDate()",
+                           -default=>$day,
+                           -override=>'1');
+
+   $temphtml .= popup_menu(-name=>'year',
+                          -values=>[1970..2037],
+                          -onChange=>"valiDate()",
+                          -default=>$year,
+                          -override=>'1');
+   $html =~ s/\@\@\@DATE\@\@\@/$temphtml/;
+
+
+
    $temphtml = textfield(-name=>'string',
                          -default=>$items{$index}{'string'},
                          -size=>'32',
@@ -1889,20 +2100,23 @@
 
    $temphtml = $lang_text{'calfmt_hourminampm'};
    $temphtml2 = popup_menu(-name=>'starthour',
-                          -values=>\@hourlist,
-                          -default=>$starthour,
-                          -labels=>\%numlabels);
+                           -values=>\@hourlist,
+                           -default=>$starthour,
+                           -labels=>\%numlabels,
+                           -override=>'1');
    $temphtml2 .= "<B>:</B>";
    $temphtml2 .= popup_menu(-name=>'startmin',
-                           -values=>[0,5,10,15,20,25,30,35,40,45,50,55],
-                           -default=>$startmin,
-                           -labels=>\%numlabels);
+                            -values=>[0,5,10,15,20,25,30,35,40,45,50,55],
+                            -default=>$startmin,
+                            -labels=>\%numlabels,
+                            -override=>'1');
    $temphtml =~ s/\@\@\@HOURMIN\@\@\@/$temphtml2/;
    if ($prefs{'hourformat'}==12) {
       $temphtml2 = popup_menu(-name=>'startampm',
                               -values=>['am','pm'],
                               -default=>$startampm,
-                              -labels=>{ am=>$lang_text{'am'}, pm=>$lang_text{'pm'} } );
+                              -labels=>{ am=>$lang_text{'am'}, pm=>$lang_text{'pm'} },
+                              -override=>'1');
    } else {
       $temphtml2 = '';
    }
@@ -1919,46 +2133,168 @@
    $temphtml2 = popup_menu(-name=>'endhour',
                            -values=>\@hourlist,
                            -default=>$endhour,
-                           -labels=>\%numlabels);
+                           -labels=>\%numlabels,
+                           -override=>'1');
    $temphtml2 .= "<B>:</B>";
    $temphtml2 .= popup_menu(-name=>'endmin',
                             -values=>[0,5,10,15,20,25,30,35,40,45,50,55],
                             -default=>$endmin,
-                            -labels=>\%numlabels);
+                            -labels=>\%numlabels,
+                            -override=>'1');
    $temphtml =~ s/\@\@\@HOURMIN\@\@\@/$temphtml2/;
    if ($prefs{'hourformat'}==12) {
       $temphtml2 = popup_menu(-name=>'endampm',
                               -values=>['am','pm'],
                               -default=>$endampm,
-                              -labels=>{ am=>$lang_text{'am'}, pm=>$lang_text{'pm'} } );
+                              -labels=>{ am=>$lang_text{'am'}, pm=>$lang_text{'pm'} },
+                              -override=>'1');
    } else {
       $temphtml2 = '';
    }
    $temphtml =~ s/\@\@\@AMPM\@\@\@/$temphtml2/;
    $html =~ s/\@\@\@ENDHOURMINMENU\@\@\@/$temphtml/;
 
-   my $linkstr=$items{$index}{'link'};
-   $linkstr="" if ($linkstr eq "0");
+
+   # deconstruct the idate
+   # An idate has the following format: <years><months><days><dayofweek>
+   # An idate can look like:
+   #    20030808                            The event occurs on August 8, 2003, This Month, This Day only
+   #    (20030808|20030809)                 The event occurs on August 8 and 9, 2003 (or August 8 and Next 1 day)
+   #    .*,04,07,.*                         The event occurs on April 7, Every Year
+   #    .*,.*,((1[5-9])|(2[0-1])),Tue       The event occurs on the 3rd Tuesday, Every Month, Every Year
+   #    2003,.*,.*,Wed                      The event occurs Every Wednesday, Every Week of 2003
+   #    2003,.*,11,.*                       The event occurs Every 11th day, Every Month of 2003
+   my ($everyyear, $monthfreq, $dayfreq, $dow, $startdate, $enddate, $ndays) = '';
+
+   my $dayfreq_default = "thisdayonly";
+   my $thisandnextndays_default = 0;
+   my $ndays_default = "";
+   my $monthfreq_default = "thismonthonly";
+   my $everyyear_default = 0;
+   my $linkstr_default=$items{$index}{'link'};
+   my $emailstr_default=$items{$index}{'email'};
+
+   if ($items{$index}{'idate'} =~ m/,/) { #idate has recurrance in it
+       ($everyyear, $monthfreq, $dayfreq, $dow) = split(/,/, $items{$index}{'idate'});
+       my %weekorder_day_wild_reversed = ( "0[1-7]" => 1,
+                                           "((0[8-9])|(1[0-4]))" => 2,
+                                           "((1[5-9])|(2[0-1]))" => 3,
+                                           "2[2-8]" => 4);
+
+       if ($weekorder_day_wild_reversed{$dayfreq}) {
+          $dayfreq_default = "thewdayofthismonth";
+       } elsif ($dayfreq eq '.*') {
+          $dayfreq_default = "everywdaythismonth";
+       }
+       if ($monthfreq eq '(01|03|05|07|09|11)') {
+          $monthfreq_default = "everyoddmonththisyear";
+       } elsif ($monthfreq eq '(02|04|06|08|10|12)') {
+          $monthfreq_default = "everyevenmonththisyear"
+       } elsif ($monthfreq eq '.*') {
+          $monthfreq_default = "everymonththisyear";
+       }
+       if ($everyyear eq '.*') {
+          $everyyear_default = 1;
+       }
+   } elsif ($items{$index}{'idate'} =~ m/^\(?(\d+)\|?.*?\|?(\d+)?\)?$/) {
+       # That regex breaks apart idates like (20030808|20030809)
+       $startdate = $1;
+       $enddate = $2 || '';
+       if ($enddate) { # we have a next Nday recurrance here
+          $thisandnextndays_default = 1;
+          $ndays_default = $items{$index}{'idate'} =~ tr/|/|/; # count pipes - cheap and easy
+       }
+   } else {
+      openwebmailerror(__FILE__, __LINE__, "Index $index idate $lang_err{'doesnt_exist'}");
+      writelog("edit calitem error - idate wrong format, index=$index");
+      writehistory("edit calitem error - idate wrong format, index=$index");
+   }
+
+   my $t=timegm(1,1,1, $day,$month-1,$year-1900);
+   my $wdaynum=(gmtime($t))[6];
+   my $weekorder=int(($day+6)/7);
+   my %dayfreqlabels = ('thisdayonly'       =>$lang_text{'thisday_only'},
+                        'thewdayofthismonth'=>$lang_text{'the_wday_of_thismonth'},
+                        'everywdaythismonth'=>$lang_text{'every_wday_thismonth'});
+   $dayfreqlabels{'thewdayofthismonth'}=~s/\@\@\@ORDER\@\@\@/$lang_order{$weekorder}/;
+   $dayfreqlabels{'thewdayofthismonth'}=~s/\@\@\@WDAY\@\@\@/$lang_wday{$wdaynum}/;
+   $dayfreqlabels{'everywdaythismonth'}=~s/\@\@\@WDAY\@\@\@/$lang_wday{$wdaynum}/;
+
+   if ($weekorder<=4) {
+      $temphtml = popup_menu(-name=>'dayfreq',
+                             -values=>['thisdayonly', 'thewdayofthismonth', 'everywdaythismonth'],
+                             -default=>$dayfreq_default,
+                             -labels=>\%dayfreqlabels,
+                             -override=>'1');
+   } else {
+      $temphtml = popup_menu(-name=>'dayfreq',
+                             -values=>['thisdayonly', 'everywdaythismonth'],
+                             -default=>$dayfreq_default,
+                             -labels=>\%dayfreqlabels,
+                             -override=>'1');
+   }
+   $html =~ s/\@\@\@FREQMENU\@\@\@/$temphtml/;
+
+   $temphtml = checkbox(-name=>'thisandnextndays',
+                        -value=>'1',
+                        -checked=>$thisandnextndays_default,
+                        -label=>'',
+                        -override=>'1');
+   $html =~ s/\@\@\@THISANDNEXTNDAYSCHECKBOX\@\@\@/$temphtml/g;
+
+   $temphtml = textfield(-name=>'ndays',
+                         -default=>$ndays_default,
+                         -size=>'2',
+                         -override=>'1');
+   $html =~ s/\@\@\@NDAYSFIELD\@\@\@/$temphtml/;
+
+   my %monthfreqlabels = ('thismonthonly'         =>$lang_text{'thismonth_only'},
+                          'everyoddmonththisyear' =>$lang_text{'every_oddmonth_thisyear'},
+                          'everyevenmonththisyear'=>$lang_text{'every_evenmonth_thisyear'},
+                          'everymonththisyear'    =>$lang_text{'every_month_thisyear'});
+   my @monthfreq =('thismonthonly');
+   if ($month%2==1) {
+      push(@monthfreq, 'everyoddmonththisyear');
+   } else {
+      push(@monthfreq, 'everyevenmonththisyear');
+   }
+   push(@monthfreq, 'everymonththisyear');
+   $temphtml = popup_menu(-name=>'monthfreq',
+                          -values=>\@monthfreq,
+                          -default=>$monthfreq_default,
+                          -labels=>\%monthfreqlabels,
+                          -override=>'1');
+   $html =~ s/\@\@\@MONTHFREQMENU\@\@\@/$temphtml/g;
+
+
+   $temphtml = checkbox(-name=>'everyyear',
+                        -value=>'1',
+                        -checked=>$everyyear_default,
+                        -label=>'',
+                        -override=>'1');
+   $html =~ s/\@\@\@EVERYYEARCHECKBOX\@\@\@/$temphtml/g;
+
+
+   $linkstr_default="http://" if ($linkstr_default eq "0");
    $temphtml = textfield(-name=>'link',
-                         -default=>$linkstr,
+                         -default=>$linkstr_default,
                          -size=>'32',
                          -override=>'1');
    $html =~ s/\@\@\@LINKFIELD\@\@\@/$temphtml/;
 
-   my $emailstr=$items{$index}{'email'};
-   $emailstr="" if ($emailstr eq "0");
 
+   $emailstr_default="" if ($emailstr_default eq "0");
    if ($config{'calendar_email_notifyinterval'} > 0 ) {
       $html =~ s/\@\@\@EMAILSTART\@\@\@//;
       $html =~ s/\@\@\@EMAILEND\@\@\@//;
       $temphtml = textfield(-name=>'email',
-                            -default=>$emailstr,
+                            -default=>$emailstr_default,
                             -size=>'32',
                             -override=>'1');
       $html =~ s/\@\@\@EMAILFIELD\@\@\@/$temphtml/;
    } else {
       $temphtml = hidden(-name=>'email',
-                         -value=>$emailstr,
+                         -value=>$emailstr_default,
                          -override=>'1');
       $html =~ s/\@\@\@EMAILSTART\@\@\@/$temphtml<!--/;
       $html =~ s/\@\@\@EMAILEND\@\@\@/-->/;
@@ -1966,16 +2302,22 @@
    }
 
    $temphtml = qq|<table><tr>|;
-   $temphtml .= qq|<td>|.popup_menu(-name=>'eventcolor',
-                                    -values=>['none', sort keys %eventcolors],
-                                    -default=>$items{$index}{'eventcolor'},
-                                    -labels=>{ none=> $lang_text{'none'} } ).qq|</td>|;
+   $temphtml .= qq|<td>|;
+   $temphtml .= popup_menu(-name=>'eventcolor',
+                           -values=>['none', sort keys %eventcolors],
+                           -default=>$items{$index}{'eventcolor'},
+                           -labels=>{ none=> $lang_text{'none'} },
+                           -override=>'1');
+   $temphtml .= qq|</td>|;
+   my $eventcolornum = 1;
    foreach (sort keys %eventcolors) {
-      $temphtml .= qq|<td width=14 align=center bgcolor="#$eventcolors{$_}">|.
-                   qq|<a onclick="JavaScript:document.editcalendar.eventcolor.value='$_'">$_</a></td>|;
+      $temphtml .= qq|<td width="14" align="center" bgcolor="#$eventcolors{$_}">|.
+                   qq|<a href="javascript:nothing()" onClick='javascript:document.editcalendar.eventcolor.selectedIndex="$eventcolornum"'>$_</a></td>\n|;
+      $eventcolornum++;
    }
-   $temphtml .= qq|<td width=14 align=center>|.
-                qq|<a onclick="JavaScript:document.editcalendar.eventcolor.value='none'">--</a></td>|;
+   $temphtml .= qq|<td width="14" align="center">|.
+                qq|<a href="javascript:nothing()" onClick='javascript:document.editcalendar.eventcolor.selectedIndex="0"'>--</a></td>\n|;
+
    $temphtml .= qq|</tr></table>|;
    $html =~ s/\@\@\@EVENTCOLORMENU\@\@\@/$temphtml/;
 
@@ -1983,7 +2325,8 @@
    $html =~ s/\@\@\@SUBMITBUTTON\@\@\@/$temphtml/;
 
    $temphtml = startform(-action=>"$config{'ow_cgiurl'}/openwebmail-cal.pl",
-                         -name=>'cancelform');
+                         -name=>'cancelform',
+                         -override=>'1');
    $temphtml .= hidden(-name=>'sessionid',
                        -value=>$thissession,
                        -override=>'1');
@@ -2078,6 +2421,12 @@
       $endhourmin = sprintf("%02d%02d", $endhour,$endmin);
    }
 
+   # fix the day if needed
+   my @days_in_month = qw(0 31 28 31 30 31 30 31 31 30 31 30 31);
+   $days_in_month[2]++ if ( ($year%4)==0 && (($year%100)!=0||($year%400)==0) );
+   $day=$days_in_month[$month] if ($day>$days_in_month[$month]); $day=1 if ($day<1);
+   if ($day != $main::day) { $main::day = $day }; # affect the global $day var or CGI.pm gets confused
+
    my ($item_count, %items, %indexes);
    if ( ($item_count=readcalbook("$folderdir/.calendar.book", \%items, \%indexes, 0)) <0 ) {
       openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $folderdir/.calendar.book");
@@ -2086,9 +2435,8 @@
    my $index = $item_count+19690404;	# avoid collision with old records
    my $t = timegm(1,1,1, $day,$month-1,$year-1900);
    my $dow = $wdaystr[(gmtime($t))[6]];
-   my $records = "";
 
-   # construct the record.
+   # construct the idate for this record.
    if ($dayfreq eq 'thisdayonly' && $monthfreq eq 'thismonthonly' && !$everyyear) {
       if ($thisandnextndays && $ndays) {
          if ($ndays !~ /\d+/) {
@@ -2163,7 +2511,7 @@
 
    reset_notifycheck_for_newitem($items{$index});
 
-   my $msg="add calitem - start=$starthourmin, end=$endhourmin, str=$string";
+   my $msg="add calitem - index=$index, start=$starthourmin, end=$endhourmin, str=$string";
    writelog($msg);
    writehistory($msg);
 }
@@ -2180,11 +2528,12 @@
    }
    return if (! defined($items{$index}) );
 
-   my $msg="delete calitem - index=$index, t=$items{$index}{'starthourmin'}, str=$items{$index}{'string'}";
    delete $items{$index};
    if ( writecalbook("$folderdir/.calendar.book", \%items) <0 ) {
       openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $folderdir/.calendar.book");
    }
+
+   my $msg="delete calitem - index=$index, t=$items{$index}{'starthourmin'}, str=$items{$index}{'string'}";
    writelog($msg);
    writehistory($msg);
 }
@@ -2196,6 +2545,8 @@
    my ($index, $string,
        $starthour, $startmin, $startampm,
        $endhour, $endmin, $endampm,
+       $dayfreq,
+       $thisandnextndays, $ndays, $monthfreq, $everyyear,
        $link, $email, $eventcolor)=@_;
    my $line;
 
@@ -2241,6 +2592,78 @@
       $endhourmin = sprintf("%02d%02d", $endhour,$endmin);
    }
 
+   # fix the day if needed
+   my @days_in_month = qw(0 31 28 31 30 31 30 31 31 30 31 30 31);
+   $days_in_month[2]++ if ( ($year%4)==0 && (($year%100)!=0||($year%400)==0) );
+   $day=$days_in_month[$month] if ($day>$days_in_month[$month]); $day=1 if ($day<1);
+   if ($day != $main::day) { $main::day = $day }; # affect the global $day var or CGI.pm gets confused
+
+   my $t = timegm(1,1,1, $day,$month-1,$year-1900);
+   my $dow = $wdaystr[(gmtime($t))[6]];
+
+   # construct the idate for this record.
+   my $idate = '';
+   if ($dayfreq eq 'thisdayonly' && $monthfreq eq 'thismonthonly' && !$everyyear) {
+      if ($thisandnextndays && $ndays) {
+         if ($ndays !~ /\d+/) {
+            openwebmailerror(__FILE__, __LINE__, "$lang_err{'badnum_in_days'}: $ndays");
+         }
+         my $date_wild='(';
+         for (my $i=0; $i<=$ndays; $i++) {
+            my ($y, $m, $d)=(gmtime($t+86400*$i))[5,4,3];
+            my $date=sprintf("%04d%02d%02d", $y+1900, $m+1, $d);
+            $date_wild.='|' if ($i>0);
+            $date_wild.=sprintf("%04d%02d%02d", $y+1900, $m+1, $d);
+         }
+         $date_wild.=')';
+         $idate=$date_wild;
+      } else {
+         $idate=sprintf("%04d%02d%02d", $year, $month, $day);
+      }
+
+   } elsif ($dayfreq eq 'thewdayofthismonth') {
+      my $year_wild=sprintf("%04d", $year);
+      my $month_wild=sprintf("%02d", $month);
+      my $day_wild=sprintf("%02d", $day);
+
+      $year_wild = ".*" if ($everyyear);
+      if ($monthfreq eq 'everyoddmonththisyear') {
+         $month_wild="(01|03|05|07|09|11)";
+      } elsif ($monthfreq eq 'everyevenmonththisyear') {
+         $month_wild="(02|04|06|08|10|12)";
+      } elsif ($monthfreq eq 'everymonththisyear') {
+         $month_wild = ".*";
+      }
+      my %weekorder_day_wild= ( 1 => "0[1-7]",
+                                2 => "((0[8-9])|(1[0-4]))",
+                                3 => "((1[5-9])|(2[0-1]))",
+                                4 => "2[2-8]" );
+      my $weekorder=int(($day+6)/7);
+      $day_wild=$weekorder_day_wild{$weekorder} if ($weekorder_day_wild{$weekorder} ne "");
+
+      $idate="$year_wild,$month_wild,$day_wild,$dow";
+
+   } else { # everywdaythismonth and else...
+      my $year_wild=sprintf("%04d", $year);
+      my $month_wild=sprintf("%02d", $month);
+
+      $year_wild = ".*" if ($everyyear);
+      if ($monthfreq eq 'everyoddmonththisyear') {
+         $month_wild="(01|03|05|07|09|11)";
+      } elsif ($monthfreq eq 'everyevenmonththisyear') {
+         $month_wild="(02|04|06|08|10|12)";
+      } elsif ($monthfreq eq 'everymonththisyear') {
+         $month_wild = ".*";
+      }
+
+      if ($dayfreq eq 'everywdaythismonth') {
+         $idate="$year_wild,$month_wild,.*,$dow";
+      } else {
+         my $daystr=sprintf("%02d", $day);
+         $idate="$year_wild,$month_wild,$daystr,.*";
+      }
+   }
+
    my (%items, %indexes);
    if ( readcalbook("$folderdir/.calendar.book", \%items, \%indexes, 0)<0 ) {
       openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $folderdir/.calendar.book");
@@ -2253,10 +2676,11 @@
 
    $items{$index}{'starthourmin'}="$starthourmin"; # " is required or "0000" will be treated as 0?
    $items{$index}{'endhourmin'}="$endhourmin";
+   $items{$index}{'idate'}="$idate";
    $items{$index}{'string'}=$string;
    $items{$index}{'link'}=$link;
    $items{$index}{'email'}=$email;
-   $items{$index}{'eventcolor'}=$eventcolor;
+   $items{$index}{'eventcolor'}="$eventcolor";
 
    if ( writecalbook("$folderdir/.calendar.book", \%items) <0 ) {
       openwebmailerror(__FILE__, __LINE__, "$lang_err{'couldnt_open'} $folderdir/.calendar.book");
