$(document).ready(function() {

  //Banking Search Page Expand/Minimise
  //show read more button if javascript on
  //Next line turned off for now
  //$('.expand_switch').html('<p class="button read_more banking max"><a href="#"><img src="graphics/button/button-read-more.png" alt="read more" class="min" /></a></p>');
  //hide section on page load

  $('div.extra').hide(); // TODO put back in


  //create buttons
  var showMore = "<img src='/static/graphics/button/button-read-more.png' alt='read more' class='show_more' />"
  var showLess = "<img src='/static/graphics/button/button-minimise.png' alt='minimise' class='show_less' />"

  
  //expand and collapse on click
  $('div.expand_switch p a').live('click', function(event) {
    this.blur();
	if ($('.expand_switch p a img').attr('class')==='show_less') {
		$('.expand_switch p a').html(showMore);
	} else {
		$('.expand_switch p a').html(showLess);
	}
	$('div.extra').toggle(600);
	$('.expand_switch').pngFix(); // Makes new buttons transparent
	event.preventDefault();
  });

    
  //tab functionality - Number 1
  //hide all tabs apart from the first one
  //finds all tabbed_content divs
  var tabContainers1 = $('div.tabs1').next('div').find('div.tabbed_content1');
  //hides all apart from first one
  tabContainers1.hide().filter(':first').show();
  //tabs interactions
  $('div.tabs1 li').click(function() {
        $(this).find('*').blur();
    	//gets selected id
	    var containerID = "#" + $(this).find('p').attr('class');
    	//hides all tabbed content apart from selected ID
        tabContainers1.hide().filter(containerID).show();
        //change state of clicked tab
        $(this).addClass('active color')
               .find('a').removeClass('swap_link')
               .end()
               //change state of other tabs
               .siblings().removeClass('active color')
               .find('a').addClass('swap_link');
    	$(document).pngFix(); // Makes new buttons transparent
	    return false;
  });
      
  //advanced search button functionality
  $('#advanced_link a').click(function() {
  this.blur();
	//gets selected id
	var containerID = "#" + $(this).attr('class');
	//hides all tabbed content apart from selected ID
    tabContainers1.hide().filter(containerID).show();
    //change state of clicked tab
    $('.tabs1 li+li').addClass('active color')
    .find('a').removeClass('swap_link')
    .end()
	//change state of other tabs
    .siblings().removeClass('active color')
    .find('a').addClass('swap_link');
	$(document).pngFix(); // Makes new buttons transparent
	return false;
  });
  
  function setupTabs2() {
      //tab functionality - Number 2
      //hide all tabs apart from the first one
      //finds all tabbed_content divs
      var tabContainers2 = $('.tabs2').next('div').find('.tabbed_content2');
      //hides all apart from first one
      tabContainers2.hide().filter(':first').show();
      //tabs interactions
      $('.tabs2 li').click(function() {
        $(this).find('*').blur();
        //gets selected id
        var containerID = "#" + $(this).find('p').attr('class');
        //hides all tabbed content apart from selected ID
        tabContainers2.hide().filter(containerID).show();
        //change state of clicked tab
        $(this).addClass('active color')
        .find('a').removeClass('swap_link')
        .end()
        //change state of other tabs
        .siblings().removeClass('active color')
        .find('a').addClass('swap_link');
        //swap content area to relevant content
        return false;
      });
  }
  
  setupTabs2();
    
  // Beauty Tips CSS - jQuery
  // Disable default links
  $('a.tooltip').click(function() {
    this.blur();
    return false;
  });
  // Style Tool Tips
  $('a.tooltip').bt({
      // add a "more" link based on href of a link (if link is present)
      contentSelector: "($('<span></span>').text($(this).attr('title')).append($(this).attr('href')? $('<a> more</a>').attr('href',$(this).attr('href')) : ''))",
      fill: '#F7F7F7', 
      strokeStyle: '#B7B7B7', 
      spikeLength: 20, 
      spikeGirth: 20, 
      padding: 8, 
      cornerRadius: 10,
      trigger: 'click',
      closeWhenOthersOpen: true,
      positions: 'top',
      centerPointX: .7,
      cssStyles: {
        fontSize: '11px'
      }
   });

   $('.color_key').bt({
      contentSelector: "($('<span></span>').text($(this).attr('title')))",
      fill: '#F7F7F7', 
      strokeStyle: '#B7B7B7', 
      spikeLength: 20, 
      spikeGirth: 20, 
      padding: 8, 
      cornerRadius: 10,
      trigger: 'click',
      closeWhenOthersOpen: true,
      positions: 'top',
      centerPointX: .7,
      cssStyles: {
        fontSize: '11px'
      }

   });
   
  function scrollTo(element) {
    var offset = element.offset();
    var confirmTop    = offset.top;
    $('html,body').animate({scrollTop: element.offset().top}, 500);
  }

  function attach_profile_links() {
      /* add profile link ajax updates */
      $('a.profile_link').live('click', function(event) {
        this.blur();
        var url = $(this).attr('href');
        var link_text = $(this).text();
        // strip anchor tag if present
        url = url.replace(/#.*$/,'');
        $('div.profile_information').text("Loading...").show().load(url + " div.profile_information", function() {
            /* ajax callback */
            setupTabs2();
            $('.rounded').corners("transparent"); // make sure we round the new corners
            $("#search_profile .active:not(:first)").removeClass("active"); // only show first block

            $(document).pngFix(); // Makes new buttons transparent
            scrollTo($('div.profile_information'));
            
            // close profile
            $('p.close_button a').click(function(event) {
               event.preventDefault();
               $('div.profile_information').hide(); 
               scrollTo($('#results_table'));
            });
            
            // profile print button
            $('.profile_information .print_info a').click(function(event) {
               event.preventDefault();
               var window_title = link_text.replace(/[^\w*]/g, '_');
               window.open(url + "?print=profile", window_title, "width=769,scrollbars=yes");
            });
            
        });
        event.preventDefault();
      });
  }
  
  function add_search_profile_accordian() {
      /* add accordian to profile criteria */
      $("#search_profile .profile_results .profile_header").live('click', function() {
            $(this).find('*').blur();
            var content = $(this).parents(".criteria_content, .section_content");
            if ( !content.hasClass("active") ) {
                // hide the old content (we first show it to make sure
                // if doesn't get instantly hidden when we remove the "active" class)
                $("#search_profile .criteria_details:visible, #search_profile .profile_details:visible").show().slideUp("slow");
                $("#search_profile .active").removeClass("active");
                
                // now reveal the new content
                var details = content.find(".criteria_details, .profile_details");
                details.hide().slideDown("slow");
                content.addClass("active");
            } else {
                var details = content.find(".criteria_details, .profile_details");
                details.show().slideUp("slow");
                content.removeClass("active");
            }
      });
  }
  
  attach_profile_links();
  add_search_profile_accordian();
  

  /* start of sorting code */
  
    /* patch in a function to let us
     * escape strings we want to match in a regexp.
     * http://simonwillison.net/2006/Jan/20/escape/
     */
    RegExp.escape = function(text) {
      if (!arguments.callee.sRE) {
        var specials = [
          '/', '.', '*', '+', '?', '|',
          '(', ')', '[', ']', '{', '}', '\\'
        ];
        arguments.callee.sRE = new RegExp(
          '(\\' + specials.join('|\\') + ')', 'g'
        );
      }
      return text.replace(arguments.callee.sRE, '\\$1');
    }

     
    /** extract the table data from the page for sorting. **/
    var results_table_rows = [];
    var criteria_columns = {};
    var column_names = [];
    
    function prepare_sortable_table() {
        // extract criteria names etc
        $("#results_table th").each(function() {
            var class_names = $(this).attr('class').split(' ');
            for ( var i = 0; i < class_names.length; i++ ) {
                var class_name = class_names[i];
                if ( class_name.match(/^criteria-/) ) {
                    var criteria_name = class_name.replace(/^criteria-/, '');
                    criteria_columns[criteria_name]=[$(this)];
                    column_names.push(criteria_name);
                    break;
                }
            }
        });
        
    
        $("#results_table tbody tr").each(function() {
            var tr = $(this);
            var row_class = tr.attr('class');
            
            var row  = {
                name: tr.find("td:first a").text(),
                classes: row_class,
                row_dom: this
            };
            
            // each image contains an alt attribute with the
            // value for that cell
            tr.find("img").each(function(index) {
                var img = $(this);
                var value = img.attr('alt');
                value = value? value : 0;
                var criteria_name = column_names[index];
                row[criteria_name] = value; 
                criteria_columns[criteria_name].push(img.parent());
            });
            
            results_table_rows.push(row);
        });

        var basic_search_form = $("form#basic_search");
        var basic_search_input = basic_search_form.find("input[name=q]");
        
        basic_search_form.submit(function(event) {
            $(this).find('input').blur();
            var q = basic_search_input.val();
            var filtered = filter_rows(results_table_rows, q);
            rebuild_result_table(filtered);
            scrollTo($('#results_table'));
            event.preventDefault();
        });
        
        $("form#advanced_search").submit(function(event) {
            $(this).find('input').blur();
            scrollTo($('#results_table'));
            event.preventDefault();
        });
        
        $("#advanced_search input[type=checkbox]").click(function() {
          this.blur();
          sort_results_table();
        });
        
        /* enable sort link */
        $("#results_table .sort_link").click(function(event) {
            this.blur();
            var image_src = $(this).find("img").attr("src");
            var up = image_src.match(/-up\.gif$/);
            
            $(this).find("img").attr("src", image_src.replace(/-\w+\.gif$/, up? '-down.gif' : '-up.gif'));
            
            // reverse order of table
            reverse_results_table();
            
            event.preventDefault();
        });
        
        /* enable select all and clear all buttons */
        $('.select_all a').click(function(event) {
            this.blur();
            var form = $(this).parents("form");
            form.find(":checkbox").attr('checked','checked');
            sort_results_table()
            event.preventDefault();
        });
        $('.clear_all a').click(function(event) {
            this.blur();
            var form = $(this).parents("form");
            form.find(":checkbox").removeAttr('checked');
            sort_results_table()
            event.preventDefault();
        });
        
    }
   
    function filter_rows(table_rows, q) {
        /* return rows that match the name given */
        q = q.toLowerCase();
        
        var filtered = [];
        for ( var i = 0; i < table_rows.length; i++ ) {
            var row = table_rows[i];
            if ( row.name.toLowerCase().indexOf(q) != -1 ) {
                filtered.push(row);
            }
        }
        
        return filtered;
    }
    
    function sort_rows(table_rows, criteria) {        
        // work out the row scores, based on the given criteria
        var scores = [];
        for ( var i = 0; i < table_rows.length; i++ ) {
            scores.push({
                score: 0,
                row: table_rows[i]
            });
        }
        
        for ( var i = 0; i < criteria.length; i++ ) {
            var criteria_i=criteria[i];
            
            // first find the max, average etc so we can
            // normalise and average empty values
            var count = 0, total = 0, max = 0;
            for ( var j = 0; j < table_rows.length; j++ ) {
                var row = table_rows[j];
                var score = Number(row[criteria_i]);
                if ( !isNaN(score) ) {
                    count++;
                    total += score;
                    max = Math.max(max, score);
                }
            }
            
            var average = (count > 0)? total/count : 0;
            
            // now we can normalise the score and
            // add them to the totals
            for ( var j = 0; j < table_rows.length; j++ ) {
                var row = table_rows[j];
                var score = Number(row[criteria_i]);
                if ( isNaN(score) || row[criteria_i] == '' || max == 0 ) {
                    score = average;
                }
                else {
                    score = score / max;
                }
                
                scores[j].score += score;
            }
        }
        
        // sort the actual rows
        scores.sort(function(a,b) { return b.score - a.score; })
    
        // now detach the scores and rows and just get the rows
        var sorted_rows = [];
        for ( var i = 0; i < scores.length; i++ ) {
            sorted_rows.push(scores[i].row);
        }
        
        //alert("sort_rows: " + (new Date().getTime() - start));
        
        return sorted_rows;
    }
    
    function filter_rows_by_type(table_rows, types) {
        if ( types.length == 0 ) {
            return table_rows;
        }
        
        for ( var i = 0; i < types.length; i++ ) {
            // types have a prefix with a number, when
            // they've come from the form, so we need to remove that
            var type = types[i].replace(/^type-\d+-/, '');
            // then convert into regexp to make matching easier
            type = new RegExp("\\btype-" + RegExp.escape(type) + "\\b");
            types[i] = type;
        }
        
        var filtered = [];
        for ( var i = 0 ; i < table_rows.length; i++ ) {
            var row = table_rows[i];
            for ( var j = 0; j < types.length; j++ ) {
                if ( types[j].test(row.classes) ) {
                    filtered.push(row);
                    break;
                }
            }
        }
        
        return filtered;
    }
    
    function sort_results_table() {
        //var start = new Date().getTime();
        var basic_search_input = $("form#basic_search").find("input[name=q]");
        // get the criteria we want to sort by
        var criteria=[];
        $("#advanced_search .sort_by_criteria :checked").each(function() {
            criteria.push($(this).attr('name'));
        });
        
        // find each filter form (questions) and filter as needed
        var table_rows = results_table_rows;
        $("#advanced_search .filter_form").each(function() {
            var types = [];
            $(this).find(":checked").each(function() { types.push($(this).attr('name')); });
            table_rows = filter_rows_by_type(table_rows, types);
        });
        
        rebuild_result_table(sort_rows(table_rows, criteria));
        
        // highlight the relevant columns
        highlight_columns(criteria);

        //alert("time: " + (new Date().getTime() - start));
    }
    
    function highlight_columns(criteria) {
        $('td.selected_criteria, th.selected_criteria').removeClass('selected_criteria');
        for ( var i = 0; i < criteria.length; i++ ) {
            var criteria_name = criteria[i];
            var columns = criteria_columns[criteria_name];
            for ( var j = 0; j < columns.length; j++ ) {
                columns[j].addClass('selected_criteria');
            }
        }
    }
    
    function rebuild_result_table(table_rows) {
        
        var table = $("#results_table");
        var tbody = table.children('tbody');
        
        // remove all rows
        tbody.empty();
        
        // then re-append them in correct order
        for ( var i = 0; i < table_rows.length; i++ ) {
            var row_dom = table_rows[i].row_dom;
            tbody.append(row_dom);
        }
        
        // reset sort link to up
        $("#results_table .sort_link img").each(function() {;
            var sort_image = $(this);
            var image_src = sort_image.attr("src");
            sort_image.attr("src", image_src.replace(/-\w+\.gif$/, '-up.gif'));
        });
        
    }
    
    function reverse_results_table() {
        var table = $("#results_table");
        var rows = $(table.find("tbody > tr").get().reverse());
        rows.each(function(i,row) {
            var tbody = table.children('tbody');
            tbody.append(row);
        });
    }    

    // extra stuff that was originally in other files 
    $(document).pngFix();
    $('div.rounded, h3.rounded').corners("transparent");
    $('div#links_right ul').prepend('<li class="print_page"><a class="swap_link" href="#print">Print page</a></li>');
	$('div#links_right ul li.print_page a').click(function(event) {
        //additionalStylesheet('profile-only', false);
		window.print();
		event.preventDefault();
	});
    $('#table_bottom .print_info a').click(function(event) {
        event.preventDefault();
        var url = window.location.href;
        window.open(url + "?print=results", "Results", "width=769,scrollbars=yes");
    });
    
    // run this async, as it takes a little while
    // in IE and holds up page loading
    setTimeout(prepare_sortable_table,10);
});

