// __date__    = "$Date: 9/06/07 1:16p $"
// __version__ = "$Revision: 39 $"
// __author__  = "$Author: Mgibberman $"

Array.prototype.remove = function(idx){ this.splice(idx,1); };

//////////////////////////////////////////////
// __Vars                                   //
//////////////////////////////////////////////

var base_div_id = 'agi-cal-or-list';
var JANUARY     = 1;
var FEBRUARY    = 2;
var MARCH       = 3;
var APRIL       = 4;
var MAY         = 5;
var JUNE        = 6;
var JULY        = 7;
var AUGUST      = 8;
var SEPTEMBER   = 9;
var OCTOBER     = 10;
var NOVEMBER    = 11;
var DECEMBER    = 12;

var todays_month;
var todays_day;
var todays_year;
set_today();

var overall_events = {};

var c_obj;
var Calendar        = {'type' : 'calendar'};
var List            = {'type' : 'list'};
var exclude_fields  = {'Type' : true};
var list_la = 36;
var list_lb = 12;
var calendar_la = 36;
var calendar_lb = 12;

function is_desktop()
{
    try
    {
        if(desktop)
            return true;
        else
            return false;
    } catch(e) {
        return false;
    }
}

function is_toolbar()
{
    try
    {
        if (typeof(toolbar) != "undefined" && toolbar==true)
            return true;
        else
            return false;
    } catch(e) {
        return false;
    }
}
//////////////////////////////////////////////
// __Calendar Functions                     //
//////////////////////////////////////////////
function create_calendar(month, year)
{
    if(!year) year = '';
    if(!month) month = '';
    create_object(Calendar, month, year);
}

function build_calendar()
{
    //clear out previous calendar
    clear_nodes(c_obj.div_id);

    // these pesky buggers needs to be checked each time
    set_today();
    populate_february();
    if (!is_desktop()) set_print_button();

    //build calendar header (arrows, month name, weekday names)
    var header = build_calendar_header(c_obj.month_names[c_obj.month]);
    var table_header = header.thead;
    var nav_header = header.nav;

    //build calendar rows
    var table_body = build_calendar_rows();

    //construct table
    var main_table = make_node('table',{'id':'agi-cal-mtable'},[table_header,table_body]);

    //build footer
    var footer = build_common_footer();

    //construnct main container
    var main_container = make_node('div',{'id':'agi-cal'},[nav_header,main_table,footer]);

    //add calendar to page
    document.getElementById(c_obj.div_id).appendChild(main_container);

    add_listeners('agi-cal-mtable', {'click'    : handle_calendar_click,
                                     'mouseover': handle_calendar_hover,
                                     'mouseout' : handle_calendar_hover});

    //fill in events
    fill_calendar_events();
    toggle_print('on');
}

function build_calendar_header(month_name)
{
    //nav header (arrows, date)
    var header = build_common_header(month_name);
    //table header (weekday names)
    var table_header =
        make_node('thead',{},
            make_node('tr',{'class':'agi-monthrow'},
                [
                make_node('th',{},make_text('Sunday')),
                make_node('th',{},make_text('Monday')),
                make_node('th',{},make_text('Tuesday')),
                make_node('th',{},make_text('Wednesday')),
                make_node('th',{},make_text('Thursday')),
                make_node('th',{},make_text('Friday')),
                make_node('th',{},make_text('Saturday'))
                ]));
    return {'nav':header, 'thead':table_header};
}

function build_calendar_rows()
{
    //set the desired month
    var first_weekday   = new Date(c_obj.year, c_obj.month-1, 1).getDay();
    var total_days      = c_obj.days_in_months[c_obj.month];

    //loop to create weeks & days
    var counter = 1;
    var tbody = make_node('tbody');
    var row = make_node('tr');
    while(true){
        var ret = get_date(counter, first_weekday, total_days);
        var pdict = {};
        pdict['id'] = 'td'+make_date_string(ret.year, ret.month, ret.day);

        //day doesn't belong to month
        if(ret.month != c_obj.month)
            pdict['class'] = 'agi-calday-empty';

        //current date, mark special
        if(ret.day==todays_day && ret.month==todays_month && ret.year==todays_year && c_obj.month==todays_month)
            pdict['class'] = 'agi-calday-today';

        //create cell
        row.appendChild(
            make_node('td',pdict,
                make_node('div',{'class':'agi-calday-full'},
                    make_text(String(ret.day)))));
        //drop down and start new row ?
        if(counter%7===0)
        {
            //end of calendar
            if((counter-first_weekday) >= total_days)
                break;
            //start new row
            else
            {
                tbody.appendChild(row);
                row = make_node('tr');
            }
        }
        counter += 1;
    }
    //final row
    if(row.hasChildNodes)
        tbody.appendChild(row);
    return tbody;
}

function fill_calendar_events()
{
    //grab list of displayable events (prev, curr, and next months)
    var event_list = build_calendarview_events();
    //loop through and build each event (icon + label)
    for(var x=0; x < event_list.length; x++)
    {
        var event = event_list[x];
        try{
            var td_id = 'td'+make_date_string(event.year_start, event.month_start, event.day_start);
            var new_node =
                make_node('p',{},
                    [
                    make_node('a',{'href':'javascript:edit_event('+make_edit_parms(event)+')'},
                        [
                        make_node('img',{'width':'20', 'height':'20', 'border':'0',
                                        'src':icon_base+event.occasion_id+'.gif'}),
                        make_text(event.label)
                        ])
                    ]);
            document.getElementById(td_id).appendChild(new_node);
        }
        catch(e){}
    }
}

function build_calendarview_events()
{
    var month = c_obj.month;
    var year = c_obj.year;
    var base = overall_events[year][month];
    var previous, next, ret, _month, _year;

    //previous month
    try
    {
        ret = adjust_date(month, year, -1);
        _month = ret.month;
        _year = ret.year;
        previous = has_key(_month,_year) ? overall_events[_year][_month] : [];
    }
    catch(e){}
    //next month
    try
    {
        ret = adjust_date(month, year, 1);
        _month = ret.month;
        _year = ret.year;
        next = has_key(_month,_year) ? overall_events[_year][_month] : [];
    }
    catch(e){}

    //combine prev, curr, and next months
    var event_list = previous.concat(base).concat(next);
    return event_list;
}

function handle_calendar_click(e)
{
    var elem;
    var day, month, year;
    var webvars;
    var add_url = ahost + '/reminders/event_add.pd?';

    //element that was clicked
    if (e.srcElement)
        elem = e.srcElement;
    else
        elem = e.target;

    //clicked on empty space in table cell
    if((elem.tagName.toUpperCase() == 'DIV') && (elem.className == 'agi-calday-full'))
        elem = elem.parentNode;

    //didn't click on empty space, return
    if(elem.id.toUpperCase().substring(0,2)!='TD')
        return;

    //parse out date of clicked cell
    var td_id = elem.id.substring(2);
    year = td_id.substring(0,4);
    month = td_id.substring(4,6);
    day = td_id.substring(6,8);

    webvars = 'month='+month+'&year='+year+'&day='+day;

    //call lightbox for add event
    if (add_html !== "" && day !== "")
    {
        lightbox(add_url + webvars,{width:440}, add_html);
        try
        {
            wevent.set_date_values(month, day, year);
        } catch(e){}
    }
    else if (day !== "")
        lightbox(add_url + webvars,{width:440});
}

function handle_calendar_hover(e)
{
    //hovered element
    var elem;
    if (e.srcElement)
        elem = e.srcElement;
    else
        elem = e.target;

    var hover_class = 'agi-calday-hover';
    var today_class = 'agi-calday-today';
    var action = e.type.toLowerCase();
    var tag = elem.tagName.toUpperCase();

    //at top level, can't change color
    if(tag=='TABLE' || tag=='TR' || tag=='TH')
        return;
    //child of TD, loop until parent (TD) found
    if(tag != 'TD')
    {
        while(true)
        {
            elem = elem.parentNode;
            tag = elem.tagName.toUpperCase();
            if(tag == 'TD')
                break;
        }
    }
    //in current month ?
    var td_id = elem.id.toUpperCase();
    if(td_id.substring(0,2) != 'TD')
        return;
    //from prev|next month
    if(Number(td_id.substring(6,8)) != c_obj.month)
        return;

    //change background color
    var is_today = (elem.className.indexOf(today_class) > -1);
    if(action == 'mouseover')
    {
        var curr = elem.className;
        if(curr)
            hover_class = curr+' '+hover_class;
        elem.className = hover_class;
    }
    //remove background color
    else
    {
        if(is_today)
            elem.className = today_class;
        else
        {
            elem.removeAttribute('class');
            elem.removeAttribute('className');
        }
    }
}

function add_listeners(target_object, event_handlers)
{
    var obj = document.getElementById(target_object);
    for(var event_to_catch in event_handlers)
        addEventListener(obj, event_to_catch, event_handlers[event_to_catch]);
}

function addEventListener(element, event, handler)
{
    if (element.addEventListener)
    {
        try
        {
            element.addEventListener(event, handler, false);
        }
        catch(e){}
    }
    else
    {
        try
        {
            element.attachEvent('on' + event, handler);
        }
        catch(e){}
    }
}

//////////////////////////////////////////////
// __List Functions                         //
//////////////////////////////////////////////

function create_list(month, year)
{
    if(!year) year = '';
    if(!month) month = '';
    create_object(List, month, year);
}

function build_list()
{
    clear_nodes(c_obj.div_id);

    // these pesky buggers needs to be checked each time
    set_today();
    if (!is_desktop()) set_print_button();

    var main_container;

    //build list header (arrows, date range)
    var header = build_list_header(c_obj.month_names[c_obj.month]);
    var table_header = header.thead;
    var nav_header = header.nav;

    //get list of displayable events
    var event_list = build_listview_events();

    //construct the table body
    var table_body = make_node('tbody');
    for(var x=0; x < event_list.length; x++)
    {
        var row;
        var month_start = event_list[x].month_start;
        var day_start   = event_list[x].day_start;
        var year_start  = event_list[x].year_start;
        month_start = (String(month_start).length<2) ? '0'+String(month_start) : month_start;
        day_start   = (String(day_start).length<2) ? '0'+String(day_start) : day_start;

        //a complete row on list view (icon, label, date, first name, last name)
        if (is_desktop())
        {
            //row_attrs = {'onmouseover':"this.className='agi-reminderRow"+((x%2)+1)+"h';",
            //             'onmouseout':"this.className='agi-reminderRow"+((x%2)+1)+"';",
            //             'class':'agi-reminderRow'+((x%2)+1)+' agi-color-occasion'};
            var link_node = make_node('span',{'class':'agi-remsendecard'},
                            [
                             make_node('a',
                            {'href':'javascript:edit_event('+make_edit_parms(event_list[x])+')'},
                                                                        make_text('send an ecard'))
                            ]);
            //var link_node = make_node('a',
            //                {'href':'javascript:edit_event('+make_edit_parms(event_list[x])+')'},
            //                                                            make_text('send an ecard'));
            if (event_list[x].occasion_id==13)
                        link_node = make_text('');
            row_attrs = {'class':'agi-reminderRow'+((x%2)+1)+' agi-color-occasion'};
            if (is_today(month_start,day_start,year_start)) {
                row_attrs['id'] = 'rowtoday';
                row_attrs['class'] = 'agi-reminderRow'+((x%2)+1)+'h agi-color-occasion';
            }
            row =
            make_node('tr',row_attrs,
                [
                make_node('td',{'align':'center'},
                    make_node('a',{'href':'javascript:edit_event('+make_edit_parms(event_list[x])+')'},
                        make_node('img',{'width':'20','height':'20','border':'0',
                        'src':icon_base+event_list[x].occasion_id+'.gif'}))),
                make_node('td',{},
                     make_node('span',{},
                     make_node('a',{'href':'javascript:edit_event('+make_edit_parms(event_list[x])+')'},make_text(event_list[x].label)))
                        ),
                make_node('td',{},make_text(month_start+'/'+day_start+'/'+year_start)),
                make_node('td',{},
                    make_node('span',{},
                    link_node))
                ]);
        } else {
            row =
            make_node('tr',{'class':'agi-row'+((x%2)+1)+' agi-color-occasion'},
                [
                make_node('td',{'align':'center'},
                    make_node('a',{'href':'javascript:edit_event('+make_edit_parms(event_list[x])+')'},
                        make_node('img',{'width':'20','height':'20','border':'0',
                        'src':icon_base+event_list[x].occasion_id+'.gif'}))),
                make_node('td',{},
                     make_node('span',{},
                     make_node('a',{'href':'javascript:edit_event('+make_edit_parms(event_list[x])+')'},make_text(event_list[x].label)))
                        ),
                make_node('td',{},make_text(month_start+'/'+day_start+'/'+year_start)),
                make_node('td',{},
                    make_node('span',{},format_name(event_list[x].first_name))),
                make_node('td',{},
                    make_node('span',{},format_name(event_list[x].last_name)))
                ]);
        }
        table_body.appendChild(row);
    }
    //construct the main table for list view
    var main_table = make_node('table',{'id':'list_header','class':'sortable agi-border'},[table_header,table_body]);

    //make default view link ?
    var footer = build_common_footer();

    //construct the overall list view
    if (is_desktop())
    {
        var scroll_div = make_node('div', {'id': 'agi-remcontent'}, [main_table]);
        main_container = make_node('div',{'onafterupdate':'javascript:alert("updated");','id':'agi-list'},[nav_header,scroll_div,footer]);
    } else {
        main_container = make_node('div',{'id':'agi-list'},[nav_header,main_table,footer]);
    }
    document.getElementById(c_obj.div_id).appendChild(main_container);

    //make column headers clickable (for sorting)
    sortables_init(exclude_fields);
    toggle_print('on');
}

function build_list_header(month_name)
{
    //nav header (arrows, date range)
    var header = build_common_header(month_name);
    var table_header;

    //head for main table (column names)
    if (is_desktop())
    {
        table_header =
        make_node('thead',{},
            make_node('tr',{'class':'agi-remSort'},
                [
                make_node('th',{'style':'text-align: center'},make_text('Type')),
                make_node('th',{},make_text('Event Name')),
                make_node('th',{},make_text('Date')),
                make_node('th',{},make_text(''))
                ]));
    } else {
        table_header =
        make_node('thead',{},
            make_node('tr',{},
                [
                make_node('th',{'style':'text-align:center'},make_text('Type')),
                make_node('th',{},make_text('Event Name')),
                make_node('th',{},make_text('Date')),
                make_node('th',{},make_text('First Name')),
                make_node('th',{},make_text('Last Name'))
                ]));
    }
    return {'nav':header, 'thead':table_header};
}

function build_listview_events()
{
    var month = c_obj.month;
    var year = c_obj.year;
    var end_year = year + 1;

    if (is_desktop())
        end_year = year;

    var range = {'start_month': month,
                 'start_year': year,
                 'end_month': month,
                 'end_year': end_year
                };
    var event_list = [];

    //get all events for current year (13 months e.g. 3/2006 - 3/2007)
    while(in_range(month, year, range))
    {
        event_list = event_list.concat(overall_events[year][month]);
        var _ret = adjust_date(month, year, 1);
        month = _ret.month;
        year = _ret.year;
    }
    return event_list;
}


//////////////////////////////////////////////
// __Object Functions                       //
//////////////////////////////////////////////

function create_object(obj, month, year)
{
    //set current object (cal or list)
    c_obj = obj;
    //initialize properties
    init_object_properties(month, year);
    //show loader
    print_loading(obj);
    //grab events, build cal or list
    create_request_object_and_open();
}

function init_object_properties(month, year)
{
    var obj_type = c_obj.type;

    //date passed in ?
    if(empty_val(month) || empty_val(year))
    {
        month = todays_month;
        year = todays_year;
    }
    //set initial values
    c_obj.type        = obj_type;
    c_obj.type_proper = c_obj.type.charAt(0).toUpperCase() + c_obj.type.substring(1);
    c_obj.month       = month;
    c_obj.year        = year;
    c_obj.div_id      = base_div_id;
    c_obj.build_fn    = eval('build_'+c_obj.type);
    c_obj.create_fn   = eval('create_'+c_obj.type);
    c_obj.print_btn   = eval(c_obj.type+'_print');
    c_obj.request     = '';
    c_obj.month_names    = populate_months();
    c_obj.days_in_months = populate_num_days();
    c_obj.ucid           = ucid;
    if(!c_obj.look_ahead && !c_obj.look_behind)
        set_threshold();
}

function create_request_object_and_open()
{
    var url_to_open = ahost+'/reminders/getevents.pd';
    var send_method = 'POST';
    var allow_async = true;
    var show_waiting = true;
    var webvars;

    //open page
    c_obj.request = new Requester(url_to_open, send_method, allow_async, show_waiting);
    c_obj.request.onsuccess = get_object_events;
    c_obj.request.onerror = print_error;

    //execute it
    webvars = 'y='+c_obj.year+'&m='+(c_obj.month)+'&c='+c_obj.ucid;
    webvars += '&la='+c_obj.look_ahead+'&lb='+c_obj.look_behind+'&t='+c_obj.type;
    c_obj.request.sendRequest(webvars);
}

function set_threshold(direction)
{
    var la = is_list() ? list_la : calendar_la;
    var lb = is_list() ? list_lb : calendar_lb;

    // No direction passed in
    if(!direction)
    {
        c_obj.look_ahead = la;
        c_obj.look_behind = lb;
        return;
    }
    // up (forward)
    if(direction=='up')
    {
        c_obj.look_ahead =  la;
        c_obj.look_behind = 0;
    }
    // down (behind)
    else
    {
        c_obj.look_ahead = is_list() ? 12 : 0;
        c_obj.look_behind = lb;
    }
}

function build_or_create_new(direction)
{
    // set lookahead & lookbehind
    set_threshold(direction);
    var use_cache = check_range_keys();

    if(is_calendar() && use_cache)
    {
        var range = get_cached_range(true); //sans 1 month buffer on endpoints
        use_cache = in_range(c_obj.month, c_obj.year, range);
    }

    // build or create new ?
    if(!use_cache)
        c_obj.create_fn(c_obj.month, c_obj.year);
    else
        c_obj.build_fn();
}

function check_range_keys()
{
    //calendar, just check if month in buffer
    if(is_calendar())
        return has_key(c_obj.month, c_obj.year);

    //set date range (for displayed year)
    var has_all_keys = false;
    var month = c_obj.month;
    var year = c_obj.year;

    var range = {'start_month': month,
                 'start_year': year,
                 'end_month': month,
                 'end_year': (year+1)
                };
    //check if each month for displayed range in buffer
    while(in_range(month, year, range))
    {
        if(!has_key(month, year))
        {
            has_all_keys = false;
            break;
        }
        has_all_keys = true;
        var ret = adjust_date(month, year, 1);
        month = ret.month;
        year = ret.year;
    }
    return has_all_keys;
}

function goto_today(which)
{
    //reinit object, go to today's date, rebuild object (using cached buffer)
    if(which)
        c_obj = which;
    set_today();
    init_object_properties(todays_month, todays_year);
    build_or_create_new('up');
    show_today(); //Desktop-specific
}


//////////////////////////////////////////////
// __Event Functions                        //
//////////////////////////////////////////////

function get_object_events(req)
{
    //grab events, prebuild keys, populate with events
    try{
        eval('var events='+req.responseText);
    }
    catch(e){
        print_error(req);
    }
    set_overall_events_keys();
    for(var x=0; x<events.length; x++)
    {
        set_event(events[x]);
    }
    c_obj.build_fn();
    show_today(); // Desktop-specific
}

function set_event(event)
{
    try{
        overall_events[event.year_start][event.month_start].push(event);
       }
    catch(e){}
}

function has_key(month, year)
{
    if(overall_events[year])
    {
        if(overall_events[year][month])
            return true;
    }
    return false;
}

function set_overall_events_keys()
{
    var range = get_date_range(c_obj.month, c_obj.year);
    var start_year = range.start_year;
    var start_month = range.start_month;
    var end_year = range.end_year;
    var end_month = range.end_month;
    var month;

    // prebuild keys (start year)
    if(!overall_events[start_year])
    overall_events[start_year] = {};
    for(month=start_month; month<=12; month++)
        overall_events[start_year][month] = [];
    // prebuild keys (middle years)
    for(var year=start_year+1; year<end_year; year++)
    {
        overall_events[year] = {};
        for(month=1; month<=12; month++)
            overall_events[year][month] = [];
    }
    // prebuild keys (end year)
    if(!overall_events[end_year])
    overall_events[end_year] = {};
    for(month=1; month<=end_month; month++)
        overall_events[end_year][month] = [];
}

function update_event_list(event_object)
{
    // the event object passed in holds an event id
    // and a new/updated list of events to put in buffer.
    // if event list is empty, user has performed a Delete

    var event_id = event_object.id;
    var events = event_object.events;
    if(!events) events = [];

    remove_events(event_id);
    add_events(events);
    c_obj.build_fn();
}

function remove_events(event_id)
{
    //delete events in buffer with given event_id
    for(var year in overall_events)
    {
        for(var month in overall_events[year])
        {
            for(var i=overall_events[year][month].length-1; i>=0; i--)
            {
                var m = overall_events[year][month];
                if(m[i].id == event_id)
                {
                    m.remove(i);
                }
            }
        }
    }
}

function add_events(events)
{
    //add events to buffer
    for(var i=0; i<events.length; i++)
    {
        var event = events[i];
        var event_day = parseInt(event.day_start);
        //insert in correct location (sorted by date)
        try{
            var month_list = overall_events[event.year_start][event.month_start];
            for(var j=0; j<month_list.length; j++)
            {
                if(event_day < parseInt(month_list[j].day_start))
                    break;
            }
            overall_events[event.year_start][event.month_start].splice(j,0,event);
        }
        catch(e){}
    }
}

function get_cached_range(remove_buffer)
{
    if(remove_buffer==undefined) remove_buffer = false;
    var no_events   = empty_events();
    var start_month = no_events ? 1 : 13;
    var start_year  = no_events ? 1899 : 99999;
    var end_month   = no_events ? 1 : 0;
    var end_year    = no_events ? 1899 : 0;

    for(var year in overall_events)
    {
        if(Number(year) < start_year)
            start_year = Number(year);
        if(Number(year) > end_year)
            end_year = Number(year);
    }
    for(var month in overall_events[start_year])
    {
        if(Number(month) < start_month)
            start_month = Number(month);
    }
    for(var month in overall_events[end_year])
    {
        if(Number(month) > end_month)
            end_month = Number(month);
    }

    if(remove_buffer)
    {
        var ret = adjust_date(start_month, start_year, 1);
        start_month = ret.month;
        start_year = ret.year;

        ret = adjust_date(end_month, end_year, -1);
        end_month = ret.month;
        end_year = ret.year;
    }

    return {start_month: start_month,
            start_year: start_year,
            end_month: end_month,
            end_year: end_year
           };
}


//////////////////////////////////////////////
// __Date(like) Functions                   //
//////////////////////////////////////////////

function populate_months()
{
    var month_names = {};
    month_names[JANUARY]    = 'January';
    month_names[FEBRUARY]   = 'February';
    month_names[MARCH]      = 'March';
    month_names[APRIL]      = 'April';
    month_names[MAY]        = 'May';
    month_names[JUNE]       = 'June';
    month_names[JULY]       = 'July';
    month_names[AUGUST]     = 'August';
    month_names[SEPTEMBER]  = 'September';
    month_names[OCTOBER]    = 'October';
    month_names[NOVEMBER]   = 'November';
    month_names[DECEMBER]   = 'December';
    return month_names;
}

function populate_num_days()
{
    var days_in_month = new Array(12);
    days_in_month[JANUARY]      = 31;
    days_in_month[FEBRUARY]     = populate_february();
    days_in_month[MARCH]        = 31;
    days_in_month[APRIL]        = 30;
    days_in_month[MAY]          = 31;
    days_in_month[JUNE]         = 30;
    days_in_month[JULY]         = 31;
    days_in_month[AUGUST]       = 31;
    days_in_month[SEPTEMBER]    = 30;
    days_in_month[OCTOBER]      = 31;
    days_in_month[NOVEMBER]     = 30;
    days_in_month[DECEMBER]     = 31;
    return days_in_month;
}

function adjust_date(month, year, inc)
{
    month += inc;
    if(month < 1)
    {
        month = 12;
        year -= 1;
    }
    else if(month > 12)
    {
        month = 1;
        year += 1;
    }
    return {'month': month, 'year': year};
}

function make_date_string(year, month, day)
{
    year = String(year);
    month = month<10 ? '0'+String(month) : String(month);
    day = day<10 ? '0'+String(day) : String(day);
    return year+month+day;
}

function set_today()
{
    var curr_date = new Date();
    todays_month = curr_date.getMonth()+1;
    todays_day = curr_date.getDate();
    todays_year = curr_date.getFullYear();
}

function in_range(month, year, range_object)
{
    if(year<range_object.start_year || year>range_object.end_year)
        return false;
    if(month<range_object.start_month && year<=range_object.start_year)
        return false;
    if(month>range_object.end_month && year>=range_object.end_year)
        return false;
    return true;
}

function get_date_range(center_month, center_year)
{
    //starting year/month
    var start_month = center_month - c_obj.look_behind;
    var start_year = center_year;
    if (start_month < 1)
    {
        start_month = Math.abs((start_month+12) % 12);
        if(start_month===0)
            start_month = 12;
        start_year -= Math.round(c_obj.look_behind/12);
        start_year -= ((center_month - (c_obj.look_behind%12))<1) ? 1 : 0;
    }
    //ending year/month
    var end_month = center_month + c_obj.look_ahead;
    var end_year = center_year;
    if (end_month > 12)
    {
        end_month = Math.abs((end_month-12) % 12);
        if(end_month===0)
            end_month = 12;
        end_year += Math.round(c_obj.look_ahead/12);
        end_year += (((c_obj.look_ahead%12)+center_month)>12) ? 1 : 0;
    }
    //return date range as a dictionary
    return {start_month: start_month,
            start_year: start_year,
            end_month: end_month,
            end_year: end_year};
}

function show_today() {
    if (is_desktop()){
        var t = document.getElementById('rowtoday');
        if (t !== null) t.scrollIntoView(false);
    }
}

function toggle_month(inc)
{
    var direction = inc>0 ? 'up' : 'down';

    var ret = adjust_date(c_obj.month, c_obj.year, inc);
    c_obj.month = ret.month;
    c_obj.year = ret.year;
    build_or_create_new(direction);
    show_today(); //Desktop-specific
}

function toggle_year(inc)
{
    var direction = inc>0 ? 'up' : 'down';
    c_obj.year += inc;
    build_or_create_new(direction);
}

function leap_year(year)
{
    //leap year if divisible by 4 and not divisible by 100,
    //or divisible by 400
    return(year%4===0 && ((year%100!==0) || (year%400===0)));
}

function populate_february()
{
    var num_days = leap_year(c_obj.year) ? 29 : 28;
    if(c_obj.days_in_months)
        c_obj.days_in_months[FEBRUARY] = leap_year(c_obj.year) ? 29 : 28;
    else
        return num_days;
}


//////////////////////////////////////////////
// __Print(like) functions                  //
//////////////////////////////////////////////
function print_loading()
{
    //hide print button
    toggle_print('off');

    //simply remove arrows and nav links ?
    try
    {
        remove_navigation();
    }
    //show print loader
    catch(e)
    {
        var show_loading = true;
        try
        {
            show_loading = (document.getElementById('loadingImage').style.display=='hidden');
        }
        catch(e){}
        if(show_loading)
        {
            var container = document.getElementById(c_obj.div_id);
            clear_nodes(c_obj.div_id);

            var loading =
                make_node('center',{},
                    make_node('div',{'id':'agi-loadershell'},
                        make_node('embed',
                            {
                            'name':'FlashProduct',
                            'src':imghost+'/'+site+'/reminders/loader.swf',
                            'swLiveConnect':true,
                            'width':110,
                            'height':110,
                            'scale':'noborder',
                            'quality':'high',
                            'type':'application/x-shockwave-flash',
                            'pluginspace':'http://www.macromedia.com/go/getflashplayer',
                            'wmode':'transparent'
                            })));
            container.appendChild(loading);
        }
    }
}

function print_error(req)
{
    //remove print button
    toggle_print('off');

    //clear out cal/list
    clear_nodes(c_obj.div_id);

    //construct error, stick it in middle of screen
    var container = document.getElementById(c_obj.div_id);
    var error_node =
        make_node('center',{},
            [
            make_node('br'),
            make_text('There was a problem loading your '+c_obj.type_proper),
            make_node('br'),
            make_node('br'),
            make_text(req.statusText)
            ]);
    container.appendChild(error_node);
}

function toggle_print(toggle)
{
    var obj = document.getElementById('print');
    if(!obj)
        return;

    //show/hide print button
    if(toggle == 'off')
        obj.style.visibility = 'hidden';
    else
        obj.style.visibility = 'visible';
}

function set_print_button()
{
    //show Print List or Print Calendar button
    var old_button = document.getElementById('print').getElementsByTagName('img')[0];
    var new_button = old_button.cloneNode(true);
    new_button.setAttribute('src',c_obj.print_btn.src);
    new_button.setAttribute('alt','Print '+c_obj.type_proper);
    new_button.setAttribute('title','Print '+c_obj.type_proper);
    old_button.parentNode.replaceChild(new_button, old_button);
}


//////////////////////////////////////////////////////
// __View Changer (set default view)                //
//////////////////////////////////////////////////////
function view_changer(which, demo)
{
    if(demo==undefined) demo = true;
    var cookie = demo ? 'womprefd' : 'wompref';

    //remove link after it is clicked
    var anchor = document.getElementById('change_view');
    anchor.removeAttribute('href');
    anchor.removeAttribute('onclick');
    anchor.style.display = 'none';

    //get current view value from cookie
    var curr_value = get_double_nvp_value(cookie, 'wview');
    if(curr_value == which)
        return;

    //set value in cookie
    set_double_nvp_value(cookie, 'wview', which);

    //set text in left nav
    change_nav_text(demo);

    //save pref in database
    if(!demo)
        set_view_pref(which);
}

function set_view_pref(which)
{
    //call page to save pref in database
    var url_to_open = ahost+'/reminders/setprefs.pd?p=DISPLAY&v='+which;
    var send_method = 'GET';
    var allow_async = true;
    var show_waiting = false;
    var req = new Requester(url_to_open, send_method, allow_async, show_waiting);
    req.onsuccess = set_pref_success;
    req.onerror = set_pref_error;
    req.sendRequest();
}

function set_pref_success(req)
{
    //insert processing if needed
}

function set_pref_error(req)
{
    //insert processing if needed
}

//////////////////////////////////////////////
// __Builder functions                      //
//////////////////////////////////////////////

function build_common_footer()
{
    if(is_toolbar()){
        return '';
    }

    var footer;
    if (is_desktop()) {
        var add_btn = make_node('div',{'id':'agi-btn_add'},
            [
            make_node('a',{'href':'javascript:add_calendar_event();'},
                [
                make_node('img',{'src':imghost+'/agbeta/desktop/rem_add.gif','alt':'Add Events','border':'0'})
                ])
            ]);
        var requester_btn = make_node('div',{'id':'agi-btn_print'},
            [
            make_node('a',{'href':ahost+'/reminders/request.pd','target':'_blank'},
                [
                make_node('img',{'src':imghost+'/agbeta/desktop/rem_requester.gif','alt':'Birthday Requester','border':'0'})
                ])
            ]);
        var print_btn = make_node('div',{'id':'agi-btn_print'},
            [
            make_node('a',{'href':'javascript:print_desktop_list();'},
                [
                make_node('img',{'src':imghost+'/agbeta/desktop/rem_printlist.gif','alt':'Print List','border':'0'})
                ])
            ]);
        footer = make_node('div',{'id':'agd-buttons', 'class':'agi-lowerRow'},[add_btn,requester_btn,print_btn]);
        return footer;
    }

    //don't show default view link for demo user
    var demo = !signed_in;
    if(demo)
        return make_text('');

    //var cookie = demo ? 'womprefd' : 'wompref';
    var cookie = 'wompref';
    var curr_view = get_double_nvp_value(cookie, 'wview');
    if(!curr_view) curr_view = 'calendar';

    //currently showing default view, don't show link
    if(curr_view == c_obj.type)
        return make_text('');

    //show appropriate default view link (cal or list)
    var anchor_attrs = {'id':'change_view','href':"javascript:view_changer('"+c_obj.type+"',"+!signed_in+")"};
    footer =
        make_node('div',{'style':'text-align:left;'},
            [
            make_node('br'),
            make_node('a',anchor_attrs,make_text('Make '+c_obj.type_proper+' View My Default'))
            ]);
    return footer;
}

function build_common_header(month_name)
{
    var toggle,range,views;
    var today_text = make_text('Back To Today');
    var cal_text = make_text('Calendar View');
    var list_text = make_text('List View');

    if (is_desktop()) {
        return build_desktop_header(month_name);
    }

    //set text for calendar
    if(is_calendar() || is_desktop())
    {
        toggle = "toggle_month";
        range = make_text(month_name+' '+c_obj.year);
        cal_text = make_node('strong',{},cal_text);
    }
    //set text for list
    else
    {
        toggle = "toggle_year";
        range = make_text(month_name+' '+c_obj.year+' - '+(c_obj.year+1));
        list_text = make_node('strong',{},list_text);
    }

    //construct arrow icons
    var arrows =
        [
        build_arrow('left'),
        build_arrow('right')
        ];
    var arrow_section = make_node('div',{'class':'agi-left agi-noprint'},arrows);

    //construct date range
    var ranges =
        [
        make_text(' '),
        make_node('span',{'class':'agi-monthtext agi-themedark'},range),
        make_text('  '),
        make_node('span',{'class':'agi-noprint agi-themedark'},
            make_node('a',
                {'id':'today','class':'agi-noprint','href':'javascript:goto_today()'},
                today_text))
        ];
    var range_section = make_node('div',{'class':'agi-left'},ranges);

    //construct Calendar/List View links
    if (is_desktop())
    {
        views = [make_text('')];
    } else {
        views =
            [
                make_node('a',{'id':'cview','href':'javascript:goto_today(Calendar)'},cal_text),
                make_text(' | '),
                make_node('a',{'id':'lview','href':'javascript:goto_today(List)'},list_text)
            ];
    }
    var view_section = make_node('div',{'id':'tview', 'class':'agi-choices agi-noprint agi-themedark'},views);

    //put it all together
    var head_section =
        make_node('div',{'id':'agi-calhead'},
            [
            arrow_section,
            range_section,
            view_section,
            make_node('div',{'class':'agi-clear'})
            ]);
    return head_section;
}

function build_desktop_header(month_name)
{
    var head_section = make_node('div',{'class':'agi-remNavTop','id':'agd-remNavTop'},[
        make_node('div',{'class':'agi-highrow'},[
            make_node('div',{'class':'agi-larrow'},[
                make_node('a',{'href':'javascript:toggle_month(-1);','title':'previous month','class':'agi-montharrow-l'},[
                    make_node('img',{'width':'23','height':'34','border':'0','src':imghost+'/agbeta/desktop/arrow_left.gif'})])]),
            make_node('div',{'class':'agi-rarrow'},[
                make_node('a',{'href':'javascript:toggle_month(1);','title':'next month','class':'agi-montharrow-r'},[
                    make_node('img',{'width':'23','height':'34','border':'0','src':imghost+'/agbeta/desktop/arrow_right.gif'})])]),
            make_node('div',{'class':'agi-monthname'},[make_text(month_name+' '+c_obj.year)]),
            make_node('div',{'class':'agi-backtotoday'},[
                make_node('a',{'id':'today','class':'agi-noprint','href':'javascript:goto_today();'},[make_text('Back to Today')])]),
            make_node('br',{'style':'clear: both;'})])]);
    return head_section;
}

function build_arrow(direction)
{
    //build up correct function and title

    var arrow_node;
    var is_left = (direction.toLowerCase()=='left');
    var which = is_left ? 'l' : 'r';
    var prev_or_next = is_left ? 'previous' : 'next';
    var year_or_month = is_list() ? 'year' : 'month';
    var arrow_text = prev_or_next+' '+year_or_month;
    var inc = is_left ? -1 : 1;
    var toggle = (is_list() &&  !is_desktop()) ? 'javascript:toggle_year' : 'javascript:toggle_month';
    toggle += '('+inc+')';
    var arrow_id = is_left ? 'agi-larrow' : 'agi-rarrow';
    var anchor_class = is_left ? 'agi-montharrow-l' : 'agi-montharrow-r';
    var anchor_or_spacer = '';

    //if <= 1/2005, do not show left arrow
    if(is_left)
    {
        if(c_obj.year < 2005 || (is_calendar() && c_obj.year==2005 && c_obj.month==JANUARY))
            anchor_or_spacer = make_spacer(arrow_id);
    }
    //build arrow
    if(empty_val(anchor_or_spacer))
    {
        anchor_or_spacer =
            make_node('a',{'id':arrow_id,
                           'href':toggle,
                           'title':arrow_text,
                           'class':anchor_class},
                make_node('div',{'class':'agi-montharrow'}));
    }
    arrow_node = make_node('div',{'class':'agi-left'},anchor_or_spacer);
    return arrow_node;
}

function make_spacer(spacer_id)
{
    //create an empty div to take place of arrow
    spacer_id = spacer_id ? spacer_id : '';
    var spacer = make_node('div',{'class':'agi-montharrow', 'id':spacer_id});
    return spacer;
}

function remove_navigation()
{
    // disable/hide arrows
    var spacer = make_spacer();
    var larrow = document.getElementById('agi-larrow');
    var rarrow = document.getElementById('agi-rarrow');
    var larrow_parent = larrow.parentNode;
    var rarrow_parent = rarrow.parentNode;

    larrow_parent.parentNode.replaceChild(spacer,larrow_parent);
    rarrow_parent.parentNode.replaceChild(spacer,rarrow_parent);

    // disable/hide navigational links
    document.getElementById('today').removeAttribute('onclick');
    document.getElementById('today').removeAttribute('href');
    document.getElementById('today').style.visibility = 'hidden';
    document.getElementById('cview').removeAttribute('onclick');
    document.getElementById('cview').removeAttribute('href');
    document.getElementById('lview').removeAttribute('onclick');
    document.getElementById('lview').removeAttribute('href');
    document.getElementById('tview').style.visibility = 'hidden';
}

function set_common_vars()
{
    cvars = new Object();

    //set the desired month
    cvars.desired_date    = new Date(c_obj.year, c_obj.month-1, 1);
    cvars.total_days      = c_obj.days_in_months[c_obj.month];
    cvars.first_weekday   = cvars.desired_date.getDay();

    return cvars;
}

function edit_event(event_id, month, day, year)
{
    var base_url,lb_map;
    var edit_parms = 'id='+event_id+'&month='+month+'&day='+day+'&year='+year;
    if (is_toolbar()) {
        base_url = ahost+'/desktop/event_viewedit.pd?' + edit_parms;
        lb_map = {width:525,height:525,position:'user',left:0,top:0};
    }
    else if (is_desktop()) {
        base_url = ahost+'/desktop/event_viewedit.pd?' + edit_parms;
        lb_map = {width:525,height:428,position:'user',left:0,top:0};
    } else {
        base_url = ahost+'/reminders/event_viewedit.pd?' + edit_parms;
        lb_map = {width:650};
    }
    //var edit_parms = 'id='+event_id+'&month='+month+'&day='+day+'&year='+year;
    //lightbox(base_url,{params:edit_parms,width:650});
    lightbox(base_url,lb_map);
}

//////////////////////////////////////////////
// __Utility functions                      //
//////////////////////////////////////////////

function is_calendar()
{
    return (c_obj.type=='calendar');
}

function is_list()
{
    return (c_obj.type=='list');
}

function is_today(m,d,y)
{
    return ( d==todays_day && m==todays_month && y==todays_year );
}

function empty_events()
{
    var i = 0;
    for(i in overall_events)
        i++;
    return (i<1);
}

function clear_nodes(which)
{
    //remove all children for a given node
    var container = document.getElementById(which);
    var children = container.childNodes;
    for(var i=children.length-1; i>=0; i--)
        container.removeChild(children[i]);
}

function format_name(name)
{
    //empty or non-existent name
    if(!name)
        return make_text('');
    //'<br>' not present
    if(name.toLowerCase().indexOf('<br>')==-1)
        return make_text(name);

    //split names, create <br> node to separate each name
    var names = name.split('<br>');
    var res = [];
    for(var i=0; i<names.length; i++)
    {
        res.push(make_text(names[i]));
        if(i<(names.length-1))
            res.push(make_node('br'));
    }
    return res;
}

function refresh_curr_view(){
    c_obj.create_fn(c_obj.month, c_obj.year);
}

function empty_val(val)
{
    return isEmpty(trim(String(val)));
}

function make_edit_parms(event)
{
    //build up parms for edit link
    var id = Number(event.id);
    var month = Number(event.month_start);
    var day = Number(event.day_start);
    var year = Number(event.year_start);
    var parm_string = id+','+month+','+day+','+year;
    return parm_string;
}

function get_date(counter, first_weekday, total_days)
{
    var month = c_obj.month;
    var year = c_obj.year;
    var day = counter - first_weekday;
    var day_object = {};
    var ret;

    //day falls in previous month
    if(day<=0)
    {
        ret = adjust_date(month, year, -1);
        month = ret.month;
        year = ret.year;
        day = c_obj.days_in_months[month] + day;
    }
    //day falls in next month
    else if(day > total_days)
    {
        ret = adjust_date(month, year, 1);
        month = ret.month;
        year = ret.year;
        day = day - total_days;
    }
    day_object.day = day;
    day_object.month = month;
    day_object.year = year;
    return day_object;
}

function print_desktop_list() {
    var win=null;
    elem1 = document.getElementById('agd-remNavTop');
    elem2 = document.getElementById('agi-remcontent');
    if (elem1 && elem2) {
        win = window.open();
        self.focus();
        if (win) {
            win.document.open();
            win.document.write('<link rel="stylesheet" type="text/css" href="'+imghost+'/css/van/lightbox.css" />');
            win.document.write('<link rel="stylesheet" type="text/css" href="'+imghost+'/css/agbeta/agi_base.css" />');
            win.document.write('<link rel="stylesheet" type="text/css" href="'+imghost+'/css/agbeta/agi_desktop.css" />');
            list_html =  "<div id='agi-cal-or-list'>";
            list_html += "<div id='agi-list'>";
            list_html += elem1.outerHTML;
            list_html += elem2.outerHTML;
            list_html += '</div' + '>';
            list_html += '</div' + '>';
            list_html = list_html.replace(/agi-remcontent/i,'agi-remcontent-print');
            win.document.write(list_html);
            win.document.close();
            win.print();
            win.close();
        }
    } else {
        alert('Error occurred printing reminder list.  You may need to disable pop-up blocking.');
    }
}


//////////////////////////////////////////////
// __Demo Functions                         //
//////////////////////////////////////////////

function set_demo()
{
    //set session cookie for demo user
    request = new Requester([ahost]+'/reminders/set_demo.pd','GET',true,true);
    request.onsuccess = set_demo_success;
    request.onerror = set_demo_explosion;
    request.sendRequest('');
}

function set_demo_success(req)
{
    demo_user = true;
    hideLightbox();
}

function set_demo_explosion(req)
{
    hideLightbox();
}
