/**
 * File: kwSearch.ContentSearch.js
 *
 * Author: Chris Boget
 * Copyright 2008 Yakabod, inc.
 *
 * $Revision: 1.21 $
 * $Date: 2012/01/11 15:37:37 $
 * Last edited by: $Author: danderson $
 **/

// Set up the namespace
var kwSearch = window.kwSearch || {};
kwSearch.ContentSearch = undefined;
kwSearch.ContentSearch = {

  oSearchRequirements : {},

  oSearchTrigger  : null,
  iSearchDelay    : 4000, /* 4 seconds */
  iRecordLimit    : null,

  setSearchDelay : function( iSearchDelay )
  {
    var retval = kwSearch.ContentSearch.iSearchDelay;

    kwSearch.ContentSearch.iSearchDelay = iSearchDelay;

    return retval;
  },

  getSearchDelay : function()
  {
    return kwSearch.ContentSearch.iSearchDelay;
  },

  setRecordLimit : function( iRecordLimit )
  {
    if( typeof iRecordLimit !== 'number' || iRecordLimit < 1 )
    {
      kwSearch.ContentSearch.iRecordLimit = null
    }
    else
    {
      kwSearch.ContentSearch.iRecordLimit = iRecordLimit;
    }

  },

  getRecordLimit : function()
  {
    return kwSearch.ContentSearch.iRecordLimit;
  },

  startSearchCountdown : function()
  {
    kwSearch.ContentSearch.stopSearchCountdown();
    if( kwSearch.ContentSearch.iSearchDelay >= 0 )
    {
      kwSearch.ContentSearch.oSearchTrigger = setTimeout( 'kwSearch.ContentSearch.performSearch()', kwSearch.ContentSearch.iSearchDelay );
    }
  },

  stopSearchCountdown : function()
  {
    clearTimeout( kwSearch.ContentSearch.oSearchTrigger );
    kwSearch.ContentSearch.oSearchTrigger = null;
  },

  addRequirement : function( sRequirement, oSetting, sSettingUniqueId )
  {
    kwSearch.ContentSearch.stopSearchCountdown();

    if( typeof oSetting == 'object' )
    {
      if( !kwSearchUtil.isEmpty( oSetting ))
      {
        var sUniqId = sSettingUniqueId || '';
        if( sUniqId )
        {
          kwSearch.ContentSearch.oSearchRequirements[sRequirement][sUniqId] = oSetting;
        }
        else
        {
          kwSearch.ContentSearch.oSearchRequirements[sRequirement] = oSetting;
        }
      }
      else
      {
        delete kwSearch.ContentSearch.oSearchRequirements[sRequirement];
      }
      kwSearch.SearchForm.setBaseSearchRequirements( kwSearch.ContentSearch.oSearchRequirements );

      kwSearch.ContentSearch.startSearchCountdown();
    }
  },

  removeRequirement : function( sRequirement, sSettingUniqueId )
  {
    kwSearch.ContentSearch.stopSearchCountdown();

    var sUniqId = sSettingUniqueId || '';
    if( sUniqId )
    {
      delete kwSearch.ContentSearch.oSearchRequirements[sRequirement][sUniqId];
    }
    else
    {
      delete kwSearch.ContentSearch.oSearchRequirements[sRequirement];
    }
    kwSearch.SearchForm.setBaseSearchRequirements( kwSearch.ContentSearch.oSearchRequirements );
    kwSearch.ContentSearch.startSearchCountdown();
  },

  performSearch : function()
  {
    var bPerformSearch = kwSearch.isSearchAllowed();//true;
    if( bPerformSearch )
    {
      kwSearch.SearchForm.setSearchTypeForSearch();
      if( kwSearch.SearchForm.getSearchType() != '' )
      {
        if( kwSearch.ContentSearch.iRecordLimit == null )
        {
          /**
           * 100 is just an arbitrary value.  It is the typical pixel height of an
           * average record's data that is returned during search.  Getting 2 and a
           * half pages worth of records to set up scrolling...
           */
          kwSearch.ContentSearch.iRecordLimit = Math.round((( PageDimensions.getPageHeight() / 100 )  * 2.5 ));
        }
        kwSearch.SearchForm.setRecordLimit( kwSearch.ContentSearch.iRecordLimit );
        kwSearch.SearchForm.setNextStartRecord( 0 );
        kwSearch.ContentSearch.Util.executeSearchCallback( 'Init' );
        kwSearch.ContentSearch.StreamContent.startContentSearch();
      }
    }
  }
}

kwSearch.ContentSearch.Util = {
  /**
   * Only accepting 'Pre', 'Mid' and 'Post' callback definitions.
   *
   * 'Init' : triggered before a new search request.
   * 'Pre'  : triggered just before every search request.
   * 'Mid'  : triggered during the search process.  Because the search results are
   *          returned to the user pagelessly, we need to allow for functionality
   *          to execute during the back and forth, but before the search has
   *          officially concluded
   * 'Post' : triggered after the search has officially concluded.
   */
  aCallbacks : { 'Init' : [],
                 'Pre'  : [],
                 'Mid'  : [],
                 'Post' : [] },

  registerSearchCallback : function( sSearchTiming, sCallbackFunction )
  {
    /**
     * Only allowing the callback properties as defined above.
     */
    if( typeof kwSearch.ContentSearch.Util.aCallbacks[sSearchTiming] != 'undefined' )
    {
      kwSearch.ContentSearch.Util.aCallbacks[sSearchTiming].push( sCallbackFunction );
    }
  },

  executeSearchCallback : function( sSearchTiming, sArguments )
  {
    if(( typeof kwSearch.ContentSearch.Util.aCallbacks[sSearchTiming] != 'undefined' ) &&
       ( kwSearch.ContentSearch.Util.aCallbacks[sSearchTiming].length > 0 ))
    {
      for( var i = 0; i < kwSearch.ContentSearch.Util.aCallbacks[sSearchTiming].length; i++ )
      {
        if( typeof kwSearch.ContentSearch.Util.aCallbacks[sSearchTiming][i] == 'function' )
        {
          /**
           * The 3 code blocks below serve no purpose other than allowing
           * for convenient break points when debugging a particular
           * callback trigger in Firebug
           */
          if( sSearchTiming == 'Init' )
          {
            var HaltHere = 1;
          }
          if( sSearchTiming == 'Pre' )
          {
            var HaltHere = 1;
          }
          if( sSearchTiming == 'Mid' )
          {
            var HaltHere = 1;
          }
          if( sSearchTiming == 'Post' )
          {
            var HaltHere = 1;
          }
          /**
           * End extraneous code
           */
          /*
          oCallback = kwSearch.ContentSearch.Util.aCallbacks[sSearchTiming][i];
          oCallback( sArguments );
          */
          kwSearch.ContentSearch.Util.aCallbacks[sSearchTiming][i].call( kwSearch.ContentSearch.Util.aCallbacks[sSearchTiming][i], sArguments );
        }
      }
    }
  }
}

kwSearch.ContentSearch.StreamContent = {

  sRequestPage        : '',
  oRequest            : null,
  bScrolling          : false,
  bUpdating           : false,
  bAjaxRequest        : true,
  oResultView         : null,

  setRequestPage : function( sRequestPage )
  {
    kwSearch.ContentSearch.StreamContent.sRequestPage = sRequestPage;
  },

  setAjaxRequest : function( bAjaxRequest )
  {
    kwSearch.ContentSearch.StreamContent.bAjaxRequest = bAjaxRequest;
  },

  startContentSearch : function()
  {
    var oSearchContainer = document.getElementById( kwSearch.ResultView.getContainerId()  );
    if( oSearchContainer )
    {
      oSearchContainer.innerHTML = '';
    }

    kwSearch.ResultView.clearMessage();
    kwSearch.ContentSearch.StreamContent.oResultView = kwSearch.ResultView.produceHandler();

    $( window ).bind( 'scroll', kwSearch.ContentSearch.StreamContent.scrollContentSearch );

    kwSearch.ContentSearch.StreamContent.bScrolling = false;
    kwSearch.ContentSearch.StreamContent.bUpdating  = false;

    kwSearch.ContentSearch.StreamContent.sendRequest();
  },

  scrollContentSearch : function()
  {
    var oSearchContents = null;
    var oSearchContainer = document.getElementById( kwSearch.ResultView.getContainerId() );
    if( oSearchContainer )
    {
      oSearchContents = oSearchContainer.innerHTML.toLowerCase();
      oSearchContents = oSearchContents.replace( /\n|\r/g, '' );
    }

    if((( PageDimensions.getPageHeight() - PageDimensions.getScrollHeight() < PageDimensions.getScrollWindowSize()) ||
        ( oSearchContents && oSearchContents == '' )) &&
       ( !kwSearch.ContentSearch.StreamContent.bScrolling ) &&
       ( !kwSearch.ContentSearch.StreamContent.bUpdating ))
    {
      kwSearch.ContentSearch.StreamContent.bScrolling = true;
      kwSearch.ContentSearch.StreamContent.sendRequest();
    }
  },

  addContentSearchData : function( oServerResponse )
  {
    kwSearch.ContentSearch.StreamContent.bScrolling = true;
    kwSearch.ContentSearch.StreamContent.bUpdating  = true;

    kwSearch.ContentSearch.StreamContent.oResultView.setData( oServerResponse ).render();

    kwSearch.ContentSearch.StreamContent.oRequest   = null;
    kwSearch.ContentSearch.StreamContent.bUpdating  = false;
    kwSearch.ContentSearch.StreamContent.bScrolling = false;

    kwSearch.ContentSearch.Util.executeSearchCallback( 'Mid', kwSearch.ContentSearch.StreamContent.bUpdating );
  },

  endContentSearch : function()
  {
    $( window ).unbind( 'scroll', kwSearch.ContentSearch.StreamContent.scrollContentSearch );

    kwSearch.ContentSearch.StreamContent.bScrolling = false;
    kwSearch.ContentSearch.StreamContent.bUpdating  = false;

    kwSearch.ContentSearch.Util.executeSearchCallback( 'Post' );
  },

  sendRequest : function()
  {
    if( kwSearch.ContentSearch.StreamContent.oRequest !== null )
    {
      kwSearch.ContentSearch.StreamContent.oRequest.abort();
    }
    if(( !kwSearch.ContentSearch.StreamContent.bUpdating ) &&
       ( kwSearch.ContentSearch.StreamContent.sRequestPage ))
    {
      kwSearch.ContentSearch.Util.executeSearchCallback( 'Pre' );

      if( kwSearch.ContentSearch.StreamContent.bAjaxRequest )
      {
        var oSearchForm = kwSearch.SearchForm.getSearchForm();
        var oRequestParams = {
          url     : kwSearch.ContentSearch.StreamContent.sRequestPage,
          success : kwSearch.ContentSearch.StreamContent.addContentSearchData,
          error   : kwSearch.ContentSearch.StreamContent.errorHandler,
          type    : 'POST',
          dataType: 'json'
        };

        if( typeof oSearchForm !== 'undefined' && oSearchForm !== null )
        {
          oRequestParams['data'] = $(oSearchForm).serialize();
          kwSearch.ContentSearch.StreamContent.oRequest = $.ajax( oRequestParams );
        }
        else
        {
          kwSearch.ContentSearch.StreamContent.oRequest = $.ajax( oRequestParams );
        }
      }
      else
      {
        kwSearch.SearchForm.submit();
      }
    }
  },

  errorHandler : function( oXHR, sTextStatus )
  {
    kwSearch.ContentSearch.StreamContent.bScrolling = false;
    kwSearch.ContentSearch.StreamContent.bUpdating  = false;

    $( window ).unbind( 'scroll', kwSearch.ContentSearch.StreamContent.scrollContentSearch );

    kwSearch.ContentSearch.StreamContent.oRequest = null;

    kwSearch.ContentSearch.Util.executeSearchCallback( 'Post' );

    if( sTextStatus != 'abort' )
    {
      kwSearch.ResultView.displayMessage( 'Unable to request results at this time, please try again.' );
    }
  }
};

PageDimensions = {
  /**
   * Arbitrary number of pixels dictating the size of a 'scroll window' (ie, the
   * number of pixels a user scrolls before encountering a new 'scroll window'
   */
  iScrollingWindowSize  : 500,

  getPageHeight : function()
  {
    var y;
    if( document.body.scrollHeight > document.body.offsetHeight )
    {
      y = document.body.scrollHeight;
    }
    else
    {
      y = document.body.offsetHeight;
    }
    return parseInt( y );
  },

  getWindowHeight : function()
  {
    var y;

    if( self.innerWidth )
    {
      y = self.innerHeight;
    }
    else if( document.documentElement && document.documentElement.clientWidth )
    {
      y = document.documentElement.clientHeight;
    }
    else if( document.body )
    {
      y = document.body.clientHeight;
    }
    return parseInt( y );
  },

  getScrollHeight : function()
  {
    var y;
    // all except Explorer
    if( self.pageYOffset )
    {
      y = self.pageYOffset;
    }
    else if( document.documentElement && document.documentElement.scrollTop )
    {
      y = document.documentElement.scrollTop;
    }
    else if( document.body )
    {
      y = document.body.scrollTop;
    }
    return parseInt( y ) + PageDimensions.getWindowHeight();
  },

  getScrollWindowSize : function()
  {
    return PageDimensions.iScrollingWindowSize;
  },

  setScrollWindowSize : function( iScrollingWindowSize )
  {
    PageDimensions.iScrollingWindowSize = iScrollingWindowSize;
  }
};

