// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults


// Run any necessary initializer code
var $j = jQuery.noConflict();
$j(document).ready(function(){
	PD.InlineHelp.initialize();
	PD.SearchBox.initialize();
	PD.PinRow.initialize();
})


var PD = {

	// some PD global vars
  
	discloseClosedImagePath: '/images/common/closed.png',
	discloseOpenedImagePath: '/images/common/opened.png',
	slideClosedImagePath: '/images/common/chevron_down.png',
	slideOpenedImagePath: '/images/common/chevron_up.png',

  InlineHelp: { // methods to support inline help system

		scoreExplanationVisible: false,

    initialize: function() { // find and add behavior to all a.inline_help_link hyperlinks
      
      // deactivate hrefs
  		$j('a.inline_help_link').click(function(){ return false; })
			
			// on mouse over the help link
			$j('a.inline_help_link').hover(function(){ 
				// get ready to position the help div, for now above the PARENT element to where the help button is
				abs_pos = PD.Util.findPos($j(this).parent().get(0))
				target_x = abs_pos.x; target_y = abs_pos.y;
				// insert and position the help div
				help_div_fragment = '<div id="help_div"><div id="help_div_content">Loading...</div></div>' 
				$j('body').prepend(help_div_fragment);
				help_h = $j('#help_div').height();
				$j('#help_div').css({
					left: target_x+"px",
					top: target_y-help_h+"px"
				}).fadeIn(200);
				// fetch the help content from the hyperlink's href, and on success reposition the help div
				$j.get(this.href, function(data){
					$j('#help_div_content').html(data);
					help_h = $j('#help_div').height();
					$j('#help_div').css({
						left: target_x+"px",
						top: target_y-help_h+"px"
					})
				});

			// on mouse out of the help link
			},function(){ 
        // zap it
  			$j('#help_div').remove();

  		})

    }, // end initialize

		initializeScoreHelp: function() { // set up the disclosure of the prose explanation for the overall scores
			// hide and style the answer
			$j('#overall_score_table #explanation #a').hide().css({position: 'absolute', width: '200px', background: 'white', 'z-index': 10});
			// convert the question into a toggle link
			$j('#overall_score_table #explanation #q').wrapInner('<a id="toggle_score_help" href="#"></a>').prepend('<img src="' + PD.discloseClosedImagePath + '" width="8" height="8" /> ').css({'cursor': 'pointer'});
			// click-enable the toggle link
			$j('#toggle_score_help').click(function(){
				PD.InlineHelp.scoreExplanationVisible = !PD.InlineHelp.scoreExplanationVisible;
				if (PD.InlineHelp.scoreExplanationVisible) {
					$j(this).prev().attr('src', PD.discloseOpenedImagePath);
					$j('#overall_score_table #explanation #a').slideDown(250);
				} else {
					$j(this).prev().attr('src', PD.discloseClosedImagePath);
					$j('#overall_score_table #explanation #a').slideUp(250);
				}
				return false;
			});
		}, // end initializeScoreHelp

		initializeUpcomingVoteReasons: function() { // set up the popdown for vote reasons on the meetings/show_upcoming page
			// hide the reasons
			$j('tr.vote_reason').hide()
			$j('.vote_reason_link').css({ // style the vote positions which have reasons
				'color': '#5fafd1',
				'border-bottom': 'dotted 1px #5fafd1',
				'cursor': 'pointer'
			}).click(function() { // click-enable the vote positions
				voter_id = $j(this).get(0).id.replace(/vote_\d+_voter_/, '');
				proposal_id = $j(this).parent().parent().get(0).id.replace(/proposal_/, '');
				reason_id = "reason_" + proposal_id + "_" + voter_id;
				$j('#'+reason_id).toggle();
				return false;
			})
		}, // end initializeUpcomingVoteReasons

		initializeVoteReasons: function() { // set up the popdown for vote reasons on the proposals/show page
			// hide the reasons
			$j('tr.vote_reason').hide()
			$j('.vote_reason_link').css({ // style the vote positions which have reasons
				'color': '#5fafd1',
				'border-bottom': 'dotted 1px #5fafd1',
				'cursor': 'pointer'
				}).click(function() { // click-enable the vote positions
					voter_id = $j(this).get(0).id.replace(/voter_/, '');
					reason_id = "reason_" + voter_id;
					$j('#'+reason_id).toggle();
					return false;
				})
			}
    
  }, // end InlineHelp

	SearchBox: { // methods to support toggling of persistent search box
		
		searchVisible: false,
		
    initialize: function() { // hide the bottom half of the search area and add a toggle link
			// hide search fields
			$j('#persistent_search #meetings_and_proposals').hide();
			// insert toggle link
			$j('#persistent_search #meetings_and_proposals').after('<div id="toggle_search"><img src="' + PD.slideClosedImagePath + '" width="8" height="8" /> <a href="#">More search options</a>');
			// click-enable toggle link (we also fire this event by default on the data archive landing page)
			$j('#persistent_search #toggle_search a').click(function() {
				PD.SearchBox.searchVisible = !PD.SearchBox.searchVisible;
				if (PD.SearchBox.searchVisible) {
					$j('#persistent_search #meetings_and_proposals').slideDown(250);
					$j(this).prev().attr('src',PD.slideOpenedImagePath);
					$j(this).html('Fewer search options');
				} else {
					$j('#persistent_search #meetings_and_proposals').slideUp(250);
					$j(this).prev().attr('src',PD.slideClosedImagePath);
					$j(this).html('More search options');
				}
				return false;
			});
		}
		
  }, // end SearchBox
  
  PinRow: { // methods to support toggling of control number in your votes
		
		pinVisible: false,
		
    initialize: function() { // hide the bottom half of the search area and add a toggle link
			// hide search fields
			$j('#cn_pin_options').hide();
			// insert toggle link
			$j('#cn_pin_options').after('<div id="toggle_cn_pin"><img src="' + PD.slideClosedImagePath + '" width="8" height="8" /> <a href="#">Show PIN options</a>');
			// click-enable toggle link (we also fire this event by default on the data archive landing page)
			$j('#toggle_cn_pin a').click(function() {
				PD.PinRow.pinVisible = !PD.PinRow.pinVisible;
				if (PD.PinRow.pinVisible) {
					$j('#cn_pin_options').slideDown(250);
					$j(this).prev().attr('src',PD.slideOpenedImagePath);
					$j(this).html('Hide PIN Options');
				} else {
					$j('#cn_pin_options').slideUp(250);
					$j(this).prev().attr('src',PD.slideClosedImagePath);
					$j(this).html('Show PIN Options');
				}
				return false;
			});
		}
		
  }, // end ControlNumber
  
	TableSorter: { // methods to support our use of the table sorting functionality provided by the jquery.tablesorter.js plugin
		
		initializeIssueArea: function() { // takes an optional sorting argument to trigger an initial sort state for the table
			var sorting = arguments[0];

			$j("#score_table").tablesorter({ textExtraction: "simple", headers: {0: { sorter: "text"}, 1: {sorter: "digit"}} }); 
			$j("#score_table").bind("sortStart",function() { 
				PD.TableSorter.truncateTable(0);
			})
			if (sorting) {
				$j("#score_table").trigger("sorton", [sorting]); 
			}
		},
		
		initializeFocusList: function() { // takes an optional sorting argument to trigger an initial sort state for the table
			var sorting = arguments[0];

			$j("#score_table").tablesorter({ textExtraction: "simple", headers: {0: { sorter: "text"}, 1: {sorter: "digit"}, 2: {sorter: "digit"}} }); 
			$j("#score_table").bind("sortStart",function() { 
				PD.TableSorter.truncateTable(0);
			})
			if (sorting) {
				$j("#score_table").trigger("sorton", [sorting]); 
			}
		},
		
		initializeProblems: function() { // takes an optional sorting argument to trigger an initial sort state for the table
			var sorting = arguments[0];

			$j("table#problems").tablesorter( { textExtraction: "complex", sortList: [[0,1]], headers: { 6: {sorter: false}} } ); //{ textExtraction: "simple", headers: {0: { sorter: "digit"}, 1: {sorter: "text"}, 3: {sorter: "text"}} }
			if (sorting) {
				$j("table#problems").trigger("sorton", [sorting]); 
			}
		},
		
		initializeProposalDetails: function() { // takes an optional sorting argument to trigger an initial sort state for the table
			var sorting = arguments[0];
			$j("table#proposal_details").tablesorter( { textExtraction: "complex", sortList: [[1,1]], headers: { 2: {sorter: false}, 3: {sorter: false}, 4: {sorter: false} } } ); //{ textExtraction: "simple", headers: {0: { sorter: "digit"}, 1: {sorter: "text"}, 3: {sorter: "text"}} }
			if (sorting) {
				$j("table#proposal_details").trigger("sorton", [sorting]); 
			}
		},
		
		initializeAnnotations: function() { // takes an optional sorting argument to trigger an initial sort state for the table
			var sorting = arguments[0];
			$j("table#annotations").tablesorter( { textExtraction: "complex", sortList: [[1,1]], headers: { 6: {sorter: false} } } ); //{ textExtraction: "simple", headers: {0: { sorter: "digit"}, 1: {sorter: "text"}, 3: {sorter: "text"}} }
			if (sorting) {
				$j("table#annotations").trigger("sorton", [sorting]); 
			}
		},
		
		truncateTable: function(numRows) { // shorten table display by hiding all but the first <numRows> rows
			if (numRows == 0) {
				// show them all
				$j("#score_table tbody tr").show();
			} else {
				// hide em all first
				$j("#score_table tbody tr").hide();
				// show the ones within the requested limit
				$j("#score_table tbody tr").each(function(i) {
					if (i<numRows) {
						$j(this).show();
					}
				});
			}
		}, // end truncateTable
		
		sortTable: function(sorting) { // force a sort of the table, where <sorting> is of the form e.g. [[0,0],[2,1]] (sort by first column ascending, then third column descending)
	        // sort on the supplied sorting params
	        $j("#score_table").trigger("sorton", [sorting]); 
	        // return false to stop default link action 
	        return false; 
		}

	}, // end TableSorter

	ProposalVoteSummary: {
		
		discloseAll: false,

		initialize: function(){
			$j("tr.fund_family_vote").hide();
			$j("tr.fund_family_link").hide();
			if ($j("tr.fund_family").size() > 0) {
				// only show toggle link if there are actually fund family rows in this display (ticket #102)
				$j('#proposal_vote_summary').before('<p id="toggle_link"><img src="' + PD.discloseClosedImagePath + '" width="8" height="8" /> <a href="javascript:PD.ProposalVoteSummary.toggleAll()">Expand all fund families</a></p>')
			}
			$j("tr.fund_family").each(function(i) {
				// setup disclosure fx 
				$j(this).find('td.disclose').html('<img src="' + PD.discloseClosedImagePath + '" width="12" height="12" />');
				this.disclosureStatus = 0;
				// setup rollovers
				$j(this).hover(function() {
					$j(this).css({background: '#ff9', cursor: 'pointer'});
				}, function() {
					$j(this).css({background: '#eee'});
				});
				// handle clicks
				$j(this).click(function() {
					// find my id and thereby my children
					me = this.id.match(/fund_family_(\d+)/)[1];
					// $j("tr.childOf"+me).toggle(); /* THIS DOESN'T WORK IN IE8. REPLACING WITH VERBOSE VERSION BELOW */
					$j("tr.childOf"+me).each(function(){
						if ($j(this).css('display') == 'none') {
							$j(this).show();
						} else {
							$j(this).hide();
						}
					})
					// change my disclosure status and icon
					this.disclosureStatus = 1 - this.disclosureStatus;
					if (this.disclosureStatus == 1) {
						$j(this).find('td.disclose').html('<img src="' + PD.discloseOpenedImagePath + '" width="12" height="12" />');
					} else {
						$j(this).find('td.disclose').html('<img src="' + PD.discloseClosedImagePath + '" width="12" height="12" />');
					}
					return false;
				});
			});
		},

		// slightly kludgey?
		toggleAll: function() {
			// toggle our discloseAll status
			PD.ProposalVoteSummary.discloseAll = !PD.ProposalVoteSummary.discloseAll;
			// update disclosure icon status
			if (PD.ProposalVoteSummary.discloseAll) {
				$j('#toggle_link img').attr('src', PD.discloseOpenedImagePath)
				$j('#toggle_link a').html('Collapse all fund families')
			} else {
				$j('#toggle_link img').attr('src', PD.discloseClosedImagePath)
				$j('#toggle_link a').html('Expand all fund families')
			}
			// selectively "click" on the fundfamily rows depending 
			// on our discloseAll status and each row's disclosure status
			$j("tr.fund_family").each(function(i) {
				if (PD.ProposalVoteSummary.discloseAll) {
					if (this.disclosureStatus == 0) {
						$j(this).trigger('click');
					}
				} else {
					if (this.disclosureStatus == 1) {
						$j(this).trigger('click');
					}
				}
			});
		}
		
	},
  
  Problem: { // methods to support the problem-reporting system

		insertForm: function(queryString) {
			$j('#spinner').html('<img src="/images/common/ajax-loader.gif" width="16" height="16" alt="Loading..." style="vertical-align: middle; padding-left: 0.25em" />');
			$j.get('/problems/inline_form?' + queryString, function(data){
				$j('#inline_form').html(data);
				$j('#inline_form').slideDown();
				$j('#spinner').empty();
			});
		}

	},
  
  Util: { // grab bag of utility methods

    // http://www.quirksmode.org/js/findpos.html
    findPos: function(obj) {
      var curleft = curtop = 0;
      if (obj.offsetParent) {
        do {
          curleft += obj.offsetLeft;
          curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
        return {x: curleft, y: curtop};
      }
    } // end findPos
    
  } // end Util
}
