/*
 * SPWS DataView
 * Version -1 (0000-00-00)
 * Library containing in-browser gui widgets and functionality.
 * Requires: MagicAjax -1.
 * 
 * Written by Maarten ter Horst,
 * Copyright (c) Maarten ter Horst 2010.
 * 
 * Science Park Web Solutions
 * http://www.scienceparkwebsolutions.nl/
 */

var dv = {
  
  hideMessage: function(button) {
    $(button).closest('.dialog_container').remove();
  },
  
  showMessage: function(message, hasCancel, onCancel, onOK) {
    $('#DVMessage').tmpl({ message: message, hasCancel: hasCancel, onCancel: onCancel, onOK: onOK }).appendTo('body');
  },
  
  hideDetailView: function() {
    $('.detail_view').html('');
    ma.mutation();
  },
  
  /*
   *
   */
  registerIndexHeader: function(view) {
    $('th input').change(function() {
      $(this).closest('.index_view_header').find('th').removeClass('sorted');
      $(this).closest('th').addClass('sorted');
    });
  },
  
  /*
   * Loads the keyboard access to the index view
   * - arrow keys to initiate and advance selection
   * - escape key to remove selection
   */
  registerIndexView: function(view) {
    if ($(view).closest('.dataview').find('.detail_view').hasClass('side'))
      $(view).css('width', '35%');
    
    /* when scrolled to bottom of table, load next entries */
    $(view).scroll(function(event) {
      if ($(this).attr('scrollTop') >=
          $(this).attr('scrollHeight') - $(this).attr('clientHeight') - 1) {
        $('<tbody>').appendTo($(this).find('table'))
            .load($(this).find('table').attr('data-url'), $($('#content').find('form')[0]).serialize() + '&p=' + ($(this).find('tbody').length),
              function(text) {
                if (text.length == 0)
                  /* reached bottom of table */
                  $(view).unbind('scroll');
              });
      }
    });
    
    /* make sure the complete screen is filled with entries while available *//*
    var prev_tableheight = $(view).find('table').attr('clientHeight');
    while (prev_tableheight < $(view).attr('clientHeight')) {
      var tableheight = $(view).find('table').attr('clientHeight');
      if (prev_tableheight == tableheight)
        break;
      $(view).scroll();
      console.log('hoi');
      prev_tableheight = tableheight;
    }*/
    
    /* keyboard access, should be improved */
    $(view).keydown(function(event) {
      var sel = $(this).find('td a.selected').first().closest('tr');
      if (event.which == 38) { // arrow up
        if ($(sel).length == 0)
          $(this).find('tr:last-child').prev().find('a').first().trigger('click');
        else
          $(sel).prev().find('a').first().trigger('click');
      }
      else if (event.which == 40) { // arrow down
        if ($(sel).length == 0)
          $(this).find('tr:first-child').find('a').first().trigger('click');
        else
          $(sel).next().find('a').first().trigger('click');
      }
      else if (event.which == 27) { // escape
        $('#detail_view_close_button').trigger('click');
      }
    });
  },
  
  /* 
   * Sets event handlers for all drop down menu components
   * - menu: the a.button element of the menu
   */
  registerDropdownMenu: function(menu) {
    var displayCurrent = function(menu) {
      if ($(menu).find('input[type="radio"]:checked').length > 0)
        $(menu).children('.dropdownlink').html(
            $(menu).find('input[type="radio"]:checked + label').html());
    };
    
    $(menu).mousedown(function() {
      if (!$(this).hasClass('open')) {
        $('.open').removeClass('open');
        $(this).addClass('open');
        $(this).focus();
        $(document).mousedown(function() {
          $(menu).removeClass('open');
          $(document).unbind('mousedown');
        });
        return false;
      }
    });
    $(menu).find('label').each(function() {
      $(this).click(function() {
        $(menu).removeClass('open');
      });
      $(this).mousedown(function() {
        if ($.browser.msie) {
          $(this).prev().click();
        }
        return false;
      });
    });
    $(menu).find('input[type=radio]').each(function() {
      $(this).change(function() {
        displayCurrent(menu);
      });
    });
    $(menu).keydown(function(event) {
      // TODO voor volgende versie: met pijltjestoetsen door menu.
    });
    
    displayCurrent(menu);
    if ($(menu).find('input[type="radio"]').length > 10)
      dv.registerDropdownMenuSearchField(menu);
    else
      $(menu).find('.dropdownFilterFieldWrapper').remove();
  },
  
  /*
   * filter div elements of a drop down list
   * - value: text filter
   * - list: div containing div.filterables
   * source: http://kilianvalkhof.com/2010/javascript/how-to-build-a-fast-simple-list-filter-with-jquery/
   */
  filterRadioList: function(filter, list) {
    if (filter) {
      $(list).find("div.filterable:not(:Contains(" + filter + "))").slideUp(100);
      $(list).find("div.filterable:Contains(" + filter + ")").slideDown(100);
    } else {
      $(list).find("div.filterable").slideDown(100);
    }
  },
  
  /*
   * Sets event handlers for filtering list items based on text in a text field
   * - menu: the menu containing the filter field
   */
  registerDropdownMenuSearchField: function(menu) {
    var field = $(menu).find('.dropdownFilterField');
    $(menu).focus(function() {
      setTimeout(function() {
        $(field).focus();
      }, 100);
    });
    $(field).keyup(function() {
      dv.filterRadioList($(this).val(), menu);
    });
    $(field).mousedown(function() {
      $(field).focus();
      return false;
    });
  },
  
  sortOptionByValue: function(a, b) {
    return parseInt($(a).attr('value')) - parseInt($(b).attr('value'))
  },
  
  /*
   *
   */
  multiselectAdd: function() {
    wrapper = $(this).closest('.multiselect_wrapper');
    select = $(wrapper).find('select').last();
    notSelected = $(wrapper).find('select').first();
    $(notSelected).find('[selected]').appendTo(select);
    $(select).html($(select).children().sort(dv.sortOptionByValue));
  },
  
  /*
   *
   */
  multiselectRemove: function() {
    wrapper = $(this).closest('.multiselect_wrapper');
    select = $(wrapper).find('select').last();
    notSelected = $(wrapper).find('select').first();
    $(select).find('[selected]').appendTo(notSelected);
    $(notSelected).html($(notSelected).children().sort(dv.sortOptionByValue));
  },
  
  /*
   *
   */
  registerMultiselect: function(select) {
    $(select).addClass('multiselect').wrap('<div class="multiselect_wrapper">')
        .before($(select).clone().removeAttr('id').removeAttr('name').addClass('notSelected').removeClass('multiselect'))
        .before($('<div class="multiselect_buttons">')
            .append($('<a class="button"><span class="triangle_right"></span></a>').click(dv.multiselectAdd))
            .append($('<br />'))
            .append($('<a class="button"><span class="triangle_left"></a>').click(dv.multiselectRemove)));
    $(select).children(':not([selected])').remove();
    $(select).children().removeAttr('selected');
    $(select).parent().find('.notSelected').children('[selected]').remove();
    $(select).parent().find('.notSelected').children().removeAttr('selected');
    $(select).closest('form').submit(function() {
      $(select).children().attr('selected', 'selected');
    });
  },
  
  registerWidgets: function() {
    $('a.dropdownMenu:not(.registered)')
        .addClass('registered').each(function() {
      dv.registerDropdownMenu(this);
    });
    $('div.index_view_header:not(.registered)')
        .addClass('registered').each(function() {
      dv.registerIndexHeader(this);
    });
    $('div.index_view:not(.registered)')
        .addClass('registered').each(function() {
      dv.registerIndexView(this);
    });
    $('.detail_view select[multiple=multiple]').filter(':not(.registered)')
        .addClass('registered').each(function() {
      dv.registerMultiselect(this);
    });
  }
};

/*
 * used in filterRadioList()
 */
jQuery.expr[':'].Contains = function(a,i,m){
  return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase())>=0;
};

$(function() {
  ma.mutation(dv.registerWidgets);
});
