/*
 * Pagination 0.2
 *  space150/2008
 */
 
Pagination = Class.create({});

Object.extend(Pagination, 
{
  STATUS_AREA: '#pagination .status',
  PREVIOUS_LINK: '#pagination .prev',
  NEXT_LINK: '#pagination .next'
});

Pagination.addMethods(
{
  initialize: function(data, elementsPerPage) 
  {
    this.elementsPerPage = elementsPerPage || 5;
    this.allElements = data || [];
    this.activeElements = data || [];
    this.index = 0;
    this.page = [];
  },
  pageOf: function(array, start, pageLength) 
  {
    var start = Math.max(0, start);
    var end   = Math.min(this.activeElements.length, start + pageLength);
    return this.activeElements.slice(start, end);
  },
  setIndex: function(value) 
  {
    if (value >= 0 && value < this.activeElements.length)
    {
      this.index = value;
    }
    this.changed();
  },
  getIndex: function() 
  {
    return this.index;
  },
  getDisplayIndex: function()
  {
    if (this.activeElements.length > 0) {
      return this.index + 1;
    }
    return 0;
  },
  setPage: function(startingPage) 
  {
    this.setIndex(startingPage * this.elementsPerPage);
  },
  getPage: function() 
  {
    this.page = this.pageOf(this.activeElements, this.index, this.elementsPerPage);
    return this.page;
  },
  pages: function() 
  {
    return Math.floor(this.activeElements.length / this.elementsPerPage);
  },
  pageNumber: function () 
  {
    return Math.floor(this.getIndex() / this.elementsPerPage);
  },
  incrementPage: function(inc) 
  {
    this.setPage(this.pageNumber() + inc);
  },
  nextPage: function() 
  {
    var start = this.index + this.elementsPerPage;
    if (start > this.activeElements.length) return [];
    return this.pageOf(this.activeElements, start, this.elementsPerPage);
  },
  prevPage: function() 
  {
    var start = this.index - this.elementsPerPage;
    return this.pageOf(this.activeElements, start, this.elementsPerPage);
  },
  hasNextPage: function() 
  {
    var start = this.index + this.elementsPerPage;
    return (start < this.activeElements.length);
  },
  hasPrevPage: function() 
  {
    return (this.index > 0);
  },
  changed: function() 
  {
    document.fire("pagination:change", this);
  },
  filter: function(filterFunction, reset)
  {
    var elementsToFilter;

    if (reset) {
      elementsToFilter = this.allElements;
    } else {
      elementsToFilter = this.activeElements;
    }
    
    var newActiveElements = [];
    for (var i = 0; i < elementsToFilter.length; i++)
    {
      var element = elementsToFilter[i];
      if (filterFunction(element)) {
        newActiveElements.push(element);
      }
    }
    this.activeElements = newActiveElements;
    this.setIndex(0);
  },
  removeFilter: function()
  {
    this.activeElements = this.allElements;
    this.changed();
  },
  sort: function(property, direction) 
  {
    if (direction.match(/(d|D|\<)/)) {
      var sign = " > ";
      this.activeElements.sort(function(left, right) 
      {
        if (left[property] < right[property]) {
          return 1;
        }
        if (left[property] > right[property]) {
          return -1;
        }
        return 0;
      });
    }
    else {
      var sign = " > ";
      this.activeElements.sort(function(left, right) 
      {
        if (left[property] < right[property]) {
          return -1;
        }
        if (left[property] > right[property]) {
          return 1;
        }
        return 0;
      });
    }
    this.changed();
  },
  info: function() 
  {
    return {
      start:  (this.getDisplayIndex()),
      end:    (this.getIndex() + this.getPage().length),
      total:  this.activeElements.length
    };
  }
});
SpecialistResultsController = Class.create({});

Object.extend(SpecialistResultsController,
{
	DEFAULT_PAGE        :  0,
	DEFAULT_SORT_ORDER  :  []
});

SpecialistResultsController.addMethods(
{
	initialize: function(repoElements, outputElement, sortSelectElement, perPage) 
	{
	  try
	  {
  	  this.repoElements = repoElements;
  		this.outputElement = outputElement;
  		this.sortSelectElement = sortSelectElement;
  		this.resultsPerPage = perPage;
		
  		this.previousLink = $$(Pagination.PREVIOUS_LINK).first();
  		this.nextLink = $$(Pagination.NEXT_LINK).first();
  		this.statusArea = $$(Pagination.STATUS_AREA).first();
  		
      // randomize initial display order
  		this.repoElements.sort(function() {return (Math.round(Math.random())-0.5);});
  		this.repoElements.sort(function() {return (Math.round(Math.random())-0.5);});

  		this.pagination = new Pagination(this.repoElements, this.resultsPerPage);
		}
		catch (error) 
		{
			Logger.log("WARNING: instance variable initialization failed: " + error);
		}
		
	  try 
	  {
	    this.populateFromURIFragment();
  		SWFAddress.addEventListener(SWFAddressEvent.CHANGE, this.handleURIFragmentChange.bind(this));
  		
  		document.observe('pagination:change', this.onPageUpdate.bindAsEventListener(this));

      if (this.previousLink != null)
			{
			  this.previousLink.observe('click', this.handleClickPreviousPage.bindAsEventListener(this));
			}
			if (this.nextLink != null)
			{
			  this.nextLink.observe('click', this.handleClickNextPage.bindAsEventListener(this));
			}
      if (this.nextLink != null)
			{
  		  this.sortSelectElement.observe('change', this.handleSelectSort.bindAsEventListener(this));
		  }
	  }
	  catch (error) {
      Logger.log("WARNING: initialize failed: " + error);
	  }
	},


  populateFromURIFragment: function() {
    /* update the drop-down to reflect the uri fragment */
    var data = this.parseURIFragment(SWFAddress.getValue());
    this.sortSelectElement.value = data.sortorder.join(':');
  },
  parseURIFragment: function(fragment) {
	  var parts = fragment.substr(1).split('/');
	  return {
	    page:       parts[0] ? Number(parts[0]) - 1 : SpecialistResultsController.DEFAULT_PAGE,
	    sortorder:  parts[1] ? parts[1].split(";")  : SpecialistResultsController.DEFAULT_SORT_ORDER
	  }
  },
	handleURIFragmentChange: function(event)
	{

	  try {

		  var data = this.parseURIFragment(event.value);

      /* update sortorder ... */
      var propdir = data.sortorder;
  	  if (propdir[0] != '' && propdir[0] != undefined) {
        this.pagination.sort(propdir[0], propdir[1]);
        this.sortSelectElement.value = data.sortorder.join(':');
      }

      this.pagination.setPage(data.page);

	  }
	  catch (error) {
	    
      Logger.log("WARNING: handleURIFragmentChange failed: " + error);
      
	  }
	  
	},
	updateURIFragment: function(currdata) {
    var newdata;

    /* copy the old data in as the defaults ... */
    newdata = SWFAddress.getPathNames();

    /* ... then override  */
    if (currdata.page !== undefined)      newdata[0] = String(currdata.page);
    if (currdata.sortorder !== undefined) newdata[1] = currdata.sortorder.join(';');
        
    SWFAddress.setValue( newdata.join('/') );    
	},



	handleClickPreviousPage: function()
	{
	  try {
	    if (this.pagination.hasPrevPage()) {
	      var index = this.pagination.pageNumber();
    		this.updateURIFragment({ page: index });
	    }
	  }
	  catch (error) {
      Logger.log("WARNING: handleClickPreviousPage failed: " + error);
	  }
	},
	handleClickNextPage: function()
	{
	  try {
	    if (this.pagination.hasNextPage()) {
	      var index = this.pagination.pageNumber() + 2;
    		this.updateURIFragment({ page: index });
		  }
	  }
	  catch (error) {
      Logger.log("WARNING: handleClickNextPage failed: " + error);
	  }
	},
	handleSelectSort: function(event) 
	{
	  try {
  	  var propdir = event.target.value.split(/:/);
  	  if (propdir[0] != '') {
        this.updateURIFragment({ 
          page:       this.pagination.pageNumber() + 1,
          sortorder:  [propdir[0], propdir[1]] 
        });
  	  }
	  }
	  catch (error) {
      Logger.log("WARNING: handleSelectSort failed: " + error);
	  }
	},
	onPageUpdate: function(event)
	{
		if (this.statusArea != null)
		{
      var info = this.pagination.info();
      var items = [info.start, "-", info.end].join('');
		  this.statusArea.update(["<span class='items'>", items, " </span>", "of", info.total].join(' '));
		}
		if (this.previousLink != null)
		{
		  var prevOpacity = this.pagination.hasPrevPage() ? 1 : 0;
		  this.previousLink.setOpacity(prevOpacity);
		  if (this.previousLink.down('img')) {
		    this.previousLink.down('img').setOpacity(prevOpacity);
	    }
		}
		if (this.nextLink != null)
		{
		  var nextOpacity = this.pagination.hasNextPage() ? 1 : 0;
		  this.nextLink.setOpacity(nextOpacity);
		  if (this.nextLink.down('img')) {
		    this.nextLink.down('img').setOpacity(nextOpacity);
		  }
		}
    
		this.render(this.pagination.getPage());
	},
	render: function(page) 
	{
		var specialist_listings = "";
		for (var i = 0; i < page.size(); i++)
		{
			var item = $(page[i].id);
			specialist_listings += '<div id="specialist-result-' + page[i].id + '" class="specialist">' + item.innerHTML + '</div>';
		}
		if (this.outputElement != null)
		{
		  this.outputElement.update(specialist_listings);
		}
    this.showHorizontalDividerLines(page);
	},
	showHorizontalDividerLines: function(page) {
		for (var i = 0; i < page.size(); i++)
		{
			var item = $(page[i].id);
  		var specialist = $('specialist-result-' + page[i].id);
  		if (((i+1) == page.size())) {
  		  specialist.addClassName('last');
  		  specialist.removeClassName('divider');
  		}
  		else {
  		  specialist.addClassName('divider');
  		  specialist.removeClassName('last');
  		}
    }	  
	}
});
SpecialistSearchModel = Class.create({})

SpecialistSearchModel.addMethods(
{
	initialize: function() 
	{
	  this.specialty_id = '';
	  this.specialty_name = '';
	},
	getSearchUrl: function()
	{
    var prefix = '';
    if (window.location.pathname.match(/\/amexnetwork/) != null) {
      prefix = '/amexnetwork';
    }
	  if (this.specialty_id != '') {
	    var url = prefix + '/specialists?';

	    this.specialty_id.split(/\,/).each(function(id) {
	      url = url + 'activity_id[]=' + id + '&';
	    }.bind(this));
	    url = url + 'activity_name=' + this.specialty_name.strip();
	    return url;
	  }
    return null;
	},
	setSpecialty: function(id, name)
	{
	  this.specialty_id = id;
	  this.specialty_name = name;
	}
});

SpecialistSearchController = Class.create({});

Object.extend(SpecialistSearchController, 
{
	SPECIALTY_SELECT: '.specialty_select',
	GO_BUTTON: '#go_button'
});

SpecialistSearchController.addMethods(
{
	initialize: function() 
	{
	  try {
  	  this.model = new SpecialistSearchModel();

  		$$(SpecialistSearchController.SPECIALTY_SELECT).invoke('observe', 'change', this.handleSelectSpecialty.bindAsEventListener(this));
  		$$(SpecialistSearchController.GO_BUTTON).invoke('observe', 'click', this.handleClickGo.bindAsEventListener(this));
  		
  		this.resetSelectSpecialties();
	  }
    catch (error) 
    {
      Logger.log("WARING: initialize failed: " + error);
    }
	},
  handleClickGo: function(event)
  {
    try {
      var url = this.model.getSearchUrl();
      if (url != null) {
        document.location = url;
      }
    }
    catch (error) {
      Logger.log("WARING: handleClickGo failed: " + error);
    }
  },
	handleSelectSpecialty: function(event)
	{
	  try {
  	  var specialty_id = event.target.value;
  	  var specialty_name = event.target.options[event.target.selectedIndex].text;

  	  this.model.setSpecialty(specialty_id, specialty_name);
      this.highlightSelectSpecialty(event.target);
	  }
	  catch (error) {
      Logger.log("WARING: handleSelectSpecialty failed: " + error);
	  }
  },
  highlightSelectSpecialty: function(target)
  {
    $$(SpecialistSearchController.SPECIALTY_SELECT).each(function(other) {
      if (target != other) {
        other.up('fieldset').removeClassName('highlighted');
        other.selectedIndex = 0;
      }
    });
    target.up('fieldset').addClassName('highlighted');
  },
  resetSelectSpecialties: function()
  {
    $$(SpecialistSearchController.SPECIALTY_SELECT).each(function(target) {
      target.selectedIndex = 0;
    });
  }
});

