// global array to cache subject photos, could be shared by all js scripts
// sPhotos[id]['url']

if (!window.sPhotos) {
    window.sPhotos = new Array();
}

window.ratingsTimeout	= '';	// holds timeout IDs for animations
window.ratingsRate	= 225;	// ms
window.ratingsStep	= 50;	// px


RatingsView = function(sel, instanceName) {
    this.currSortField 		= 'RATING_DATE';
    this.currFirst		= 1;
    this.sortAscending		= true;
    this.origHtml 		= '';
    this.pageSize		= 40;
    this.lastPage		= false;

    // ratings page cache, like: this.cache[sortField][0|1][first] where 0 or 1 represents sortAscending

    this.cache				= new Array();
    this.cache['SUBJECT_NAME']		= new Array();
    this.cache['CRITERION_NAME']	= new Array();
    this.cache['ROLE_NAME']		= new Array();
    this.cache['RATING_SCORE']		= new Array();
    this.cache['RATING_DATE']		= new Array();
    this.cache['SUBJECT_NAME'][1]	= new Array();
    this.cache['CRITERION_NAME'][1]	= new Array();
    this.cache['ROLE_NAME'][1]		= new Array();
    this.cache['RATING_SCORE'][1]	= new Array();
    this.cache['RATING_DATE'][1]	= new Array();
    this.cache['SUBJECT_NAME'][0]	= new Array();
    this.cache['CRITERION_NAME'][0]	= new Array();
    this.cache['ROLE_NAME'][0]		= new Array();
    this.cache['RATING_SCORE'][0]	= new Array();
    this.cache['RATING_DATE'][0]	= new Array();

    this.getRatings	= function() {

	if (this.sortAscending) {
	    ascIndex = 1;
	}
	else {
	    ascIndex = 0;
	}
	// if not already cached, get ratings and cache them

	if (!this.cache[this.currSortField][ascIndex][this.currFirst]) {

	    ajaxUrl	= GLOBALS['contextPath'] + '/ajax/loadRatings';

	    if (sel == '#ratingsBy') {
		ajaxUrl	+= '?bySubject';
	    }
	    else {
		ajaxUrl += '?ofSubject';
	    }

	    ajaxUrl	+= '&subjectId='		+ GLOBALS['sid']
			+ '&sortField='		+ this.currSortField
			+ '&pageSize='		+ this.pageSize
			+ '&first='		+ this.currFirst
			+ '&sortAscending='	+ String(this.sortAscending);

	    ajaxResults = new Array();

	    $.ajax({
		url:		ajaxUrl,
		async:		false,
		type:		'GET',
		dataType:	'json',
		success:	function(arg) {
		    ajaxResults = arg['ratings'];
		},
		error:		function(arg) {
		    ;
		}
	    });

	    // cache the results

	    this.cache[this.currSortField][ascIndex][this.currFirst] = ajaxResults;
	}

	// get ratings from cache

	theRatings = this.cache[this.currSortField][ascIndex][this.currFirst];

	rNuHtml	= '';

	for (i=0; i< theRatings.length; i++) {

	    dateObj = new Date(theRatings[i]['whenUpdated']);
//	    theDate = dateObj.getMonth() + '/' + dateObj.getDate() + '/' + dateObj.getFullYear().toString().slice(-2);
        theDate = (dateObj.getMonth() + 1) + '/' + dateObj.getDate() + '/' + dateObj.getFullYear().toString().slice(-2);

	    // start build output

	    if (theRatings[i]['comments']) {
		theComments = theRatings[i]['comments'];
	    }
	    else {
		theComments = '';
	    }

	    rNuHtml += '<tr>';

	    // ratings by or ratings of?

	    if (sel == '#ratingsBy') {
		rNuHtml += '<td class="peopleLink" name="' + theRatings[i]['subjectId'] + '" id="rbId_' + i + '"><a href="' + GLOBALS.contextPath + '/viewSubject/' + theRatings[i]['subjectId'] + '"><span class="peopleLink">' + theRatings[i]['subjectName'] + '<span class="frHover"></span></span></a></td>';
	    }
	    else {
		rNuHtml += '<td class="peopleLink" name="' + theRatings[i]['raterId'] + '" id="rbId_' + i + '"><a href="' + GLOBALS.contextPath + '/viewSubject/' + theRatings[i]['raterId'] + '"><span class="peopleLink">' + theRatings[i]['raterName'] + '<span class="frHover"></span></span></a></td>';
	    }

        rNuHtml +=	'<td class="criterion" title="' + theComments + '"><em>' + theRatings[i]['criterionName'] + '</em>';
        if (theRatings[i]['type'] == 'REVIEW') {
            rNuHtml += ' for review of <a href="' + GLOBALS.contextPath + '/viewSubject/' + theRatings[i]['rateable']['subjectId'] + '"><span class="peopleLink">' + theRatings[i]['rateable']['subjectName'] + '</span></a></td>';
        }
        else {
            rNuHtml += '</td>';
        }
        rNuHtml += '<td class="roleFont" title="' + theComments + '">' + theRatings[i]['roleName'] + '</td>' +
                   '<td class="score" title="' + theComments + '">' + theRatings[i]['value'] + '</td>' +
                   '<td class="date" title="' + theComments + '">' + theDate + '</td>' +
                   '</tr>';

//	    rNuHtml +=	'<td class="criterion" title="' + theComments + '"><em>' + theRatings[i]['criterionName'] + '</em></td>' +
//			'<td class="roleFont" title="' + theComments + '">' + theRatings[i]['roleName'] + '</td>' +
//			'<td class="score" title="' + theComments + '">' + theRatings[i]['value'] + '</td>' +
//			'<td class="date" title="' + theComments + '">' + theDate + '</td>' +
//		    '</tr>';

	    // get / cache photos

	    if (typeof window.sPhotos[theRatings[i]['subjectId']] == 'undefined') {
		$.ajax({
		    url:	GLOBALS['contextPath'] + '/ajax/getRandomSubjectImage?subjectId=' + theRatings[i]['subjectId'],
		    type:	'GET',
		    dataType:	'json',
		    success:	function(imgArg) {

			// cache url

			window.sPhotos[theRatings[i]['subjectId']] = new Array();
			window.sPhotos[theRatings[i]['subjectId']]['url'] = imgArg['imageUrl'];

			// apply url as image src

			$(sel + ' .rTable .peopleLink img.' + theRatings[i]['subjectId']).attr('src', imgArg['imageUrl']);

		    },
		    error:	function() {
			;
		    }
		});
	    }
	    else {
		$(sel + ' .rTable .peopleLink img.' + theRatings[i]['subjectId']).attr('src', window.sPhotos[theRatings[i]['subjectId']]);
	    }
	}

	// output

	if (this.currFirst > 1) {
	    $(sel + ' .rTable').append(rNuHtml);
	}
	else {
	    $(sel + '.scrollInner').css('top', 0);
	    $(sel + ' .rTable').html(rNuHtml);
	}

	// header row same widths as data rows below

	hRow = $(sel + ' .rHeader th:lt(2)');
	dRow = $(sel + ' .rTable tr:eq(0) td');

	for (i=0; i<hRow.length; i++) {
	    $(hRow[i]).width($(dRow[i]).width());
	}

	// show/hide pics

	$(sel + ' .rTable td.peopleLink').mouseover(function(){

	    daEl = $(this);

	    daEl.find('.frHover').css({
		'position':	'absolute',
		'top':	daEl.position().top,
		'left':	daEl.position().left + 100,
		'z-index':	20000,
		'display':	'block'
	    });

	    // calculate and set dimensions to display

	    maxWidth	= 100;
	    maxHeight 	= 100;

	    dispWidth	= daEl.find(' span.frHover img').width();
	    dispHeight	= daEl.find(' span.frHover img').height();

	    ratio	= dispWidth / dispHeight;

	    if (dispWidth > maxWidth) {
		dispWidth	= maxWidth;
		dispHeight	= dispWidth / ratio;
	    }

	    if (dispHeight > maxHeight) {
		dispHeight	= maxHeight;
		dispWidth	= dispHeight * ratio;
	    }

	    daEl.find(' span.frHover img').width(dispWidth);
	    daEl.find(' span.frHover img').height(dispHeight);
	});

	$(sel + ' .rTable td.peopleLink').mouseout(function(){
	    $(sel + ' .rTable .frHover').hide();
	})

	// number of results is used to detect last page

	if (theRatings.length < this.pageSize){
	    this.lastPage = true;
	}

    }

    this.show		= function() {

	// remember initial view

	this.origHtml = $(sel + ' .rSummary').html();

	// output table shell

	$(sel + ' .rSummary').html('<table class="rHeader">' +
					    '<tr>' +
						'<th class="peopleLink"><span class="sortH" onClick="' + instanceName + '.sortH(' + "'SUBJECT_NAME'" + ', this)"><span>' + 'Name' + '</span></span></th>' +
						'<th class="criterion"><span class="sortH" onClick="' + instanceName + '.sortH(' + "'CRITERION_NAME'" + ', this)"><span>' + 'criterion' + '</span></span></th>' +
						'<th class="roleFont"><span class="sortH" onClick="' + instanceName + '.sortH(' + "'ROLE_NAME'" + ', this)"><span>' + 'Role' + '</span></span></th>' +
						'<th class="sd" style="font-size:0.9em"><span class="sortH" onClick="' + instanceName + '.sortH(' + "'RATING_SCORE'" + ', this)"><span class="score">' + 'score' + '</span></span>' +
						'<span class="sortH" onClick="' + instanceName + '.sortH(' + "'RATING_DATE'" + ', this)"><span class="date">' + 'date' + '</span></span></th>' +
					    '</tr>' +
					'</table>' +
					'<div class="scrollOuter"><div class="scrollInner"><table class="rTable"></table></div></div>');
	// get initial data

	this.currFirst = 1;
	this.getRatings();

	// take up more space

	$(sel).css({
	    'margin-left': 0,
	    'width':	280
	});

	// limit display area + add scrolling if results large enough

	if ($(sel + ' .rTable').height() > 370) {
	    $(sel + ' .scrollOuter').css({
		'height':	370,
		'position':	'relative',
		'overflow':	'hidden'
	    });
	    $(sel + ' .scrollInner').css({
		'position':	'absolute'
	    });
	    $(sel + ' .scrollButtons').html('<div class="upDiv"></div><div class="downDiv"><img src="' + GLOBALS['contextPath'] + '/js/assets/downArrow-17x5.png" border="0" name="down" class="down" /></div>');

	    // bind events to scroll buttons

	    $(sel + ' .scrollButtons img[name=down]').mouseover(function(){
		eval (instanceName + '.moveDown()');
	    });

	    $(sel + ' .scrollButtons img[name=down]').mouseout(function(){
		window.clearTimeout(window.ratingsTimeout);
	    });
	}
	else {
	    //$(sel + ' .rSummary').css('height', $(sel + ' .rTable').height());
	}

	// set toggle

	theOrig	= this.origHtml;
	hideFn	= this.hide;

	$(sel + ' .rToggle').unbind().click(hideFn);
	$(sel + ' .rToggle .moreLess').html('hide');

	// header row same widths as data rows below

	hRow = $(sel + ' .rHeader th:lt(2)');
	dRow = $(sel + ' .rTable tr:eq(0) td');

	for (i=0; i<hRow.length; i++) {
	    $(hRow[i]).width($(dRow[i]).width());
	}

	// add sort indicator

	if (this.sortAscending) {
	    theClass = 'headerSortDown';
	}
	else {
	    theClass = 'headerSortUp';
	}

	switch (this.currSortField) {
	    case 'SUBJECT_NAME':
		sortEl = $(sel + ' .rHeader .peopleLink');
		break;
	    case 'CRITERION_NAME':
		sortEl = $(sel + ' .rHeader .criterion');
		break;
	    case 'ROLE_NAME':
		sortEl = $(sel + ' .rHeader .roleFont');
		break;
	    case 'RATING_SCORE':
		sortEl = $(sel + ' .rHeader .sortH:eq(3)');
		break;
	    case 'RATING_DATE':
		sortEl = $(sel + ' .rHeader .sortH:last');
		break;
	}

	sortEl.addClass(theClass);

	// set values for move functions

	this.rInnerEl		= $(sel + ' .scrollInner');
	this.rOuterHeight 	= this.rInnerEl.parent().height();
	this.rInnerHeight	= this.rInnerEl.height();
	this.rInnerTop		= parseInt(this.rInnerEl.css('top').slice(0,-2));
	this.rTopLimit		= - (this.rInnerHeight - this.rOuterHeight);


	// start loading pics

	$(sel + ' .rTable td.peopleLink').each(function(){

	    $.ajax({
		url:	GLOBALS['contextPath'] + '/ajax/getRandomSubjectImage?subjectId=' + $(this).attr('name') + '&rbId=' + $(this).attr('id'),
		type:	'GET',
		dataType:	'json',
		success:	function(imgArg) {

		    theSel 	= sel + this.url.replace(/^(.*)(={1})([0-9]*)(&rbId=)(.*)$/, ' #$5');

		    $(theSel + ' span.frHover').append('<img src="' + imgArg['imageUrl'] + '" />');

		},
		error:	function() {
		    ;
		}
	    });

	});
    }

    this.sortH		= function(nuField, trigEl) {

	// remove sort arrows

	$('.rHeader .sortH').attr('class', 'sortH');

	// do the sorting

	if (nuField == this.currSortField) {
	    this.sortAscending = !this.sortAscending;
	}
	else {
	    this.sortAscending = true;
	}

	this.currSortField = nuField;
	this.currFirst = 1;
	this.getRatings();

	// add sort arrow

	if (this.sortAscending) {
	    $(trigEl).addClass('headerSortDown');
	} else {
	    $(trigEl).addClass('headerSortUp');
	}

    }

    this.hide		= function() {

	// reset CSS

	$(sel).css({
	    'margin-left':	10,
	    'padding-left':	7,
	    'width':	200
	});

	// reset HTML

	$(sel + ' .rSummary').html(theOrig);

	// reset toggle

	$(sel + ' .rToggle').unbind().click(function(){
	    eval (instanceName + '.show()');
	});
	$(sel + ' .rToggle .moreLess').html('show all');

	// remove scroll arrows

	$(sel + ' .scrollButtons').html('');
    }

    this.moveDown	= function() {

	this.rInnerHeight	= this.rInnerEl.height();
	this.rInnerTop		= parseInt(this.rInnerEl.css('top').slice(0,-2));
	this.rTopLimit		= - (this.rInnerHeight - this.rOuterHeight);

	// add scroll up button if necessary

	if (!$(sel + ' .scrollButtons img.up').length){
	    $(sel + ' .scrollButtons div.upDiv').append('<img src="' + GLOBALS['contextPath'] + '/js/assets/upArrow-17x5.png" class="up" />');

	    $(sel + ' .scrollButtons img.up').mouseover(function(){
		eval(instanceName + '.moveUp();');
	    });

	    $(sel + ' .scrollButtons img.up').mouseout(function(){
		window.clearTimeout(window.ratingsTimeout);
	    });
	}

	// are we halfway down the list? time to retrieve more results

	if (this.rInnerTop <= this.rTopLimit / 2 && !this.lastPage) {
	    this.currFirst = this.currFirst + this.pageSize;
	    this.getRatings();
	}

	// scroll down

	if (this.rInnerTop > this.rTopLimit) {
	    if (Math.abs(this.rTopLimit - this.rInnerTop) < window.ratingsStep) {
		this.rInnerEl.css('top', this.rInnerTop -  Math.abs(this.rTopLimit - this.rInnerTop));
	    }
	    else {
		this.rInnerEl.css('top', this.rInnerTop - window.ratingsStep);
	    }

	    // repeat

	    window.clearTimeout(window.ratingsTimeout);
	    window.ratingsTimeout = window.setTimeout(instanceName + ".moveDown()", window.ratingsRate);
	}
	else {
	    if (window.ratingsTimeout) {
		window.clearTimeout(window.ratingsTimeout);
	    }
	}

    }

    this.moveUp		= function() {

	this.rInnerHeight	= this.rInnerEl.height();
	this.rInnerTop		= parseInt(this.rInnerEl.css('top').slice(0,-2));
	this.rTopLimit		= - (this.rInnerHeight - this.rOuterHeight);

	if (this.rInnerTop < 0) {
	    if (Math.abs(this.rInnerTop) < window.ratingsStep) {
		this.rInnerEl.css('top', this.rInnerTop + Math.abs(this.rInnerTop));
	    }
	    else {
		this.rInnerEl.css('top', this.rInnerTop + window.ratingsStep);
	    }

	    window.ratingsTimeout = window.setTimeout(instanceName + ".moveUp();", window.ratingsRate);
	}
	else {
	    if (window.ratingsTimeout) {
		window.clearTimeout(window.ratingsTimeout);
	    }
	}
    }
}

$(document).ready(function(){

    $('#ratingsBy .rToggle').unbind().click(function(){
	if (typeof ratingsViewBy == 'undefined') {
	    ratingsViewBy = new RatingsView('#ratingsBy', 'ratingsViewBy');
	}
	ratingsViewBy.show();
    });

    $('#ratingsOf .rToggle').unbind().click(function(){
	if (typeof ratingsViewOf == 'undefined') {
	    ratingsViewOf = new RatingsView('#ratingsOf', 'ratingsViewOf');
	}
	ratingsViewOf.show();
    });
});