var Grade = {

	reportCard : false,

	setup : function(){
		$$('a#submitGrade').each(function(el, i){
			el.observe( 'click', function(e){
				Event.stop(e);
				Grade.submitGrade();
			})
		});
		$$('a#clickToViewReportCard').each(function(el, i){
			el.observe( 'click', function(e){
				Event.stop(e);
				$$('#popupViewReportCard p').first().innerHTML = GradeText.view_report_card;
				Grade.popup('popupViewReportCard', 270, $('selectGrade').cumulativeOffset().left - 40);
			})
		});
		$$('#overlay').each(function(el){
			el.observe('click', function(e){ Grade.popupHide(); })
		});
		$$('a.popupClose').each(function(el){
			el.observe('click', function(e){
				Event.stop(e);
				Grade.popupHide();
			});
		});
		$$('#comments > div.commentBox').each(function(el, i){
			Grade.truncateDesc(el.select('p.commentDesc').first());
		});
		$$('a#submitMainComment').each(function(el, i){
			el.observe( 'click', function(e){
				Event.stop(e);
				Grade.validateAddComment(e);
			})
		});
		$$('a#moreInfo').each(function(el, i){
			el.observe( 'click', function(e){
				Event.stop(e);
				$('popupMoreInfo').setStyle({ height : '525px' });
				$('extendedRulesText').hide();			
				Grade.popup('popupMoreInfo', 525);
			})
		});
		$$('#comments').each(function(el, i){
			Grade.startCommentScroll();
		});
		$$('div.commentBox').each(function(el,i){
			el.observe('click', function(e){
				Event.stop(e);
				Grade.stopScroll();
			});
		});
		$$('#extendedRules').each(function(el,i){
			el.observe('click', function(e){
				Event.stop(e);
				if ( $('extendedRulesText').visible()){
					$('popupMoreInfo').morph ( 'height : 525px' );
					Effect.BlindUp('extendedRulesText');
				} else {
					$('popupMoreInfo').morph ( 'height : 700px' );
					Effect.BlindDown('extendedRulesText');
				}

			});
		});
	},
	
	// submit a grade
	submittingGrade : false,
	submitGrade : function() {
	
		if( Form.serialize('selectGrade') == '' ) {
			$('errorMessage').innerHTML = GradeText.no_grade;
			Grade.popup('popupError', 125);
			return;
		}
	
		if ( Grade.submittingGrade === true )
			return;
			
		Grade.submittingGrade = true;
		
		$('selectGrade').request ({
			onComplete: function(t){
				if ( t.responseText === 'success' ) {
					if ( Grade.reportCard === false ) {
						$$('#popupViewReportCard p').first().innerHTML = GradeText.grade_success;
						Grade.popup('popupViewReportCard', 305, $('selectGrade').cumulativeOffset().left - 40);					
					} else {
						Grade.showReportCard();
					}
				} else {
					$('errorMessage').innerHTML = t.responseText;
					Grade.popup('popupError', 125);
				}
				
				Grade.submittingGrade = false;
			}
		});
	},
	
	// get the average grade then show the report card
	showReportCard : function() {
		new Ajax.Request (siteURL + 'grade/ajax/av_grade', {
			method : 'post',
			onComplete : function (t) {
				var grade = t.responseText;
				$$('#selectGrade input').each(function(el, i){
					if ( i == grade ) {
						var pos = el.positionedOffset();
						$('avGrade').setStyle({ left : pos.left + 'px' });
					}
				});
				var grades = ['A','B','C','D','F'];
				$('avGradeText').innerHTML = grades[grade];
				$('reportCard').appear();	
			}	
		});
	},
		
	// show a popup
	popup : function ( content, height, x, y ) {
		// get the popup as a DOM element
		var popup = $(content);

		// remove any existing error tips
		$$('.errorTip').each ( function(el, i){
			el.remove();
		});

		// set a default for the height if not specified
		if ( !(height > 0) )
			height = 300;
		
		// set the height of the popup
		popup.setStyle({ 'height' : height.toString() + 'px' });
		
		// show the overlay 
		$('overlay').appear({ duration: 0.75, from: 0, to: 0.65 });
		
		// get the viewport dimensions
		var vpDims = document.viewport.getDimensions();
		var vpScroll = document.viewport.getScrollOffsets();
		
		// get the popup dimensions
		var pDims = popup.getDimensions();
		
		if ( !(x > 0) )
			x = Math.round(vpDims.width/2 - pDims.width/2).toString();
		if ( !(y > 0) )
			y = Math.round(vpDims.height/2 - pDims.height/2 + vpScroll.top).toString();
				
		// center the popup
		popup.setStyle({
			'top' : y + 'px',
			'left' : x + 'px'
		});
		
		// show the popup
		popup.appear({ duration : 1 });
	},
	
	// hide all open popups
	popupHide : function(){
		$$('.errorTip').each ( function(el, i){ el.remove() });	
		$$('div.popup').each(function(el, i){ el.fade({ duration: 0.3 }) });
		$('overlay').fade( { duration : 0.3 });	
	},
	
	// validate the report card form
	validateReportCard : function (event)
	{
		Event.stop(event);
	
		$$('.errorTip').each ( function(el, i){
			el.remove();
		});
	
		if ( $F('rc_fname') == '' ) Grade.showErrorTip ( 'rc_fname', GradeText.no_fname );
		if ( $F('rc_lname') == '' ) Grade.showErrorTip ( 'rc_lname', GradeText.no_lname, 'top' );
		if ( $F('rc_email') == '' ) Grade.showErrorTip ( 'rc_email', GradeText.no_email );
		if ( !Grade.validEmail( $F('rc_email') ) ) Grade.showErrorTip ( 'rc_email', GradeText.invalid_email );
		if ( $F('rc_zip') == '' ) Grade.showErrorTip ( 'rc_zip', GradeText.no_zip, 'top' );

		var tips = $$('.errorTip');
		
		if ( tips.length > 0 )
			return false;
		else {
			$('viewReportCard').request({
  				onComplete: function(t){ 
  					Grade.popupHide();
  					if ( t.responseText == 'success' ){
  						Grade.reportCard = true;
  						Grade.showReportCard();
  					} else {
						$('errorMessage').innerHTML = t.responseText;
						Grade.popup('popupError', 150);
  					}
  				}
			});
		}
	},
	
	// process the comments form
	validateAddComment : function(event) {
		Event.stop(event);
	
		$$('.errorTip').each ( function(el, i){
			el.remove();
		});
	
		if ( $F('fname') == '' ) Grade.showErrorTip ( 'fname', GradeText.no_fname );
		if ( $F('lname') == '' ) Grade.showErrorTip ( 'lname', GradeText.no_lname, 'top' );
		if ( $F('email') == '' ) Grade.showErrorTip ( 'email', GradeText.no_email );
		if ( !Grade.validEmail( $F('email') ) ) Grade.showErrorTip ( 'email', GradeText.invalid_email );
		if ( $F('zip') == '' ) Grade.showErrorTip ( 'zip', GradeText.no_zip, 'top' );
		if ( $F('comment') == '' ) Grade.showErrorTip ( 'comment', GradeText.no_comment );

		var tips = $$('.errorTip');
		
		if ( tips.length > 0 )
			return false;
		else {
			$('mainCommentBox').request({
  				onComplete: function(t){ 
  					if ( t.responseText == 'success' ){
						$('errorMessage').innerHTML = GradeText.comment_success;
						Grade.popup('popupError', 200);
  					} else {
						$('errorMessage').innerHTML = t.responseText;
						Grade.popup('popupError', 150);
  					}
  				}
			});
		}
	},

	// process the reply form
	validateReply : function(event) {
		Event.stop(event);
	
		$$('.errorTip').each ( function(el, i){
			el.remove();
		});
	
		if ( $F('ar_fname') == '' ) Grade.showErrorTip ( 'ar_fname', GradeText.no_fname );
		if ( $F('ar_lname') == '' ) Grade.showErrorTip ( 'ar_lname', GradeText.no_lname, 'top' );
		if ( $F('ar_email') == '' ) Grade.showErrorTip ( 'ar_email', GradeText.no_email );
		if ( !Grade.validEmail( $F('ar_email') ) ) Grade.showErrorTip ( 'ar_email', GradeText.invalid_email );
		if ( $F('ar_zip') == '' ) Grade.showErrorTip ( 'ar_zip', GradeText.no_zip, 'top' );
		if ( $F('ar_comment') == '' ) Grade.showErrorTip ( 'ar_comment', GradeText.no_comment );

		var tips = $$('.errorTip');
		
		if ( tips.length > 0 )
			return false;
		else {
			$('addReply').request({
  				onComplete: function(t){ 
  					$('popupAddReply').fade();
  					if ( t.responseText == 'success' ){
						$('errorMessage').innerHTML = GradeText.reply_success;
						Grade.popup('popupError', 200);
  					} else {
						$('errorMessage').innerHTML = t.responseText;
						Grade.popup('popupError', 150);
  					}
  				}
			});
		}
	},
	
	// test a string to see if it is a valid email
	validEmail: function ( email ){
		var pattern = /^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\.([a-zA-Z])+([a-zA-Z])+/;
    	return pattern.test( email )
	},
	
	// show the error tips
	showErrorTip: function ( element, error, align ){
		if ( align == '' || align == null ) align = 'left';	
		var newID = 'errorTip_' + $(element).id;
		if ( $(newID) ) return;
		
		var html = '<div id="' + newID + '" class="errorTip">' + error + '</div>';
		$$('body').first().insert( html );
		
		var pos = $(element).cumulativeOffset();

		switch ( align )
		{
			case 'left' :
				$(newID).setStyle({
					'top' : pos.top + 'px',
					'left' : pos.left - $(newID).getWidth() + 'px'
				});		
			break;
			case 'top' :
				$(newID).addClassName('top');
				$(newID).setStyle({
					'top' : (pos.top - $(newID).getHeight()) + 'px',
					'left' : pos.left + 'px'
				});		
			break;
		}
	},
	
	// truncate the comments
	commentDescs : {},
	truncateDesc : function(el) {
		var text = el.innerHTML;
		var commentBox = el.up().up();
		var commentID = commentBox.id;
		var replies = commentBox.select('.commentReplies .commentBox');
		if ( text.length < 275 && replies.length == 0 )
			commentBox.select('.commentMoreLink').first().remove();
		else {
			Grade.commentDescs[commentID] = text;
			el.innerHTML = text.truncate(275, ' ...');	
		}
	},
	
	// expand the comments
	commentDescDims : {},
	expandDesc : function(e) {
		Event.stop(e);
		Grade.stopScroll();
				
		var commentBox = Event.element(e).up().up();
		var expandBox = commentBox.select('.commentExpand').first();

		if ( !Grade.commentDescDims.hasOwnProperty(commentBox.id) )
			Grade.commentDescDims[commentBox.id] = { 'more' : 0, 'less' : 0 };
		
		if ( Grade.commentDescDims[commentBox.id].less == 0 )
			Grade.commentDescDims[commentBox.id].less = expandBox.getHeight();

		expandBox.setStyle({ height : expandBox.getHeight() + 'px' });
		
		var desc = commentBox.select('.commentDesc').first();
		var replies = commentBox.select('.commentReplies').first();
		var expand = false;
		
		if ( replies.visible() ){
			expand = false;
		} else {
			desc.innerHTML = Grade.commentDescs[commentBox.id];
			Event.element(e).innerHTML = '&uarr; view less';
			replies.show();
			expand = true;
		}
		
		if ( Grade.commentDescDims[commentBox.id].more == 0 )
			Grade.commentDescDims[commentBox.id].more = desc.getHeight() + replies.getHeight() + 15;
			
		if ( expand )
			expandBox.morph ( 'height : ' + Grade.commentDescDims[commentBox.id].more + 'px' );
		else {
			expandBox.morph ( 
				'height : ' + Grade.commentDescDims[commentBox.id].less + 'px',
				{
					afterFinish : function() {
						Grade.truncateDesc(desc);
						Event.element(e).innerHTML = '&darr; view more';
						replies.hide();					
					}
				} );
		}
		
	},
	
	// popup the reply window
	showReply: function (event) {
		Event.stop(event);
		var el = Event.element(event).up().up();
		var commenter = el.select('b').first().innerHTML;
		$('ar_comment').value = '@' + commenter + ': ';
		$('parent_comment').value = el.id.replace('comment_','');
		Grade.popup('popupAddReply', 475);
	},
	
	// start the scrolling of the comment box
	commentScrollPos : [],
	scroller : '',
	startCommentScroll : function() {
		// get the scroll positions for each of the boxes
		$$('#comments > div').each(function(el, i){
			Grade.commentScrollPos.push(el.positionedOffset().top);
		});
		
		// do nothing if there are not enough boxes
		if ( Grade.commentScrollPos.last() < $('comments').getHeight() )
			return;
		
		Grade.scroller = new PeriodicalExecuter(Grade.scrollComments,6);
	},
	
	currScroll : 0,
	scrollComments : function() {
		Grade.currScroll = Grade.currScroll + 1 >= Grade.commentScrollPos.length ? 0 : Grade.currScroll + 1;
		var dest = Grade.commentScrollPos[Grade.currScroll];
		var comments = $('comments');
		if ( dest > ( comments.scrollHeight - comments.getHeight()) )
			Grade.currScroll = 0;
		
		new Effect.ScrollVertical('comments',{ to: dest, duration: 1 });
	},
	
	stopScroll : function() {
		if ( Grade.scroller != '' )
			Grade.scroller.stop();	
	}

};

document.observe( 'dom:loaded', Grade.setup );


/**
* Language abstraction
*/
var GradeText = {
	'no_grade'			: 'Please select a grade to submit!',
	'grade_success' 	: 'Thanks for submitting your grade.<br />If you would like to see the full results thus far, please complete the fields below:',
	'view_report_card' 	: 'To view the results, please enter your details.',
	'no_fname' 			: 'First Name is required.',
	'no_lname' 			: 'Last Name is required.',
	'no_email' 			: 'An email is required.',
	'invalid_email' 	: 'Please enter a valid email address,',
	'no_zip' 			: 'Zip is required.',
	'no_comment'		: 'A comment is required.',
	'comment_success'	: 'Thank you for your comment!  It is currently being reviewed by a PAC staffer.  Check back soon.',
	'reply_success'		: 'Thank you for your reply!  It is currently being reviewed by a PAC staffer.  Check back soon.'
};


/**
* Extend the Effects object with a smooth vertical scrolling method
*/
Effect.ScrollVertical = Class.create();
Object.extend(Object.extend(Effect.ScrollVertical.prototype, Effect.Base.prototype), 
{
    initialize: function(element){
        if(typeof element == "string") {        
            this.element = $(element);
            if(!this.element){ throw(Effect._elementDoesNotExistError); }
        }
        var options = Object.extend({
            from: this.element.scrollTop || 0,
            to:   this.element.offsetHeight
        }, arguments[1] || {});
        this.start(options);
    },
    update: function(position) {
        this.element.scrollTop = position;
    }
});