/*
 * If you want to change data, you are in the wrong file.
 * Try schedule-data.js.
 */

// image link related globals
tutorImgFolder = 
"http://inst.eecs.berkeley.edu/~selfpace/img/tutors/fa09/"
blowupSuffix = ".jpg"
imageSuffix = "_small.jpg"
thumbSuffix = "_tiny.jpg"

// returns image of given size for tutor
function tutorImage(tutor, size) {
    return tutorImgFolder + tutor.imageName + "_" + size + ".jpg";
}

// returns a list of times given a string range
function timesBetween ( range ) {
    range = range.split ( "-" );
    t1 = range[0];
    t2 = range[1];
    // check if t1 is a halftime
    t1half = t1.indexOf ( ":" );
    t2half = t2.indexOf ( ":" );
    if ( t1half != -1 ) {
        // converts to number
        t1 = 1 * t1.substring ( 0, t1half ) + .5;
    } else {
        t1 = 1 * t1;
    }
    if ( t2half != -1 ) {
        // converts to number
        t2 = 1 * t2.substring ( 0, t2half ) + .5;
    } else {
        t2 = 1 * t2;
    }
    return _tbHelper ( t1, t2, [] );
}

function _tbHelper ( t1, t2, L ) {
    if ( t1 == t2 ) {
        return L;
    } else {
        if ( t1 % 1 > 0 ) {
            L.push ( parseInt ( t1 - .5 ) + "30" );
        } else {
            L.push ( t1.toString() );
        }
        if ( t1 > 12 ) {
            t1 = 1;
        } else {
            t1 += .5;
        }
        return _tbHelper ( t1, t2, L );
    }
}

function _tFormat ( timestr ) {
    if ( timestr.length <= 2 ) {
        return timestr + ":00";
    } else if ( timestr.length == 3 ) {
        return timestr.substring (0,1) + ":" + timestr.substring (1,3);
    } else if ( timestr.length == 4 ) {
        return timestr.substring (0,2) + ":" + timestr.substring (2,4);
    }
}

function tutorTimes ( tutor ) {
    timesDict = tutor.times;
    if ( ! timesDict._cachedTimes ) {
        timesList = [];
        for ( day in timesDict ) {
            timesDict[day].each ( function ( range ) {
                timesBetween ( range ).each ( function ( time ) {
                    timesList.push ( day + time );
                } );
            } );
        }
        timesDict._cachedTimes = timesList;
    }
    return timesDict._cachedTimes;
}

function classTimes ( cls ) {
    if ( ! cls._cachedTimes ) {
        timesList = [];
        // ONLY GETS SOLID TUTORS
        whoTutors ( cls, 'solid' ).each ( function ( tutor ) {
            timesList.extend ( tutorTimes ( tutor ) );
        } );
        cls._cachedTimes = timesList;
    }
    return cls._cachedTimes;
}

function whoTutors ( cls, type ) {
    if ( ! cls._cachedTutors ) {
        tutors = [];
        tutorsSolid = [];
        tutorsShaky = [];
        tutorsLearning = [];
        schedule.tutors.each ( function ( tutor ) {
            if ( tutor.classes.solid.contains ( cls.abbr ) ) {
                tutors.push ( tutor );
                tutorsSolid.push ( tutor );
            } else if ( tutor.classes.shaky.contains ( cls.abbr ) ) {
                tutors.push ( tutor );
                tutorsShaky.push ( tutor );
            } else if ( tutor.classes.learning.contains ( cls.abbr ) ) {
                tutors.push ( tutor );
                tutorsLearning.push ( tutor );
            }
        } );
        cls._cachedTutors = {
            'all' : tutors,
            'solid': tutorsSolid,
            'shaky': tutorsShaky,
            'learning': tutorsLearning
        };
    }
    return cls._cachedTutors[type];
}

function _highlightTutor ( tutor ) {
    tutorTimes ( tutor ).each ( function ( time ) {
        $(time).toggleClass ( "highlight" );
    } );
    tutor.classes.solid.each ( function ( cls ) {
        $('cls'+cls).toggleClass ( "highlight" );
    } );
    tutor.classes.learning.each ( function ( cls ) {
        $('cls'+cls).toggleClass ( "midlight" );
    } );
    tutor.classes.shaky.each ( function ( cls ) {
        $('cls'+cls).toggleClass ( "lowlight" );
    } );
}

function _highlightClass ( cls ) {
    classTimes ( cls ).each ( function ( time ) {
        $(time).addClass ( "highlight" );
    } );
    whoTutors ( cls, 'solid' ).each ( function ( tut ) {
        $('tut'+tut.abbr).toggleClass ( "highlight" );
    } );
    whoTutors ( cls, 'learning' ).each ( function ( tut ) {
        $('tut'+tut.abbr).toggleClass ( "midlight" );
    } );
    whoTutors ( cls, 'shaky' ).each ( function ( tut ) {
        $('tut'+tut.abbr).toggleClass ( "lowlight" );
    } );
}

function _clearHighlights ( ) {
    $$(".tabletime").removeClass ( "highlight" );
    $$(".tutor_sel").removeClass ( "highlight" );
    $$(".class_sel").removeClass ( "highlight" );
    $$(".tutor_sel").removeClass ( "midlight" );
    $$(".class_sel").removeClass ( "midlight" );
    $$(".tutor_sel").removeClass ( "lowlight" );
    $$(".class_sel").removeClass ( "lowlight" );
}

function showTutorImg ( e, abbr ) {
    if ( typeof Tooltip == "undefined" || !Tooltip.ready ) return;
    for ( tutor in schedule.tutors ) {
        tutor = schedule.tutors[tutor];
        if ( tutor.abbr == abbr ) {
            var img_src = tutorImage ( tutor, "small" );
            var content = '<img src="'+img_src+'"></img>';
            Tooltip.show(e, content);
            break;
        }
    }
}
function hideTutorImg ( e, abbr ) {
    if ( typeof Tooltip == "undefined" || !Tooltip.ready ) return;
    Tooltip.hide();
}

function generateSchedule ( ) {
    // generate table rows and elements programmatically
    var elTable = $( 'schedule_matrix' );
    var elTBody = new Element ( 'tbody' ).inject ( elTable );
    var elHeader = new Element ( 'tr' ).inject ( elTBody );
    new Element ( 'th' ).setText ( "Time" ).inject ( elHeader );
    new Element ( 'th' ).setText ( "Monday" ).inject ( elHeader );
    new Element ( 'th' ).setText ( "Tuesday" ).inject ( elHeader );
    new Element ( 'th' ).setText ( "Wednesday" ).inject ( elHeader );
    new Element ( 'th' ).setText ( "Thursday" ).inject ( elHeader );
    new Element ( 'th' ).setText ( "Friday" ).inject ( elHeader );
    timesBetween ( scheduleBounds ).each ( function ( t ) {
        var elRow = new Element ( 'tr' ).inject ( elTBody );
        new Element ( 'th' ).setText ( _tFormat ( t ) ).inject ( elRow );
        m = new Element ( 'td' );
        m.setProperty ( 'id', 'm' + t ).addClass ( 'tabletime' ).inject ( elRow );
        tu = new Element ( 'td' );
        tu.setProperty ( 'id', 'tu' + t ).addClass ( 'tabletime' ).inject ( elRow );
        w = new Element ( 'td' );
        w.setProperty ( 'id', 'w' + t ).addClass ( 'tabletime' ).inject ( elRow );
        th = new Element ( 'td' );
        th.setProperty ( 'id', 'th' + t ).addClass ( 'tabletime' ).inject ( elRow );
        f = new Element ( 'td' );
        f.setProperty ( 'id', 'f' + t ).addClass ( 'tabletime' ).inject ( elRow );
    } );
    // this is a shared lock for the entire set of tutors and classes; locking
    // on one tutor/class means that no other tutors/classes can change the
    // highlight when moused over
    // this particular loop over tutors creates the list of tutors on the lhs
    lock = null;
    schedule.tutors.each ( function ( tutor ) {
        tutorTimes ( tutor ).each ( function ( time ) {
            $(time).appendText ( " " + tutor.abbr + " " );
        } );
        // this clump of code creates the hover image in addition to
        // the regular text
        tutor_sel = new Element ( 'div' );
        tutor_pic = new Element ( 'img' );
        //tutor_pic_lnk = new Element ( 'a' );
        tutor_name = new Element('p');
        tutor_sel.addClass ( 'tutor_sel' );
        tutor_sel.setProperty ( 'id', 'tut'+tutor.abbr );
        tutor_sel.addClass ( 'featurebox_side' );
        tutor_sel.inject ( 'left_side' );
        tutor_pic.setProperty ( 'src', tutorImage ( tutor, "tiny" ) );
        tutor_pic.setProperty ( 'onmouseover', 'showTutorImg(event,"'+tutor.abbr+'")' );
        tutor_pic.setProperty ( 'onmouseout',  'hideTutorImg(event,"'+tutor.abbr+'")' );
        tutor_pic.setProperty ( 'href',  '#' );
        tutor_pic.injectInside ( tutor_sel );
        tutor_name.setText ( " " + tutor.abbr + " / " + tutor.name );
        tutor_name.injectAfter ( tutor_pic );
        // stores the mouse state
        over = false;
        fover = function () { 
            over = true;
            if ( ! lock ) {
                _highlightTutor ( tutor );
            }
        };
        fout = function () {
            over = false;
            if ( ! lock ) {
                _clearHighlights ();
            }
        };
        fclick = function () { 
            abbr = 'tut'+tutor.abbr;
            if ( lock == abbr ) {
                lock = null;
                $(abbr).removeClass ( "highlight" );
            } else {
                if ( lock ) $(lock).removeClass ( "highlight" );
                lock = abbr;
                _clearHighlights ();
                _highlightTutor ( tutor );
                $(abbr).addClass ( "highlight" );
            }
        };
        tutor_sel.onmouseover = fover;
        tutor_sel.onmouseout = fout;
        tutor_sel.onmousedown = fclick;
    } );
    // this particular loop over classes creates the list of classes on the lhs
    classdb.classes.each ( function ( cls ) {
        class_sel = new Element ( 'div' );
        class_pic = new Element ( 'img' );
        class_name = new Element ( 'span' ).setText ( "CS" +
                                                      cls.abbr + " / " +
                                                      cls.name );;
        class_sel.addClass ( 'class_sel' ).addClass ( 'featurebox_side' );
        class_sel.setProperty ( 'id', 'cls'+cls.abbr );
        class_sel.inject ( 'right_side' );
        class_pic.setProperty ( 'src', "http://inst.eecs.berkeley.edu/~selfpace/img/16x16/report.png" );
        class_pic.injectInside ( class_sel );
        class_name.injectAfter ( class_pic );
        // stores the mouse state
        
        fover = function () { 
            over = true;
            if ( ! lock ) {
                _highlightClass ( cls );
            }
        };
        fout = function () {
            over = false;
            if ( ! lock ) {
                _clearHighlights ();
            }
        };
        fclick = function () { 
            abbr = 'cls'+cls.abbr;
            if ( lock == abbr ) {
                // unlock!
                lock = null;
                $(abbr).removeClass ( "highlight" );
            } else {
                // lock!
                if ( lock ) $(lock).removeClass ( "highlight" );
                lock = abbr;
                _clearHighlights ();
                _highlightClass ( cls );
                $(abbr).addClass ( "highlight" );
            }
        };
        class_sel.onmouseover = fover;
        class_sel.onmouseout = fout;
        class_sel.onmousedown = fclick;
    } );
    allTimes = timesBetween ( scheduleBounds );
    textSched = [];
    for (day in schedule.hours ) {
        textSched.push ( day.toUpperCase() + ': ' + schedule.hours[day] );
        schedule.hours[day].each ( function ( range ) {
            openTimes = timesBetween ( range );
            allTimes.each ( function ( time ) {
                if ( ! openTimes.contains ( time ) ) {
                    $(day+time).appendText ( "[closed]" ).addClass ( 'closed' );
                }
            } );
        } );
    };
    // generate textual schedule
    $('schedule_desc').setText ( textSched.join ( ', ' ) )
}
