var months   = new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
var days     = new Array(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var dow      = new Array('Su','Mo','Tu','We','Th','Fr','Sa');
var holydays = new Array();


function MakeDateLable(y,m,d) {
    if(m<10) {
        m = '0'+m.toString().replace(/^0/g,'');
    }
    if(d<10) {
        d = '0'+d.toString().replace(/^0/g,'');
    }
    return y+'-'+m+'-'+d;
}

function MakeMonDay(m,d) {
    if(m<10) {
        m = '0'+m.toString().replace(/^0/g,'');
    }
    if(d<10) {
        d = '0'+d.toString().replace(/^0/g,'');
    }
    return ''+m+d;
}

function CalendarDay (y,m,d,c,prefix) { // visible day
    var txt;
    var hc;
    if(m < 10) {
        m = '0'+m;
    }
    if(d< 10) {
        d = '0'+d;
    }
    
    if(!prefix) {
        prefix='';
    }
    
    if(holydays[MakeMonDay(m,d)]) {
        hc='holyday'; // holyday
    } else {
        hc='nonholyday'; // not a holyday
    }
    
    txt = '<td align="right" class="'+c+'" onClick="GotDate(\''+y+"','"+m+"','"+d+"','"+prefix+'\')" id="'+prefix+MakeDateLable(y,m,d)+'">'+d+'<img src="http://www.villa-sinclair.com/r/img/vspacer.gif" width="5" height="5" border="0" align="absbottom" title="'+holydays[MakeMonDay(m,d)]+'" class="'+hc+'" /><br /></td>';
    return txt;
}

function InvisibleDay() { // previous or next month days
    return '<td class="empty"><br /></td>';
}

function PastDay(d) { // days before today
    if(d<10) {
        d = '0'+d;
    }
    return '<td align="right" class="past">'+d+'<br /></td>';
}

function CalendarDayClass(id,c) {
    var item = document.getElementById(id);
    if(item) {
        if(item.className == c) {
            return -1;
        } else {
            item.className=c;
            return 1;
        }
    }
    return 0;
}

function CheckDayClass (id,Class) {
    var item = document.getElementById(id);
    if(item) {
        if(item.className != Class) {
            return -1;
        } else {
            return 1;
        }
    }
    return 0;
}

function CalendarDayClassIF(id,ClassTo,ClassFrom) {
    var item = document.getElementById(id);
    if(item) {
        if(item.className != ClassFrom) {
            return -1;
        } else {
            item.className=ClassTo;
            return 1;
        }
    }
    return 0;
}

function getObjectClass(id) {
    var item = document.getElementById(id);
    if(item) {
        return item.className;
    }
    return '';
}

function GetFirstDOW(y,m) { // returns day of week for first of month
    var firstWeek = new Date(y,m-1,1);
    return firstWeek.getDay();
}

function BeforeToday(y,m,d) {
    var today = new Date();
    var curday = new Date(y,m-1,d);
    return (today>curday);
}

function CalendarWeek(y,m,w,prefix) { //draws week
    var txt = '<tr>';
    var delta=1+(7*w); // day of month for first day of month week 'w'
    var d=-GetFirstDOW(y,m); // count of days before of first of month in first month week
    
    var mdays = days[m-1]; // month days
    if((m==2) && (y%4)) { // correct month days for feb
        mdays-=1;
    }
    for(var i=0; i<7; i++) { // 7 days of week
        if( ((d+i+delta) > 0) && ((d+i+delta) <= mdays)) { // if visible days
            if(BeforeToday(y,m,d+i+delta)) {
                txt += PastDay(d+i+delta);
            } else {
                txt += CalendarDay(y,m,d+i+delta,'free',prefix);
            }
        } else {
            txt += InvisibleDay();
        }
    }
    
    return txt+'</tr>';
}

function CalendarMonth(y,m,prefix) { // month text
    var txt = '<table cellspacing="2" cellpadding="1" border="0">'; // header of month
    txt +='<tr><th colspan="7" class="month_name">'+months[m-1]+' '+y+'<br /></th></tr>';
    txt += '<tr><th class="weekend">'+dow[0]+'</th>';
    for(var i=1; i<6; i++) {
        txt += '<th class="buden">'+dow[i]+'</th>';
    }
    txt += '<th class="weekend">'+dow[6]+'</th></tr>';
    for(i=0;i<6;i++) { // draw 6 weeks of month
        txt += CalendarWeek(y,m,i,prefix);
    }
    txt += '</table>';
    return txt;
}

function CalendarQuarter(y,q,prefix) {
    var txt = '<table cellspacing="5" cellpadding="2" border="0">'; // header of month
    txt += '<tr>'
    q--;
    for(var i=1;i<=3;i++) { // draw 6 weeks of month
        txt += '<td>';
        txt += CalendarMonth(y,i+(3*q),prefix);
        txt += '</td>';
    }
    txt += '</tr>';
    txt += '</table>';
    return txt;
}

function MarkPeriod(b,e,prefix,ClassTo,ClassFrom) {
    var by,bm,bd,ey,em,ed,bb,ee;
    if (b == e) return 0;
    by=b.substring(0,4);
    bm=b.substring(5,7).replace(/^0/g,'');
    bd=b.substring(8,10).replace(/^0/g,'');
    ey=e.substring(0,4);
    em=e.substring(5,7).replace(/^0/g,'');
    ed=e.substring(8,10).replace(/^0/g,'');
    
    
    var ClassBgFrom = getObjectClass(prefix+b);
    var ClassEnFrom = getObjectClass(prefix+e);
    var ClassBgTo = ResolveEdgeClass(ClassBgFrom,ClassTo,0);
    var ClassEnTo = ResolveEdgeClass(ClassEnFrom,ClassTo,1);
    
    // alert(ClassBgTo+" "+ClassEnTo);
    if (CalendarDayClassIF(prefix+b,ClassBgTo,ClassBgFrom) == -1) {
        return 0;
    }
    if (CalendarDayClassIF(prefix+e,ClassEnTo,ClassEnFrom) == -1) {
        return 0;
    }
    var dayms = (1000*60*60*24);
    bb = new Date(Date.parse(bm+"/"+bd+"/"+by) + dayms);
    ee = new Date(Date.parse(em+"/"+ed+"/"+ey) - dayms);
    // alert(b+" : "+bb+" |=| "+e+" : "+ee);

    if (bb>ee) {
        return 1;
    }
    
    bb = MakeDateLable(bb.getFullYear(),parseInt(bb.getMonth()+1),bb.getDate());
    ee = MakeDateLable(ee.getFullYear(),parseInt(ee.getMonth()+1),ee.getDate());
    if (!FillPeriodByClass(bb,ee,prefix,ClassTo,ClassFrom)) {
        CalendarDayClassIF(prefix+b,ClassBgFrom,ClassBgTo);
        CalendarDayClassIF(prefix+e,ClassEnFrom,ClassEnTo);
        return 0;
    }
    return 1;
}

function FreePeriod(b,e,prefix,ClassTo,ClassFrom) {
    var by,bm,bd,ey,em,ed,bb,ee;
    if (b == e) return 0;
    by=b.substring(0,4);
    bm=b.substring(5,7).replace(/^0/g,'');
    bd=b.substring(8,10).replace(/^0/g,'');
    ey=e.substring(0,4);
    em=e.substring(5,7).replace(/^0/g,'');
    ed=e.substring(8,10).replace(/^0/g,'');

//    var ClassBg = getObjectClass(prefix+b);
//    var ClassEn = getObjectClass(prefix+e);
    var ClassBgFrom = getObjectClass(prefix+b);
    var ClassEnFrom = getObjectClass(prefix+e);
    var ClassBgTo = ResolveEdgeClass(ClassBgFrom,ClassTo,0);
    var ClassEnTo = ResolveEdgeClass(ClassEnFrom,ClassTo,1);
    
    
    // alert(ClassBgFrom+" "+ClassEnFrom);
    if (CalendarDayClassIF(prefix+b,ClassBgTo,ClassBgFrom) == -1) {
        return 0;
    }
    
    if (CalendarDayClassIF(prefix+e,ClassEnTo,ClassEnFrom) == -1) {
        return 0;
    }
    
    var dayms = (1000*60*60*24);
    bb = new Date(Date.parse(bm+"/"+bd+"/"+by) + dayms);
    ee = new Date(Date.parse(em+"/"+ed+"/"+ey) - dayms);
    if (bb>ee) {
        return 1;
    }
    
    bb = MakeDateLable(bb.getFullYear(),parseInt(bb.getMonth()+1),bb.getDate());
    ee = MakeDateLable(ee.getFullYear(),parseInt(ee.getMonth()+1),ee.getDate());
    //alert(bb+" "+ee);
    if (!FillPeriodByClass(bb,ee,prefix,ClassTo,ClassFrom)) {
        CalendarDayClassIF(prefix+b,ClassBgFrom,ClassBgTo);
        CalendarDayClassIF(prefix+e,ClassEnFrom,ClassEnTo);
        return 0;
    }
    return 1;
}

function FillPeriodByClass(b,e,prefix,ClassTo,ClassFrom) {
    var by,bm,bd,ey,em,ed,cm,y,prev;
    if (CheckDayClass(prefix+b,ClassFrom) == -1) {
        return 0;
    }
    
    by=b.substring(0,4);
    bm=b.substring(5,7).replace(/^0/g,'');
    bd=b.substring(8,10).replace(/^0/g,'');
    ey=e.substring(0,4);
    em=(ey-by)*12+parseInt(e.substring(5,7).replace(/^0/g,''));
    ed=e.substring(8,10).replace(/^0/g,'');
    prev = MakeDateLable(by,bm,bd);
    for(var m=bm; m<=em; m++) {
        y=parseInt(by)+parseInt((m-1)/12);
        cm=m%12;
        if(cm==0) {
            cm=12;
        }
        for(var d=1; d<=31; d++) {
            if((y==by && m==bm && d<bd)) {
                continue;
            }
            if((y==ey && m==em && d>ed)) {
                return 1;
            }
            if(CalendarDayClassIF(prefix+MakeDateLable(y,cm,d),ClassTo,ClassFrom) == -1) {
                FillPeriodByClass(b,prev,prefix,ClassFrom,ClassTo);
                return 0;
            }
            prev = MakeDateLable(y,cm,d);
        }
    }
    return 1;
}

function ResolveEdgeClass(cc,nc,pos) {
    // cc: current class
    // nc: new class (base for period)
    // pos: 0 - begin period, 1 - end period
    
    var r = '';
    if ((pos != 0) && (pos != 1)) { return r; }
    
    if (cc == 'free') { cc = 'free_free'; }
    var prts = cc.split('_');
    if(pos == 0) { // begin period
        r = prts[0]+'_'+nc;
    } else { // end period
        r = nc+'_'+prts[1];
    }
    if (r == 'free_free') { r = 'free'; }
    
    return r;
}

function IsReserved(id) {
    var ClassRegExp = /free/;
    var cc = getObjectClass(id);
    return !ClassRegExp.test(cc);
}

function FillPeriod(b,e,prefix) {
    //alert(b+' '+e);
    return MarkPeriod(b,e,prefix,'busy','free');
}

function UnFillPeriod(b,e,prefix) {
    return FreePeriod(b,e,prefix,'free','busy');
}

function getYearFromLable(t) {
    return t.substring(0,4);
}

function getMonFromLable(t) {
    return t.substring(5,7).replace(/^0/g,'');
}

function getDayFromLable(t) {
    return t.substring(8,10).replace(/^0/g,'');
}

function FormatDate(t) {
    var y = t.substring(0,4);
    var m = t.substring(5,7).replace(/^0/g,'');
    var d = t.substring(8,10).replace(/^0/g,'');
    return months[m-1] + '/' + d + '/' + y;
}


