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

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

  Words : {
    sDefaultSearchType : 'Query',

    sSortType     : '',
    sWords        : '',
    sInclusivity  : '',

    addToSearch : function()
    {
      var oSearch = { "searchText"  : unescape( kwSearch.Widgets.Words.sWords ),
                      "sortType"    : kwSearch.Widgets.Words.sSortType,
                      "inclusivity" :  kwSearch.Widgets.Words.sInclusivity
                    };

      kwSearch.Widgets.Util.executeWidgetCallback( 'Words', oSearch );

      kwSearch.ContentSearch.addRequirement( 'Words', oSearch );
      kwSearch.SearchForm.setSearchType( 'Search' );
    },

    setWords : function( sWords )
    {
      if( kwSearch.Widgets.Words.sWords != sWords )
      {
        kwSearch.Widgets.Words.sWords = sWords;
        kwSearch.Widgets.Words.addToSearch();

        if( kwSearch.Widgets.Words.sWords == '' )
        {
          kwSearch.Widgets.Words.sDefaultSearchType = 'Query';
          kwSearch.SearchForm.setSearchType( '' );
        }
        else
        {
          kwSearch.Widgets.Words.sDefaultSearchType = 'Search';
        }
      }
      else
      {
        kwSearch.SearchForm.setSearchType( 'Search' );
      }
    },

    setSortType : function( sSortType )
    {
      kwSearch.Widgets.Words.sSortType = sSortType;
      kwSearch.Widgets.Words.addToSearch();

      kwSearch.SearchForm.setSearchSort( '', '' );
    },

    setInclusivity : function( sInclusivity )
    {
      kwSearch.Widgets.Words.sInclusivity = sInclusivity;

      if( $.trim( kwSearch.Widgets.Words.sWords ) != '' )
      {
        kwSearch.Widgets.Words.addToSearch();
      }
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
        if( oState.sortType )
        {
          kwSearch.Widgets.Words.setSortType( oState.sortType );
        }
        if( oState.inclusivity )
        {
          kwSearch.Widgets.Words.setInclusivity( oState.inclusivity );
        }
        if( oState.searchText )
        {
          kwSearch.Widgets.Words.setWords( oState.searchText );
        }
      }
    },

    isWordsSet : function()
    {
      var retval = false;

      if(( kwSearch.Widgets.State.isExpanded( 'Words' )) &&
         ( kwSearch.Widgets.Words.sWords != '' ))
      {
        retval = true;
      }
      return retval;
    },

    deactivate : function()
    {
      kwSearch.Widgets.Words.removeFromSearch();

      return true;
    },

    removeFromSearch : function()
    {
      kwSearch.SearchForm.setSearchType( '' );
      kwSearch.Widgets.Util.removeFromSearch( 'Words' );
    }
  },

  Who : {
    sDefaultSearchType : 'Search',

    aWhoList : {},

    setWho : function( iWhoId, sWhoName )
    {
      kwSearch.Widgets.Who.aWhoList = {};

      kwSearch.Widgets.Who.addWho( iWhoId, sWhoName );
    },

    addWho : function( iWhoId, sWhoName )
    {
      var iTmpId    = iWhoId;
      var iTmpName  = sWhoName;
      if( !sWhoName )
      {
        if(( typeof iWhoId != 'undefined' ) &&
           ( typeof iWhoId['id'] != 'undefined' ) &&
           ( typeof iWhoId['name'] != 'undefined' ))
        {
          iTmpId    = iWhoId['id'];
          iTmpName  = iWhoId['name'];
        }
      }
      if( typeof iTmpId != 'undefined' )
      {
        var oTmp      = {};
        oTmp[iTmpId]  = {'id' : iTmpId, 'name' : iTmpName};
        kwSearch.Widgets.Who.addToSearch( oTmp );
      }
    },

    removeWho : function( iWhoId, sWhoName )
    {
      if(( typeof kwSearch.Widgets.Who.aWhoList[iWhoId] != 'undefined' ) &&
         ( kwSearch.Widgets.Who.aWhoList[iWhoId]['name'] == sWhoName ))
      {
        delete kwSearch.Widgets.Who.aWhoList[iWhoId];
        kwSearch.Widgets.Who.addToSearch( kwSearch.Widgets.Who.aWhoList );
      }
    },

    addToSearch : function( oWho )
    {
      if( typeof oWho == 'string' )
      {
        oWho = JSON.parse( oWho );
      }
      if( typeof oWho == 'object' )
      {
        for( sKey in oWho )
        {
          kwSearch.Widgets.Who.aWhoList[sKey] = oWho[sKey];
        }
      }
      kwSearch.Widgets.Util.executeWidgetCallback( 'Who', kwSearch.Widgets.Who.aWhoList );

      kwSearch.ContentSearch.addRequirement( 'Who', kwSearch.Widgets.Who.aWhoList );

      kwSearch.SearchForm.setSearchType( 'Search' );
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
        kwSearch.Widgets.Who.addToSearch( oState );
      }
    },

    removeFromSearch : function()
    {
      var sNotSearchType = '';
      if( kwSearch.Widgets.State.getExpandedWidgets().length > 0 )
      {
        sNotSearchType = 'Search';
      }
      kwSearch.SearchForm.setSearchType( '', sNotSearchType );
      kwSearch.Widgets.Util.removeFromSearch( 'Who' );
    }
  },

  Where : {
    sDefaultSearchType : 'Search',

    oLocations : {},

    addWhere : function( iWhereId, sWhereName )
    {
      // START HERE THOR
      var iTmpId    = iWhereId;
      var iTmpName  = sWhereName;
      if( !sWhereName )
      {
        if(( typeof iWhereId['id'] != 'undefined' ) &&
           ( typeof iWhereId['name'] != 'undefined' ))
        {
          iTmpId    = iWhereId['id'];
          iTmpName  = iWhereId['name'];
        }
      }
      if( typeof iTmpId != 'undefined' )
      {
        var oTmp      = {};
        oTmp[iTmpId]  = iTmpName;
        kwSearch.Widgets.Where.addToSearch( oTmp );
      }
    },

    removeWhere : function( iWhereId, sWhereName )
    {
      if(( typeof kwSearch.Widgets.Where.oLocations[iWhereId] != 'undefined' ) &&
         ( typeof kwSearch.Widgets.Where.oLocations[iWhereId] != 'undefined' ) &&
         ( kwSearch.Widgets.Where.oLocations[iWhereId] == sWhereName ))
      {
        delete kwSearch.Widgets.Where.oLocations[iWhereId];

        kwSearch.Widgets.Where.addToSearch( kwSearch.Widgets.Where.oLocations );
      }
    },

    resetWhere : function()
    {
      kwSearch.Widgets.Where.oLocations = {};
    },

    addToSearch : function( oWhere )
    {
      if( typeof oWhere == 'string' )
      {
        oWhere = JSON.parse( oWhere );
      }
      if( typeof oWhere == 'object' )
      {
        /**
         * Right now, the functionality is that we'll be getting all the teams
         * at once, as opposed to one team at a time.  If functionality is ever
         * added such that the user can select one team at a time then something
         * will be necessary allowing for the removal of teams/locations from the
         * search.
         */
        kwSearch.Widgets.Where.oLocations = {};
        for( sKey in oWhere )
        {
          kwSearch.Widgets.Where.oLocations[sKey] = oWhere[sKey];
        }
      }
      kwSearch.Widgets.Util.executeWidgetCallback( 'Where', kwSearch.Widgets.Where.oLocations );

      kwSearch.ContentSearch.addRequirement( 'Where', kwSearch.Widgets.Where.oLocations );

      /**
       * I'm not convinced that WHERE should be changing the search type.
       * I'm leaving this in here in the event that it is later needed.
       */
//      kwSearch.SearchForm.setSearchType( 'Search' );
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
        kwSearch.Widgets.Where.addToSearch( oState );
      }
    },

    activate : function()
    {
      kwSearch.Widgets.Where.addToSearch();

      return true;
    },

    deactivate : function()
    {
      kwSearch.Widgets.Where.removeFromSearch();

      return true;
    },

    removeFromSearch : function()
    {
      var sNotSearchType = '';
      if( kwSearch.Widgets.State.getExpandedWidgets().length > 0 )
      {
        sNotSearchType = 'Search';
      }
      kwSearch.SearchForm.setSearchType( '', sNotSearchType );
      kwSearch.Widgets.Util.removeFromSearch( 'Where' );

      kwSearch.Widgets.Util.executeWidgetCallback( 'Where', {} );
    }
  },

  Offering : {
    sDefaultSearchType : 'Query',

    oOfferings : {},
    oTeamIds   : {},
    oQueries   : {},

    addToSearch : function( oOffering, oQuerySettings )
    {
      if( typeof oOffering == 'undefined' )
      {
        oOffering = kwSearch.Widgets.Offering.oOfferings;
      }
      else if( typeof oOffering == 'string' )
      {
        oOffering = JSON.parse( oOffering );
      }

      if( typeof oOffering == 'object' )
      {
        if( kwSearch.SearchForm.getSearchType() != 'Search' )
        {
          kwSearch.Widgets.Offering.oOfferings = {};
        }
        if( typeof oOffering.length != 'undefined' )
        {
          kwSearch.Widgets.Offering.oOfferings = oOffering;
        }
        else
        {
          for( sKey in oOffering )
          {
            kwSearch.Widgets.Offering.oOfferings[sKey] = oOffering[sKey];
          }
        }
        // 2, including 'QuerySettings'
        if(( kwSearch.Widgets.Util.countElements( kwSearch.Widgets.Offering.oOfferings ) > 2 ) &&
           ( typeof kwSearch.Widgets.Offering.oOfferings['0'] != 'undefined' ))
        {
          delete kwSearch.Widgets.Offering.oOfferings['0'];
        }
      }

      var oQuery = oQuerySettings || kwSearch.Widgets.Offering.oOfferings['QuerySettings'];
      if( typeof oQuery == 'string' )
      {
        oQuery = JSON>parse( oQuerySettings );
      }
      kwSearch.Widgets.Offering.setQueryData( oQuery );

      kwSearch.Widgets.Util.executeWidgetCallback( 'Offering', kwSearch.Widgets.Offering.oOfferings );

      kwSearch.ContentSearch.addRequirement( 'Offering', kwSearch.Widgets.Offering.oOfferings );
    },

    setQueryData : function( oQuery )
    {
      /**
       * { QueryId : '', QueryName : '' }
       */
      if( typeof oQuery == 'object' )
      {
        for( sKey in oQuery )
        {
          kwSearch.Widgets.Offering.oQueries[sKey] = oQuery[sKey];
        }
        /**
         * I'm doing this so that the "Query" specific data for the
         * Offering is stored and can be set properly the next time the
         * page loads and/or the widget is activated.
         */
        kwSearch.Widgets.Offering.oOfferings['QuerySettings'] = kwSearch.Widgets.Offering.oQueries;

        kwSearch.Widgets.Query.addToSearch( kwSearch.Widgets.Offering.oQueries, 'Offering' );
      }
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
        oQuerySettings = null;
        if( typeof oState['QuerySettings'] != 'undefined' )
        {
          oQuerySettings = oState['QuerySettings'];

          delete oState['QuerySettings'];
        }

        oTeamIds = {};
        if( typeof oState['Teams'] != 'undefined' )
        {
          oTeamIds = oState['Teams'];

          delete oState['Teams'];
        }
        kwSearch.Widgets.Offering.addToSearch( oState, oQuerySettings );
        kwSearch.Widgets.Offering.setTeams( oTeamIds );
      }
    },

    addTeams : function( oTeams )
    {
      if( typeof oTeams != 'undefined' )
      {
        for( iTeamId in oTeams )
        {
          kwSearch.Widgets.Offering.oTeamIds[iTeamId] = oTeams[iTeamId];
        }
      }
      kwSearch.Widgets.Offering.setTeams( kwSearch.Widgets.Offering.oTeamIds );
    },

    setTeams : function( oTeamIds )
    {
      if( $.sizeOf( oTeamIds ) > 0 )
      {
        kwSearch.Widgets.Offering.oTeamIds = oTeamIds;
        kwSearch.Widgets.Util.executeWidgetCallback( 'Where', kwSearch.Widgets.Offering.oTeamIds );
      }
    },

    integrateTeams : function()
    {
      if( kwSearch.Widgets.Util.countElements( kwSearch.Widgets.Offering.oTeamIds ) > 0 )
      {
        kwSearch.Widgets.Offering.oOfferings['Teams'] = kwSearch.Widgets.Offering.oTeamIds;
      }
      else
      {
        delete kwSearch.Widgets.Offering.oOfferings['Teams'];
      }
    },

    /**
     * This is called just prior to search so that the selected
     * Offerings and selected teams can be aggregated together and
     * sent back as a whole.
     */
    prepareForSearch : function()
    {
      if(( kwSearch.Widgets.State.isExpanded( 'Offering' )) &&
         ( kwSearch.SearchForm.getSearchType() == 'Search' ) &&
         ( kwSearch.Widgets.Util.countElements( kwSearch.Widgets.Offering.oOfferings ) >= 1 ))
      {
        var iSearchDelay = kwSearch.ContentSearch.setSearchDelay( -1 );

        kwSearch.Widgets.Offering.integrateTeams();

        kwSearch.ContentSearch.addRequirement( 'Offering', kwSearch.Widgets.Offering.oOfferings );

        kwSearch.ContentSearch.setSearchDelay( iSearchDelay );
      }
    },

    removeOffering : function( sOffering )
    {
      if( kwSearch.Widgets.Offering.oOfferings[sOffering] )
      {
        delete kwSearch.Widgets.Offering.oOfferings[sOffering];

        var iSelectedOfferings = kwSearch.Widgets.Util.countElements( kwSearch.Widgets.Offering.oOfferings );
        if(( iSelectedOfferings == 1 ) &&
           ( typeof kwSearch.Widgets.Offering.oOfferings['QuerySettings'] != 'undefined' ))
        {
          delete kwSearch.Widgets.Offering.oOfferings['QuerySettings'];

          iSelectedOfferings = 0;
        }

        kwSearch.Widgets.Util.executeWidgetCallback( 'Offering', kwSearch.Widgets.Offering.oOfferings );
        if( iSelectedOfferings == 0 )
        {
          kwSearch.Widgets.Offering.removeFromSearch();
        }
        else
        {
          kwSearch.ContentSearch.addRequirement( 'Offering', kwSearch.Widgets.Offering.oOfferings );
        }
      }
    },

    activate : function()
    {
      kwSearch.Widgets.Offering.addToSearch();

      return true;
    },

    deactivate : function()
    {
      kwSearch.Widgets.Offering.removeFromSearch();

      return true;
    },

    removeFromSearch : function()
    {
      var sNotSearchType = '';
      if( kwSearch.Widgets.State.getExpandedWidgets().length > 0 )
      {
        sNotSearchType = 'Search';
      }
      kwSearch.SearchForm.setSearchType( '', sNotSearchType );
      kwSearch.Widgets.Util.removeFromSearch( 'Offering' );
    }
  },

  Subject : {
    sDefaultSearchType : 'Query',

    oSubjects : {},
    oTeamId : {},
    oQueries : {},
    aDocumentType : [],

    setDocumentType: function( aDocumentTypes )
    {
      if( aDocumentTypes instanceof Array )
      {
        kwSearch.Widgets.Subject.aDocumentType = aDocumentTypes;
      }
      else if( typeof aDocumentTypes === 'string' )
      {
        kwSearch.Widgets.Subject.aDocumentType.push( aDocumentTypes );
      }

      kwSearch.Widgets.Subject.addToSearch();
    },

    _getSubjectsForSearch : function( bClearSubjectName )
    {
      var oSubjectRequirements = {};

      for( sKey in kwSearch.Widgets.Subject.oSubjects )
      {
        if(( sKey == 'Teams' ) || ( sKey == 'QuerySettings' ) || ( sKey == 'DocumentType' ))
        {
          oSubjectRequirements[sKey] = kwSearch.Widgets.Subject.oSubjects[sKey];
        }
        else
        {
          if(( typeof bClearSubjectName != 'undefined' ) && ( bClearSubjectName ))
          {
            /**
             * We are doing this so that the search is performed only
             * against the Subject ID; Subject Names can be duplicated
             * within the taxonomy.
             */
            oSubjectRequirements[sKey] = '';
          }
          else
          {
            oSubjectRequirements[sKey] = kwSearch.Widgets.Subject.oSubjects[sKey];
          }
        }
      }

      return oSubjectRequirements;
    },

    addToSearch : function( oSubject, oQuerySettings )
    {
      if( typeof oSubject == 'undefined' )
      {
        oSubject = kwSearch.Widgets.Subject.oSubjects;
      }
      else if( typeof oSubject == 'string' )
      {
        oSubject = JSON.parse( oSubject );
      }

      if( kwSearch.Widgets.Subject.aDocumentType instanceof Array && kwSearch.Widgets.Subject.aDocumentType.length > 0 )
      {
        oSubject.DocumentType = kwSearch.Widgets.Subject.aDocumentType;
      }

      if( typeof oSubject == 'object' )
      {
        kwSearch.Widgets.Subject.oSubjects = {};
        for( var sKey in oSubject )
        {
          kwSearch.Widgets.Subject.oSubjects[sKey] = oSubject[sKey];
        }
        // 2, including 'QuerySettings'
        if(( kwSearch.Widgets.Util.countElements( kwSearch.Widgets.Subject.oSubjects ) > 2 ) &&
           ( typeof kwSearch.Widgets.Subject.oSubjects['0'] != 'undefined' ))
        {
          delete kwSearch.Widgets.Subject.oSubjects['0'];
        }
      }

      var oQuery = oQuerySettings || kwSearch.Widgets.Subject.oSubjects['QuerySettings'];
      if( typeof oQuery == 'string' )
      {
        oQuery = JSON.parse( oQuerySettings );
      }
      kwSearch.Widgets.Subject.setQueryData( oQuery );

      kwSearch.Widgets.Util.executeWidgetCallback( 'Subject', kwSearch.Widgets.Subject.oSubjects );

      kwSearch.ContentSearch.addRequirement( 'Subject', kwSearch.Widgets.Subject._getSubjectsForSearch());
    },

    setQueryData : function( oQuery )
    {
      /**
       * { QueryId : '', QueryName : '' }
       */
      if( typeof oQuery == 'object' )
      {
        for( sKey in oQuery )
        {
          kwSearch.Widgets.Subject.oQueries[sKey] = oQuery[sKey];
        }
        /**
         * I'm doing this so that the "Query" specific data for the
         * Subject is stored and can be set properly the next time the
         * page loads and/or the widget is activated.
         */
        kwSearch.Widgets.Subject.oSubjects['QuerySettings'] = kwSearch.Widgets.Subject.oQueries;

        kwSearch.Widgets.Query.addToSearch( kwSearch.Widgets.Subject.oQueries, 'Subject' );
      }
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
        var oQuerySettings = null;
        if( typeof oState['QuerySettings'] != 'undefined' )
        {
          oQuerySettings = oState['QuerySettings'];

          delete oState['QuerySettings'];
        }

        var oTeamIds = {};
        if( typeof oState['Teams'] != 'undefined' )
        {
          if( kwSearch.Widgets.Util.wasSearchPosted())
          {
            kwSearch.Widgets.Where.addToSearch( oState['Teams'] );
          }
          delete oState['Teams'];
        }
        kwSearch.Widgets.Subject.addToSearch( oState, oQuerySettings );
      }
    },

    setTeams : function( oTeamIds )
    {
      if( $.sizeOf( oTeamIds ) > 0 )
      {
        kwSearch.Widgets.Subject.oTeamId = oTeamIds;

        kwSearch.Widgets.Util.executeWidgetCallback( 'Where', kwSearch.Widgets.Subject.oTeamId );
        kwSearch.ContentSearch.startSearchCountdown();
      }
    },

    integrateTeams : function()
    {
      if( kwSearch.Widgets.Util.countElements( kwSearch.Widgets.Subject.oTeamId ) > 0 )
      {
        kwSearch.Widgets.Subject.oSubjects['Teams'] = kwSearch.Widgets.Subject.oTeamId;

        kwSearch.ContentSearch.addRequirement( 'Subject', kwSearch.Widgets.Subject._getSubjectsForSearch());
      }
      else
      {
        delete kwSearch.Widgets.Subject.oSubjects['Teams'];
      }
    },

    /**
     * This is called just prior to search so that the selected
     * subjects and selected teams can be aggregated together and
     * sent back as a whole.
     */
    prepareForSearch : function()
    {
      if(( kwSearch.Widgets.State.isExpanded( 'Subject' )) &&
         ( kwSearch.SearchForm.getSearchType() == 'Search' ) &&
         ( kwSearch.Widgets.Util.countElements( kwSearch.Widgets.Subject.oSubjects ) >= 1 ))
      {
        var iSearchDelay = kwSearch.ContentSearch.setSearchDelay( -1 );

        kwSearch.Widgets.Subject.integrateTeams();

        kwSearch.ContentSearch.addRequirement( 'Subject', kwSearch.Widgets.Subject._getSubjectsForSearch( true ));

        kwSearch.ContentSearch.setSearchDelay( iSearchDelay );
      }
    },

    removeSubject : function( sSubject )
    {
      if( kwSearch.Widgets.Subject.oSubjects[sSubject] )
      {
        delete kwSearch.Widgets.Subject.oSubjects[sSubject];

        var iSelectedSubjects = kwSearch.Widgets.Util.countElements( kwSearch.Widgets.Subject.oSubjects );
        if(( iSelectedSubjects == 1 ) &&
           ( typeof kwSearch.Widgets.Subject.oSubjects['QuerySettings'] != 'undefined' ))
        {
          delete kwSearch.Widgets.Subject.oSubjects['QuerySettings'];

          iSelectedSubjects = 0;
        }

        kwSearch.Widgets.Util.executeWidgetCallback( 'Subject', kwSearch.Widgets.Subject.oSubjects );
        if( iSelectedSubjects == 0 )
        {
          kwSearch.Widgets.Subject.removeFromSearch();
        }
        else
        {
          kwSearch.ContentSearch.addRequirement( 'Subject', kwSearch.Widgets.Subject._getSubjectsForSearch());
        }
      }
    },

    activate : function()
    {
      kwSearch.Widgets.Subject.addToSearch();

      kwSearch.Widgets.State.hideWidgetButton( 'What' );

      return true;
    },

    deactivate : function()
    {
      kwSearch.Widgets.Subject.removeFromSearch();

      kwSearch.Widgets.State.hideWidgetButton( 'Subject' );
      if( !kwSearch.Widgets.State.isExpanded( 'What' ))
      {
        kwSearch.Widgets.State.showWidgetButton( 'What' );

      }
      return true;
    },

    removeFromSearch : function()
    {
      $( '#ui-icon-buttons' ).hide();
      if( !(kwSearch.ResultView.getHandler() instanceof SearchView_Grid ))
      {
        kwSearch.ResultView.setHandler( new SearchView_Grid() );
      }
      var sNotSearchType = '';
      if( kwSearch.Widgets.State.getExpandedWidgets().length > 0 )
      {
        sNotSearchType = 'Search';
      }
      kwSearch.SearchForm.setSearchType( '', sNotSearchType );
      kwSearch.Widgets.Util.removeFromSearch( 'Subject' );
    }
  },

  Query : {
    sDefaultSearchType : 'Query',

    oQueries : {},

    addToSearch : function( oQuery, sQueryType )
    {
      if( typeof oQuery == 'string' )
      {
        oQuery = JSON.parse( oQuery );
      }
      if( typeof oQuery == 'object' )
      {
        kwSearch.Widgets.Query.oQueries = {};

        var iQueryId = oQuery.QueryId || 0;
        kwSearch.Widgets.Query.oQueries[iQueryId] = oQuery;
      }
      kwSearch.Widgets.Util.executeWidgetCallback( 'Query', kwSearch.Widgets.Query.oQueries, sQueryType );
      kwSearch.ContentSearch.addRequirement( 'Query', kwSearch.Widgets.Query.oQueries );
//      kwSearch.SearchForm.setSearchType( 'Query', 'Search' );
    },

    setDefaultState : function( oState, sQueryType )
    {
      if( oState )
      {
        for( var sKey in oState )
        {
          kwSearch.Widgets.Query.addToSearch( oState[sKey], sQueryType );
        }
      }
    },

    removeQuery : function( sQuery, sQueryType )
    {
      if( kwSearch.Widgets.Query.oQueries[sQuery] )
      {
        delete kwSearch.Widgets.Query.oQueries[sQuery];

        kwSearch.Widgets.Util.executeWidgetCallback( 'Query', kwSearch.Widgets.Query.oQueries, sQueryType );

        kwSearch.ContentSearch.addRequirement( 'Query', kwSearch.Widgets.Query.oQueries );
      }
    },

    removeFromSearch : function()
    {
      var sNotSearchType = '';
      if( kwSearch.Widgets.State.getExpandedWidgets().length > 0 )
      {
        sNotSearchType = 'Search';
      }
      kwSearch.SearchForm.setSearchType( '', sNotSearchType );
      kwSearch.Widgets.Util.removeFromSearch( 'Query' );
    }
  },

  What : {
    sDefaultSearchType : 'Query',

    aWhatTypes : [],

    /**
     * I needed to do this because every time I tried to prototype
     * the Array object, IE kept choking and dying.  Stupid IE...
     */
    _indexOf : function( sWhat )
    {
      var returnVal = -1;

      for( var i = 0; i < kwSearch.Widgets.What.aWhatTypes.length; i++ )
      {
        if( kwSearch.Widgets.What.aWhatTypes[i] === sWhat )
        {
          returnVal = i;
          break;
        }
      }
      return returnVal;
    },

    _addChildWhats : function()
    {
      var sWhat;
      var iKey;
      var sPushedItem;
      var aTmp;

      aTmp = kwSearch.Widgets.What.aWhatTypes;
      for( iKey in aTmp )
      {
        sWhat       = aTmp[iKey];
        sPushedItem = '';
        /**
         * Neither ResourceItem nor Journal are selectable items in the
         * interface.  As a result, we need to add them if the container
         * is also selected
         **/
        if( sWhat == 'Flightboard' )
        {
          if( kwSearch.Widgets.What._indexOf( 'ResourceItem' ) == -1 )
          {
            sPushedItem = 'ResourceItem';
          }
        }
        else if( sWhat == 'VLog' )
        {
          if( kwSearch.Widgets.What._indexOf( 'Journal' ) == -1 )
          {
            sPushedItem = 'Journal';
          }
        }
        if( sPushedItem != '' )
        {
          kwSearch.Widgets.What.aWhatTypes.push( sPushedItem );
        }
      }
    },

    _finishSettingWhatsForSearch : function()
    {
      /**
       * Change the default search type depending on the number
       * of WHATs selected.
       * This needs to go here, before the child whats are added.
       */
      if( kwSearch.Widgets.What.aWhatTypes.length == 1 )
      {
        kwSearch.Widgets.What.sDefaultSearchType = 'Query';
      }
      else
      {
        kwSearch.Widgets.What.sDefaultSearchType = 'Search';
      }

      kwSearch.Widgets.What._addChildWhats();

      if( kwSearch.Widgets.What.aWhatTypes.length == 0 )
      {
        kwSearch.ContentSearch.removeRequirement( 'What' );
      }
      else
      {
        kwSearch.ContentSearch.addRequirement( 'What', kwSearch.Widgets.What.aWhatTypes );
      }

      kwSearch.Widgets.Util.executeWidgetCallback( 'What', kwSearch.Widgets.What.aWhatTypes );

      /**
       * I'm not convinced that WHAT should be changing the search type.
       * I'm leaving this in here in the event that it is later needed.
       */
//      kwSearch.SearchForm.setSearchType( 'Query', 'Search' );
    },

    addToSearch : function( sWhat )
    {
      if( typeof sWhat == 'string' )
      {
        if( kwSearch.Widgets.What._indexOf( sWhat ) == -1 )
        {
          kwSearch.Widgets.What.aWhatTypes.push( sWhat );
        }
      }
      else if(( typeof sWhat == 'object' ) && ( sWhat.length > 0 ))
      {
        kwSearch.Widgets.What.aWhatTypes = sWhat;
      }
      kwSearch.Widgets.What._finishSettingWhatsForSearch();
    },

    getSelectedWhats : function()
    {
      return kwSearch.Widgets.What.aWhatTypes;
    },

    setWhats : function( aWhatTypes )
    {
      if(( typeof aWhatTypes != 'undefined' ) &&
         ( typeof aWhatTypes.length != 'undefined' ))
      {
        kwSearch.Widgets.What.aWhatTypes = [];

        var aTmp = [];
        for( var i = 0; i < aWhatTypes.length; i++ )
        {
          if( kwSearch.Widgets.What._indexOf( aWhatTypes[i] ) == -1 )
          {
            kwSearch.Widgets.What.aWhatTypes.push( aWhatTypes[i] );
          }
        }
        kwSearch.Widgets.What._finishSettingWhatsForSearch();
      }
    },

    removeWhat : function( sWhat )
    {
      if( sWhat )
      {
        var index = kwSearch.Widgets.What._indexOf( sWhat );
        if( index != -1 )
        {
          kwSearch.Widgets.What.aWhatTypes.splice( index, 1 );
          if( sWhat == 'Flightboard' )
          {
            kwSearch.Widgets.What.removeWhat( 'ResourceItem' );
          }
          else if( sWhat == 'VLog' )
          {
            kwSearch.Widgets.What.removeWhat( 'Journal' );
          }
        }
      }
      else
      {
        kwSearch.Widgets.What.aWhatTypes = [];
      }
      kwSearch.Widgets.Util.executeWidgetCallback( 'What', kwSearch.Widgets.What.aWhatTypes );

      if( kwSearch.Widgets.What.aWhatTypes.length == 0 )
      {
        kwSearch.ContentSearch.removeRequirement( 'What' );
      }
      else
      {
        kwSearch.ContentSearch.addRequirement( 'What', kwSearch.Widgets.What.aWhatTypes );
      }
    },

    setDefaultState : function( oState )
    {
      kwSearch.Widgets.What.addToSearch( oState );
    },

    activate : function()
    {
      /**
       * Overriding
       */
      kwSearch.Widgets.Applications.removeFromSearch();
      kwSearch.Widgets.Blogs.removeFromSearch();
      kwSearch.Widgets.Subject.removeFromSearch();

      return true;
    },

    deactivate : function()
    {
      /**
       * Overriding so that the WHATs are never removed from
       * search
       */

      return true;
    },

    removeFromSearch : function()
    {
      var sNotSearchType = '';
      if( kwSearch.Widgets.State.getExpandedWidgets().length > 0 )
      {
        sNotSearchType = 'Search';
      }
      kwSearch.SearchForm.setSearchType( '', sNotSearchType );
    }
  },

  Applications : {
    sDefaultSearchType : 'Query',

    oApplications : {},
    oQueries      : {},

    addToSearch : function( oApplications, oQuerySettings )
    {
      if( typeof oApplications == 'undefined' )
      {
        oApplications = kwSearch.Widgets.Applications.oApplications;
      }
      else if( typeof oApplications == 'string' )
      {
        oApplications = JSON.parse( oApplications );
      }

      if( typeof oApplications == 'object' )
      {
        if( kwSearch.SearchForm.getSearchType() != 'Search' )
        {
          kwSearch.Widgets.Applications.oApplications = {};
        }
        for( sKey in oApplications )
        {
          kwSearch.Widgets.Applications.oApplications[sKey] = oApplications[sKey];
        }
        // 2, including 'QuerySettings'
        if(( kwSearch.Widgets.Util.countElements( kwSearch.Widgets.Applications.oApplications ) > 2 ) &&
           ( typeof kwSearch.Widgets.Applications.oApplications['0'] != 'undefined' ))
        {
          delete kwSearch.Widgets.Applications.oApplications['0'];
        }
      }

      var oQuery = oQuerySettings || kwSearch.Widgets.Applications.oApplications['QuerySettings'];
      if( typeof oQuery == 'string' )
      {
        oQuery = JSON.parse( oQuerySettings );
      }
      kwSearch.Widgets.Applications.setQueryData( oQuery );

      kwSearch.Widgets.Util.executeWidgetCallback( 'Applications', kwSearch.Widgets.Applications.oApplications );

      kwSearch.ContentSearch.addRequirement( 'Applications', kwSearch.Widgets.Applications.oApplications );
//      kwSearch.SearchForm.setSearchType( 'Query', 'Search' );
    },

    setQueryData : function( oQuery )
    {
      /**
       * { QueryId : '', QueryName : '' }
       */
      if( typeof oQuery == 'object' )
      {
        for( sKey in oQuery )
        {
          kwSearch.Widgets.Applications.oQueries[sKey] = oQuery[sKey];
        }
        /**
         * I'm doing this so that the "Query" specific data for the
         * Application is stored and can be set properly the next time
         * the page loads and/or the widget is activated.
         */
        kwSearch.Widgets.Applications.oApplications['QuerySettings'] = kwSearch.Widgets.Applications.oQueries;

        kwSearch.Widgets.Query.addToSearch( kwSearch.Widgets.Applications.oQueries, 'Applications' );
      }
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
        oQuerySettings = null;
        if( typeof oState['QuerySettings'] != 'undefined' )
        {
          oQuerySettings = oState['QuerySettings'];

          delete oState['QuerySettings'];
        }
        kwSearch.Widgets.Applications.addToSearch( oState, oQuerySettings );
      }
    },

    removeApplications : function( sApplications )
    {
      if( kwSearch.Widgets.Applications.oApplications[sApplications] )
      {
        delete kwSearch.Widgets.Applications.oApplications[sApplications];

        var iSelectedApplications = kwSearch.Widgets.Util.countElements( kwSearch.Widgets.Applications.oApplications );
        if(( iSelectedApplications == 1 ) &&
           ( typeof kwSearch.Widgets.Applications.oApplications['QuerySettings'] != 'undefined' ))
        {
          delete kwSearch.Widgets.Applications.oApplications['QuerySettings'];

          iSelectedApplications = 0;
        }

        kwSearch.Widgets.Util.executeWidgetCallback( 'Applications', kwSearch.Widgets.Applications.oApplications );
        if( iSelectedApplications == 0 )
        {
          kwSearch.Widgets.Applications.removeFromSearch();
        }
        else
        {
          kwSearch.ContentSearch.addRequirement( 'Applications', kwSearch.Widgets.Applications.oApplications );
        }
      }
    },

    activate : function()
    {
      kwSearch.Widgets.Applications.addToSearch();

      kwSearch.Widgets.State.hideWidgetButton( 'What' );

      return true;
    },

    deactivate : function()
    {
      kwSearch.Widgets.Applications.removeFromSearch();

      kwSearch.Widgets.State.hideWidgetButton( 'Applications' );
      if( !kwSearch.Widgets.State.isExpanded( 'What' ))
      {
        kwSearch.Widgets.State.showWidgetButton( 'What' );

      }
      return true;
    },

    removeFromSearch : function()
    {
      var sNotSearchType = '';
      if( kwSearch.Widgets.State.getExpandedWidgets().length > 0 )
      {
        sNotSearchType = 'Search';
      }
      kwSearch.SearchForm.setSearchType( '', sNotSearchType );
      kwSearch.Widgets.Util.removeFromSearch( 'Applications' );
    }
  },

  Blogs : {
    sDefaultSearchType : 'Query',

    oBlogs    : {},
    oQueries  : {},

    addToSearch : function( oBlogs, oQuerySettings )
    {
      if( typeof oBlogs == 'undefined' )
      {
        oBlogs = kwSearch.Widgets.Blogs.oBlogs;
      }
      else if( typeof oBlogs == 'string' )
      {
        oBlogs = JSON.parse( oBlogs );
      }

      if( typeof oBlogs == 'object' )
      {
        if( kwSearch.SearchForm.getSearchType() != 'Search' )
        {
          kwSearch.Widgets.Blogs.oBlogs = {};
        }
        kwSearch.Widgets.Blogs.oBlogs = {};
        for( sKey in oBlogs )
        {
          kwSearch.Widgets.Blogs.oBlogs[sKey] = oBlogs[sKey];
        }
        // 2, including 'QuerySettings'
        if(( kwSearch.Widgets.Util.countElements( kwSearch.Widgets.Blogs.oBlogs ) > 2 ) &&
           ( typeof kwSearch.Widgets.Blogs.oBlogs['0'] != 'undefined' ))
        {
          delete kwSearch.Widgets.Blogs.oBlogs['0'];
        }
      }

      var oQuery = oQuerySettings || kwSearch.Widgets.Blogs.oBlogs['QuerySettings'];
      if( typeof oQuery == 'string' )
      {
        oQuery = JSON.parse( oQuerySettings );
      }
      kwSearch.Widgets.Blogs.setQueryData( oQuery );

      kwSearch.Widgets.Util.executeWidgetCallback( 'Blogs', kwSearch.Widgets.Blogs.oBlogs );

      kwSearch.ContentSearch.addRequirement( 'Blogs', kwSearch.Widgets.Blogs.oBlogs );
    },

    setQueryData : function( oQuery )
    {
      /**
       * { QueryId : '', QueryName : '' }
       */
      if( typeof oQuery == 'object' )
      {
        for( sKey in oQuery )
        {
          kwSearch.Widgets.Blogs.oQueries[sKey] = oQuery[sKey];
        }
        /**
         * I'm doing this so that the "Query" specific data for the
         * Application is stored and can be set properly the next time
         * the page loads and/or the widget is activated.
         */
        kwSearch.Widgets.Blogs.oBlogs['QuerySettings'] = kwSearch.Widgets.Blogs.oQueries;

        kwSearch.Widgets.Query.addToSearch( kwSearch.Widgets.Blogs.oQueries, 'VLog' );
      }
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
        oQuerySettings = null;
        if( typeof oState['QuerySettings'] != 'undefined' )
        {
          oQuerySettings = oState['QuerySettings'];

          delete oState['QuerySettings'];
        }
        kwSearch.Widgets.Blogs.addToSearch( oState, oQuerySettings );

        var oTeamIds  = {};
        var iTeamId   = 0;
        var sTeamName = '';
        for( sKey in oState )
        {
          if( typeof oState[sKey]['Team'] != 'undefined' )
          {
            iTeamId   = oState[sKey]['Team']['TeamId'];
            sTeamName = oState[sKey]['Team']['TeamName'];

            oTeamIds[iTeamId] = sTeamName;
          }
        }
        if( $.sizeOf( oTeamIds ) > 0 )
        {
          kwSearch.Widgets.Util.executeWidgetCallback( 'Where', oTeamIds );
        }
      }
    },

    removeBlogs : function( sBlogs )
    {
      if( kwSearch.Widgets.Blogs.oBlogs[sBlogs] )
      {
        delete kwSearch.Widgets.Blogs.oBlogs[sBlogs];

        var iSelectedBlogs = kwSearch.Widgets.Util.countElements( kwSearch.Widgets.Blogs.oBlogs );
        if(( iSelectedBlogs == 1 ) &&
           ( typeof kwSearch.Widgets.Blogs.oBlogs['QuerySettings'] != 'undefined' ))
        {
          delete kwSearch.Widgets.Blogs.oBlogs['QuerySettings'];

          iSelectedBlogs = 0;
        }

        kwSearch.Widgets.Util.executeWidgetCallback( 'Blogs', kwSearch.Widgets.Blogs.oBlogs );
        if( iSelectedBlogs == 0 )
        {
          kwSearch.Widgets.Blogs.removeFromSearch();
        }
        else
        {
          kwSearch.ContentSearch.addRequirement( 'Blogs', kwSearch.Widgets.Blogs.oBlogs );
        }
      }
    },

    activate : function()
    {
      kwSearch.Widgets.Blogs.addToSearch();

      kwSearch.Widgets.State.hideWidgetButton( 'What' );

      return true;
    },

    deactivate : function()
    {
      kwSearch.Widgets.Blogs.removeFromSearch();

      kwSearch.Widgets.State.hideWidgetButton( 'Blogs' );
      if( !kwSearch.Widgets.State.isExpanded( 'What' ))
      {
        kwSearch.Widgets.State.showWidgetButton( 'What' );

      }
      return true;
    },

    removeFromSearch : function()
    {
      var sNotSearchType = '';
      if( kwSearch.Widgets.State.getExpandedWidgets().length > 0 )
      {
        sNotSearchType = 'Search';
      }
      kwSearch.SearchForm.setSearchType( '', sNotSearchType );
      kwSearch.Widgets.Util.removeFromSearch( 'Blogs' );
    }
  },

  SavedSearches : {
    sDefaultSearchType : 'Search',

    sSavedSearchRequirements    : '',
    sOriginalSearchRequirements : '',

    addToSearch : function( sSavedSearchRequirements )
    {
      var bPerformSearch = false;

      sSavedSearchRequirements = sSavedSearchRequirements || kwSearch.Widgets.SavedSearches.sSavedSearchRequirements;
      if(( sSavedSearchRequirements ) && ( sSavedSearchRequirements != '' ))
      {
        kwSearch.Widgets.SavedSearches.sSavedSearchRequirements = sSavedSearchRequirements;
        if( kwSearch.Widgets.SavedSearches.sOriginalSearchRequirements == '' )
        {
          kwSearch.Widgets.SavedSearches.sOriginalSearchRequirements = kwSearch.SearchForm.getBaseSearchRequirements();
        }

        kwSearch.Widgets.SavedSearches.runSavedSearch( sSavedSearchRequirements );
      }
    },

    runSavedSearch : function( sBaseSearchRequirements )
    {
      var iSearchDelay = kwSearch.ContentSearch.setSearchDelay( -1 );

      var oRegisteredWidgets = kwSearch.Widgets;//.State.getRegisteredWidgets();
      var sWidgetName;

      var oBaseSearchRequirements = JSON.parse( sBaseSearchRequirements );
      for( sWidgetName in oRegisteredWidgets )
      {
        /**
         * Scrub the widget's default state to prepare for saved search
         */
        if(( kwSearch.Widgets[sWidgetName] ) &&
           ( typeof kwSearch.Widgets[sWidgetName].setDefaultState == 'function' ))
        {
//          kwSearch.Widgets[sWidgetName].setDefaultState( {} );
        }
        if( typeof oBaseSearchRequirements[sWidgetName] != 'undefined' )
        {
          kwSearch.Widgets.Util.activateWidget( sWidgetName );
        }
        else
        {
          if( sWidgetName != 'SavedSearches' )
          {
            kwSearch.Widgets.Util.deactivateWidget( sWidgetName );
          }
        }
      }
      kwSearch.SearchForm.setSearchType( 'Search' );
      kwSearch.SearchForm.setBaseSearchRequirements( oBaseSearchRequirements );

      kwSearch.Widgets.Util.setDefaultState( true );
      kwSearch.ContentSearch.stopSearchCountdown();
      kwSearch.ContentSearch.setSearchDelay( iSearchDelay );
    },

    deactivate : function()
    {
      if( kwSearch.Widgets.SavedSearches.sOriginalSearchRequirements !== '' )
      {
        var oBaseSearchRequirements = JSON.parse( kwSearch.Widgets.SavedSearches.sOriginalSearchRequirements );

        kwSearch.SearchForm.setBaseSearchRequirements( oBaseSearchRequirements );

        kwSearch.Widgets.SavedSearches.runSavedSearch( kwSearch.Widgets.SavedSearches.sOriginalSearchRequirements );
      }

      kwSearch.Widgets.SavedSearches.sOriginalSearchRequirements = '';

      kwSearch.Widgets.State.moveWidget( 'SavedSearches', kwSearch.Widgets.State.expanded, kwSearch.Widgets.State.collapsed );

      return true;
    }
  },

  WorkflowApps : {
    sDefaultSearchType : 'Search',

    addToSearch : function( oSelectedOption )
    {
      kwSearch.Widgets.Util.executeWidgetCallback( 'WorkflowApps', oSelectedOption );
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
      }
    },

    removeFromSearch : function()
    {
      kwSearch.Widgets.Util.removeFromSearch( 'WorkflowApps' );
    }
  },

  WorkflowAppJobs : {
    sDefaultSearchType : 'Search',

    addToSearch : function( oSelectedOption )
    {
      kwSearch.Widgets.Util.executeWidgetCallback( 'WorkflowAppJobs', oSelectedOption );
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
      }
    },

    removeFromSearch : function()
    {
      kwSearch.Widgets.Util.removeFromSearch( 'WorkflowAppJobs' );
    }
  },

  // TODO : implement
  Slidey : {
    sDefaultSearchType : 'Search',

    addToSearch : function()
    {
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
      }
    },

    removeFromSearch : function()
    {
      kwSearch.Widgets.Util.removeFromSearch( 'Slidey' );
    }
  },

  SubTypes : {
    /**
     * The default search type is not set here because adding
     * sub-types should not interfere with expected queries.
     * Additionally, with this being only a meta-widget, it should
     * be up to the actual widgets to define what the search type
     * should be.
     */
    sDefaultSearchType : '',
    oSubTypes          : {},

    addSubTypeToSearch : function( sSubType, sSubTypeValue, sType )
    {
      if(( !sType ) || ( $.trim( sType ) === '' ))
      {
        sType = 'Global';
      }

      if( typeof kwSearch.Widgets.SubTypes.oSubTypes[sType] === 'undefined' )
      {
        kwSearch.Widgets.SubTypes.oSubTypes[sType] = {};
      }
      if( typeof kwSearch.Widgets.SubTypes.oSubTypes[sType][sSubType] === 'undefined' )
      {
        kwSearch.Widgets.SubTypes.oSubTypes[sType][sSubType] = {};
      }
      kwSearch.Widgets.SubTypes.oSubTypes[sType][sSubType][sSubTypeValue] = sSubTypeValue;

      kwSearch.Widgets.SubTypes.addToSearch();
    },

    addToSearch : function()
    {
      kwSearch.ContentSearch.addRequirement( 'SubTypes', kwSearch.Widgets.SubTypes.oSubTypes );
      /*kwSearch.SearchForm.setSearchType( 'Search' );*/
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
        if( typeof oState['DefaultSearchType'] !== 'undefined' )
        {
          kwSearch.Widgets.SubTypes.sDefaultSearchType = oState['DefaultSearchType'];

          delete oState['DefaultSearchType'];
        }
        kwSearch.Widgets.SubTypes.oSubTypes = oState;

        kwSearch.Widgets.SubTypes.addToSearch();
      }
    },

    resetSubTypes : function()
    {
      kwSearch.Widgets.SubTypes.oSubTypes = {};

      kwSearch.ContentSearch.addRequirement( 'SubTypes', kwSearch.Widgets.SubTypes.oSubTypes );
      kwSearch.SearchForm.setSearchType( '' );
    },

    removeTypeFromSearch : function( sType )
    {
      if(( sType ) &&
         ( $.trim( sType ) !== '' ) &&
         ( typeof kwSearch.Widgets.SubTypes.oSubTypes[sType] !== 'undefined' ))
      {
        delete kwSearch.Widgets.SubTypes.oSubTypes[sType];

        kwSearch.Widgets.SubTypes.addToSearch();
      }
    },

    removeSubTypeFromSearch : function( sType, sSubType )
    {
      if(( sType ) &&
         ( sSubType ) &&
         ( $.trim( sType ) !== '' ) &&
         ( $.trim( sSubType ) !== '' ) &&
         ( typeof kwSearch.Widgets.SubTypes.oSubTypes[sType] !== 'undefined' ) &&
         ( typeof kwSearch.Widgets.SubTypes.oSubTypes[sType][sSubType] !== 'undefined' ))
      {
        delete kwSearch.Widgets.SubTypes.oSubTypes[sType][sSubType];

        kwSearch.Widgets.SubTypes.addToSearch();
      }
    },

    removeFromSearch : function()
    {
      kwSearch.Widgets.Util.removeFromSearch( 'SubTypes' );
    }
  },

  Projects: {
    sDefaultSearchType: 'Search',
    oProjectsList: {},
    _getProjectsForSearch : function()
    {
      /*
       * We strip the name out for the search because there could be many
       * projects by the same name, so it's ID we care about.
       */
      var oProjectRequirements = {};

      for( sKey in kwSearch.Widgets.Projects.oProjectsList )
      {
        oProjectRequirements[sKey] = '';
      }

      return oProjectRequirements;
    },
    addProject: function( Arg1, Arg2 )
    {
      var oProject, oForAdd;

      if( arguments.length === 1 )
      {
        oProject = Arg1;
      }
      else if(  arguments.length === 2  )
      {
        oProject = {
          id: Arg1,
          name: Arg2
        };
      }

      if( typeof oProject === 'object' && oProject !== null &&
          ( typeof oProject.id === 'number' ||
            ( typeof oProject.id === 'string' && ! isNaN( oProject.id ) )
          ) &&
          typeof oProject.name === 'string' && oProject.name !== ''
        )
      {
        oForAdd = {};
        oForAdd[oProject.id] = oProject;
        kwSearch.Widgets.Projects.addToSearch( oForAdd );
      }
    },
    removeProject: function( iProjectId, sProjectName )
    {
      if( typeof kwSearch.Widgets.Projects.oProjectsList[iProjectId] === 'object' &&
          kwSearch.Widgets.Projects.oProjectsList[iProjectId] !== null &&
          kwSearch.Widgets.Projects.oProjectsList[iProjectId].name === sProjectName
        )
      {
        delete kwSearch.Widgets.Projects.oProjectsList[iProjectId];
        kwSearch.Widgets.Projects.addToSearch( kwSearch.Widgets.Projects.oProjectsList );
      }
    },
    addToSearch: function( oProjects )
    {
      var key;

      if( typeof oProjects === 'string' )
      {
        try
        {
          oProjects = JSON.parse( oProjects );
        }
        catch( e ){}
      }

      if( typeof oProjects === 'object' && oProjects !== null )
      {
        for( key in oProjects )
        {
          kwSearch.Widgets.Projects.oProjectsList[key] = oProjects[key];
        }
      }

      kwSearch.Widgets.Util.executeWidgetCallback( 'Projects', kwSearch.Widgets.Projects.oProjectsList );
      kwSearch.ContentSearch.addRequirement( 'Projects', kwSearch.Widgets.Projects._getProjectsForSearch() );
      kwSearch.SearchForm.setSearchType( 'Search' );
    },
    setDefaultState : function( oState )
    {
      if( oState )
      {
        kwSearch.Widgets.Projects.addToSearch( oState );
      }
    },
    removeFromSearch : function()
    {
      kwSearch.Widgets.Util.removeFromSearch( 'Projects' );
    }
  },

  Tags : {
    sDefaultSearchType : 'Search',

    aTagsList : {},

    addTags : function( iTagsId, sTagsName )
    {
      var iTmpId    = iTagsId;
      var iTmpName  = sTagsName;
      if( !sTagsName )
      {
        if(( typeof iTagsId['id'] != 'undefined' ) &&
           ( typeof iTagsId['name'] != 'undefined' ))
        {
          iTmpId    = iTagsId['id'];
          iTmpName  = iTagsId['name'];
        }
      }
      if( typeof iTmpId != 'undefined' )
      {
        var oTmp      = {};
        oTmp[iTmpId]  = {'id' : iTmpId, 'name' : iTmpName};
        kwSearch.Widgets.Tags.addToSearch( oTmp );
      }
    },

    removeTags : function( iTagsId, sTagsName )
    {
      if(( typeof kwSearch.Widgets.Tags.aTagsList[iTagsId] != 'undefined' ) &&
         ( kwSearch.Widgets.Tags.aTagsList[iTagsId]['name'] == sTagsName ))
      {
        delete kwSearch.Widgets.Tags.aTagsList[iTagsId];
        kwSearch.Widgets.Tags.addToSearch( kwSearch.Widgets.Tags.aTagsList )
      }
    },

    addToSearch : function( oTags )
    {
      if( typeof oTags == 'string' )
      {
        oTags = JSON.parse( oTags );
      }
      if( typeof oTags == 'object' )
      {
        for( sKey in oTags )
        {
          kwSearch.Widgets.Tags.aTagsList[sKey] = oTags[sKey];
        }
      }
      kwSearch.Widgets.Util.executeWidgetCallback( 'Tags', kwSearch.Widgets.Tags.aTagsList );

      kwSearch.ContentSearch.addRequirement( 'Tags', kwSearch.Widgets.Tags.aTagsList );

      kwSearch.SearchForm.setSearchType( 'Search' );
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
        kwSearch.Widgets.Tags.addToSearch( oState );
      }
    },

    removeFromSearch : function() {kwSearch.Widgets.Util.removeFromSearch( 'Tags' );}
  },

  When : {
    sDefaultSearchType : 'Search',
    oDateRange         : {'StartDate' : '',
                           'EndDate'   : ''},

    getDateRange : function()
    {
      return kwSearch.Widgets.When.oDateRange;
    },

    /**
     * The argument is a Unix Timestamp
     */
    addStartDate : function( iStartDate )
    {
      kwSearch.Widgets.When.oDateRange['StartDate'] = iStartDate;
      kwSearch.Widgets.When.addToSearch();
    },

    /**
     * The argument is a Unix Timestamp
     */
    addEndDate : function( iEndDate )
    {
      kwSearch.Widgets.When.oDateRange['EndDate'] = iEndDate;
      kwSearch.Widgets.When.addToSearch();
    },

    addToSearch : function()
    {
      if(( typeof kwSearch.Widgets.When.oDateRange['StartDate'] == 'number' ) &&
         ( typeof kwSearch.Widgets.When.oDateRange['EndDate'] == 'number' ) &&
         ( kwSearch.Widgets.When.oDateRange['StartDate'] > 0  ) &&
         ( kwSearch.Widgets.When.oDateRange['EndDate'] > 0 ) &&
         ( kwSearch.Widgets.When.oDateRange['EndDate'] > kwSearch.Widgets.When.oDateRange['StartDate'] ))
      {
        kwSearch.Widgets.Util.executeWidgetCallback( 'When', kwSearch.Widgets.When.oDateRange );

        kwSearch.ContentSearch.addRequirement( 'When', kwSearch.Widgets.When.oDateRange );
      }
    },

    // TODO : implement
    setDefaultState : function( oState )
    {
      if( oState )
      {
        kwSearch.Widgets.When.oDateRange = oState;
        kwSearch.Widgets.When.addToSearch();
      }
    },

    removeFromSearch : function()
    {
      var sNotSearchType = '';
      if( kwSearch.Widgets.State.getExpandedWidgets().length > 0 )
      {
        sNotSearchType = 'Search';
      }
      kwSearch.SearchForm.setSearchType( '', sNotSearchType );
      kwSearch.Widgets.Util.removeFromSearch( 'When' );
    }
  },

  Mailbox : {
    sDefaultSearchType : 'Query',

    oMailboxInfo : {},
    oQuery : {'QueryId' : 0, 'QueryName' : 'ContentTypes_Message'},

    activate : function()
    {
      kwSearch.Widgets.Query.removeFromSearch();

      kwSearch.ContentSearch.addRequirement( 'Mailbox', kwSearch.Widgets.Mailbox.oMailboxInfo );
      kwSearch.Widgets.Mailbox.addToSearch( kwSearch.Widgets.Mailbox.oQuery );

      kwSearch.Widgets.State.moveWidget( 'Mailbox', kwSearch.Widgets.State.collapsed, kwSearch.Widgets.State.expanded );
      kwSearch.ContentSearch.performSearch();

      return true;
    },

    setMailboxOwner : function( nOwnerId, sOwnerName)
    {
      /* Wait until activate to add the owner to the search, otherwise we overwrite the defaults */
      /* Default to the inbox to start */
      kwSearch.Widgets.Mailbox.oMailboxInfo = {'nOwnerId' : nOwnerId, 'sOwnerName' : sOwnerName, 'Mailbox' : 'Inbox', 'Unread': false};
    },

    setSearchType : function()
    {
      var sSearchType = 'Query';

      /* If there is at least one of the other widgets expanded
         and set with something to search on, do a 'search' */
      if (kwSearch.Widgets.State.getExpandedWidgets().length > 1)
      {
        if ((kwSearch.Widgets.State.isExpanded( 'MessageWho' )) &&
             kwSearch.Widgets.Util.countElements(kwSearch.Widgets.MessageWho.aWhoList) > 0)
        {
          sSearchType = 'Search';
        }
        else
        if ((kwSearch.Widgets.State.isExpanded( 'Words' )) &&
             kwSearch.Widgets.Words.sWords.length > 0)
        {
          sSearchType = 'Search';
        }
        else
        if (kwSearch.Widgets.State.isExpanded( 'When' ) &&
            typeof kwSearch.Widgets.When.oDateRange['StartDate'] == 'number')
        {
          sSearchType = 'Search';
        }
        else
        if (kwSearch.Widgets.State.isExpanded( 'Tags' ) &&
            kwSearch.Widgets.Util.countElements(kwSearch.Widgets.Tags.aTagsList) > 0)
        {
          sSearchType = 'Search';
        }
      }

      kwSearch.Widgets.Mailbox.sDefaultSearchType = sSearchType;
      kwSearch.SearchForm.setSearchType( sSearchType );
    },

    setSearchDirection : function( sValue )
    {
      kwSearch.Widgets.Query.removeFromSearch();

      kwSearch.Widgets.Mailbox.setSearchType();
      kwSearch.Widgets.Mailbox.oMailboxInfo['Mailbox'] = sValue;

      if ((kwSearch.Widgets.State.isExpanded( 'MessageWho' )) &&
           kwSearch.Widgets.Util.countElements(kwSearch.Widgets.MessageWho.aWhoList) > 0)
      {
        kwSearch.Widgets.MessageWho.setSearchDirection( sValue);
      }
      else
      {
        kwSearch.Widgets.Query.addToSearch( kwSearch.Widgets.Mailbox.oQuery, 'Mailbox' );
      }
    },

    setUnread : function( bUnread )
    {
      kwSearch.Widgets.Query.removeFromSearch();

      /* Deactivate and hide the other widgets, as we the search/query is incompatible */
      kwSearch.Widgets.MessageWho.deactivate();
      kwSearch.Widgets.Words.deactivate();
      kwSearch.Widgets.State.moveWidget( 'Words', kwSearch.Widgets.State.expanded, kwSearch.Widgets.State.collapsed );
      kwSearch.Widgets.Util.removeFromSearch( 'Tags' );
      kwSearch.Widgets.State.moveWidget( 'Tags', kwSearch.Widgets.State.expanded, kwSearch.Widgets.State.collapsed );
      kwSearch.Widgets.Util.removeFromSearch( 'When' );
      kwSearch.Widgets.State.moveWidget( 'When', kwSearch.Widgets.State.expanded, kwSearch.Widgets.State.collapsed );

      kwSearch.Widgets.Mailbox.setSearchType();
      kwSearch.Widgets.Mailbox.oMailboxInfo['Unread'] = bUnread;
      kwSearch.Widgets.Query.addToSearch( kwSearch.Widgets.Mailbox.oQuery, 'Mailbox' );
    },

    getMailbox : function()
    {
      return kwSearch.Widgets.Mailbox.oMailboxInfo['Mailbox'];
    },

    addToSearch : function( sValue )
    {
      kwSearch.Widgets.Query.removeFromSearch();

      kwSearch.SearchForm.setSearchType( 'Query' );
      kwSearch.Widgets.Query.addToSearch( kwSearch.Widgets.Mailbox.oQuery, 'Mailbox' );
    },

    removeFromSearch : function()
    {
      kwSearch.SearchForm.setSearchType( '' );
      kwSearch.Widgets.Util.removeFromSearch( 'Mailbox' );
    },

    deactivate : function()
    {
      kwSearch.Widgets.Mailbox.removeFromSearch();

      return true;
    }
  },

  MessageWho : {
    sDefaultSearchType : 'Search',

    oMailboxInfo : {},
    aWhoList : {},

    activate : function()
    {
      kwSearch.Widgets.MessageWho.oMailboxInfo['Mailbox'] = kwSearch.Widgets.Mailbox.getMailbox();
      kwSearch.Widgets.State.moveWidget( 'MessageWho', kwSearch.Widgets.State.collapsed, kwSearch.Widgets.State.expanded );
      if ( kwSearch.Widgets.Util.countElements(kwSearch.Widgets.MessageWho.aWhoList) > 0)
      {
        kwSearch.Widgets.MessageWho.addToSearch( kwSearch.Widgets.MessageWho.aWhoList );
        kwSearch.ContentSearch.performSearch();
      }

      return true;
    },

    addWho : function( iWhoId, sWhoName )
    {
      var iTmpId    = iWhoId;
      var iTmpName  = sWhoName;
      if( !sWhoName )
      {
        if(( typeof iWhoId != 'undefined' ) &&
           ( typeof iWhoId['id'] != 'undefined' ) &&
           ( typeof iWhoId['name'] != 'undefined' ))
        {
          iTmpId    = iWhoId['id'];
          iTmpName  = iWhoId['name'];
        }
      }
      if( typeof iTmpId != 'undefined' )
      {
        var oTmp      = {};
        oTmp[iTmpId]  = {'id' : iTmpId, 'name' : iTmpName};
        kwSearch.Widgets.MessageWho.addToSearch( oTmp );
      }
    },

    removeWho : function( iWhoId, sWhoName )
    {
      if(( typeof kwSearch.Widgets.MessageWho.aWhoList[iWhoId] != 'undefined' ) &&
         ( kwSearch.Widgets.MessageWho.aWhoList[iWhoId]['name'] == sWhoName ))
      {
        delete kwSearch.Widgets.MessageWho.aWhoList[iWhoId];
        kwSearch.Widgets.MessageWho.addToSearch( kwSearch.Widgets.MessageWho.aWhoList );
      }
    },

    addToSearch : function( oWho )
    {
      if( typeof oWho == 'string' )
      {
        oWho = JSON.parse( oWho );
      }

      var nWho = 0;
      if( typeof oWho == 'object' )
      {
        for( sKey in oWho )
        {
          kwSearch.Widgets.MessageWho.aWhoList[sKey] = oWho[sKey];
        }
      }
      kwSearch.Widgets.Util.executeWidgetCallback( 'MessageWho', kwSearch.Widgets.MessageWho.aWhoList );

      var aTmp      = {};
      aTmp['MailboxInfo'] = kwSearch.Widgets.MessageWho.oMailboxInfo;
      aTmp['MessageWho'] = kwSearch.Widgets.MessageWho.aWhoList;

      kwSearch.ContentSearch.addRequirement( 'MessageWho', aTmp );
      kwSearch.SearchForm.setSearchType( 'Search' );
    },

    setSearchDirection : function( sValue )
    {
      kwSearch.Widgets.Query.removeFromSearch();
      kwSearch.SearchForm.setSearchType( 'Search' );
      kwSearch.Widgets.MessageWho.oMailboxInfo['Mailbox'] = sValue;
      kwSearch.Widgets.MessageWho.addToSearch( kwSearch.Widgets.MessageWho.aWhoList );
    },

    deactivate : function()
    {
      kwSearch.Widgets.Util.removeFromSearch( 'MessageWho' );
      kwSearch.Widgets.State.moveWidget( 'MessageWho', kwSearch.Widgets.State.expanded, kwSearch.Widgets.State.collapsed );
      return true;
    }
  },

  Tasks : {
    sDefaultSearchType : 'Query',

    sTaskType             : '',
    bCompletedTaskSearch  : false,

    addToSearch : function()
    {
      var oSearch = {"taskType"            : kwSearch.Widgets.Tasks.sTaskType,
                      "completedTaskSearch" : kwSearch.Widgets.Tasks.bCompletedTaskSearch};

      kwSearch.Widgets.Util.executeWidgetCallback( 'Tasks', oSearch );

      kwSearch.ContentSearch.addRequirement( 'Tasks', oSearch );
    },

    setTaskType : function( sAssignedToType )
    {
      kwSearch.Widgets.Tasks.sTaskType = sAssignedToType;

      kwSearch.Widgets.Tasks.addToSearch();
    },

    searchCompletedTasks : function( bCompletedTaskSearch )
    {
      kwSearch.Widgets.Tasks.bCompletedTaskSearch = bCompletedTaskSearch;

      kwSearch.Widgets.Tasks.addToSearch();
    },

    activate : function()
    {
      kwSearch.Widgets.State.moveWidget( 'Tasks', kwSearch.Widgets.State.collapsed, kwSearch.Widgets.State.expanded );
      kwSearch.ContentSearch.performSearch();

      return true;
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
        if( oState.taskType )
        {
          kwSearch.Widgets.Tasks.setTaskType( oState.taskType );
        }
        if( oState.completedTaskSearch )
        {
          kwSearch.Widgets.Tasks.searchCompletedTasks( oState.completedTaskSearch );
        }
      }
    },

    removeFromSearch : function()
    {
      var sNotSearchType = '';
      if( kwSearch.Widgets.State.getExpandedWidgets().length > 0 )
      {
        sNotSearchType = 'Search';
      }
      kwSearch.SearchForm.setSearchType( '', sNotSearchType );
      kwSearch.Widgets.Util.removeFromSearch( 'Tasks' );
    }
  },

  AssignedTo : {
    sDefaultSearchType : 'Query',

    aAssignedToList : {},
    sAssignedToType : '',

    setAssignedTo : function( iAssignedToId, sAssignedToName )
    {
      kwSearch.Widgets.AssignedTo.aAssignedToList = {};

      kwSearch.Widgets.AssignedTo.addAssignedTo( iAssignedToId, sAssignedToName );
    },

    addAssignedTo : function( iAssignedToId, sAssignedToName )
    {
      var iTmpId    = iAssignedToId;
      var iTmpName  = sAssignedToName;
      if( !sAssignedToName )
      {
        if(( typeof iAssignedToId != 'undefined' ) &&
           ( typeof iAssignedToId['id'] != 'undefined' ) &&
           ( typeof iAssignedToId['name'] != 'undefined' ))
        {
          iTmpId    = iAssignedToId['id'];
          iTmpName  = iAssignedToId['name'];
        }
      }
      if( typeof iTmpId != 'undefined' )
      {
        var oTmp      = {};
        oTmp[iTmpId]  = {'id' : iTmpId, 'name' : iTmpName};
        kwSearch.Widgets.AssignedTo.addToSearch( oTmp );
      }
    },

    removeAssignedTo : function( iAssignedToId, sAssignedToName )
    {
      if(( typeof kwSearch.Widgets.AssignedTo.aAssignedToList[iAssignedToId] != 'undefined' ) &&
         ( kwSearch.Widgets.AssignedTo.aAssignedToList[iAssignedToId]['name'] == sAssignedToName ))
      {
        delete kwSearch.Widgets.AssignedTo.aAssignedToList[iAssignedToId];

        kwSearch.Widgets.AssignedTo.addToSearch( kwSearch.Widgets.AssignedTo.aAssignedToList );
      }
    },

    addToSearch : function( oAssignedTo, sAssignedToType )
    {
      if( typeof oAssignedTo == 'string' )
      {
        oAssignedTo = JSON.parse( oAssignedTo );
      }
      if(( oAssignedTo !== null ) && ( typeof oAssignedTo == 'object' ))
      {
        for( sKey in oAssignedTo )
        {
          kwSearch.Widgets.AssignedTo.aAssignedToList[sKey] = oAssignedTo[sKey];
        }
      }

      var sAssignedToTypeSetting = sAssignedToType || kwSearch.Widgets.AssignedTo.aAssignedToList['AssignedToType'];

      kwSearch.Widgets.AssignedTo.setAssignedToType( sAssignedToTypeSetting, false );

      kwSearch.Widgets.Util.executeWidgetCallback( 'AssignedTo', kwSearch.Widgets.AssignedTo.aAssignedToList );

      kwSearch.ContentSearch.addRequirement( 'AssignedTo', kwSearch.Widgets.AssignedTo.aAssignedToList );

      if( $.sizeOf( kwSearch.Widgets.AssignedTo.aAssignedToList ) > 1 )
      {
        kwSearch.SearchForm.setSearchType( 'Search' );
      }
      else
      {
        kwSearch.SearchForm.setSearchType( kwSearch.Widgets.AssignedTo.sDefaultSearchType );
      }
    },

    setAssignedToType : function( sAssignedToType, bAddToSearch )
    {
      if( typeof bAddToSearch === 'undefined' )
      {
        bAddToSearch = true;
      }

      if(( typeof sAssignedToType !== 'undefined' ) &&
         ( $.trim( sAssignedToType ) !== '' ))
      {
        kwSearch.Widgets.AssignedTo.sAssignedToType = sAssignedToType;

        kwSearch.Widgets.AssignedTo.aAssignedToList['AssignedToType'] = kwSearch.Widgets.AssignedTo.sAssignedToType;
      }

      if( bAddToSearch )
      {
        kwSearch.Widgets.AssignedTo.addToSearch();
      }
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
        kwSearch.Widgets.AssignedTo.addToSearch( oState );
      }
    },

    removeFromSearch : function()
    {
      var sNotSearchType = '';
      if( kwSearch.Widgets.State.getExpandedWidgets().length > 0 )
      {
        sNotSearchType = 'Search';
      }
      kwSearch.SearchForm.setSearchType( '', sNotSearchType );
      kwSearch.Widgets.Util.removeFromSearch( 'AssignedTo' );
    }
  },

  JumpSort : {
    sDefaultSearchType : 'Query',

    sLetter : '',
    oSort   : {},

    addToSearch : function()
    {
      var oJumpSort = { "Letter"  : kwSearch.Widgets.JumpSort.sLetter,
                        "Sort"    : kwSearch.Widgets.JumpSort.oSort };

      var sField     = '',
          sDirection = '';
      if( typeof kwSearch.Widgets.JumpSort.oSort['Field'] != 'undefined' )
      {
        sField = kwSearch.Widgets.JumpSort.oSort['Field'];

        if( sField != 'Date' )
        {
          kwSearch.Widgets.JumpSort.sDefaultSearchType = 'Search';
        }
        else
        {
          kwSearch.Widgets.JumpSort.sDefaultSearchType = 'Query';
        }
      }
      if( typeof kwSearch.Widgets.JumpSort.oSort['Direction'] != 'undefined' )
      {
        sDirection = kwSearch.Widgets.JumpSort.oSort['Direction'];
      }

      kwSearch.SearchForm.setSearchSort( sField, sDirection );

      kwSearch.Widgets.Util.executeWidgetCallback( 'JumpSort', oJumpSort );

      kwSearch.ContentSearch.addRequirement( 'JumpSort', oJumpSort );
      kwSearch.SearchForm.setSearchType( 'Search' );
    },

    addLetter : function( sLetter )
    {
      kwSearch.Widgets.JumpSort.sLetter = sLetter;

      kwSearch.Widgets.JumpSort.addToSearch();
    },

    addSort : function( sSortField, sSortDirection )
    {
      kwSearch.Widgets.JumpSort.oSort = { 'Field'     : sSortField,
                                          'Direction' : sSortDirection };

      kwSearch.Widgets.JumpSort.addToSearch();
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
        if( oState.Letter )
        {
          kwSearch.Widgets.JumpSort.addLetter( oState.Letter );
        }
        if( oState.Sort )
        {
          kwSearch.Widgets.JumpSort.addSort( oState.Sort.Field, oState.Sort.Direction );
        }
      }
    },

    removeFromSearch : function()
    {
      kwSearch.Widgets.Util.removeFromSearch( 'JumpSort' );
    }
  },

  // TODO : implement
  Status : {
    sDefaultSearchType : '',

    addToSearch : function()
    {
    },

    setDefaultState : function( oState )
    {
      if( oState )
      {
      }
    },

    removeFromSearch : function()
    {
      kwSearch.Widgets.Util.removeFromSearch( 'Status' );
    }
  },

  Util : {
    aCallbacks    : {},
    bPostedSearch : false,

    countElements : function( oObject )
    {
      var retval = 0;

      try
      {
        if( typeof oObject != 'undefined' )
        {
          for( var sKey in oObject )
          {
            if(( typeof sKey != 'undefined' ) &&
               ( typeof oObject[sKey] != 'undefined' ))
            {
              retval++;
            }
          }
        }
      }
      catch( e ) {}

      return retval;
    },

    wasSearchPosted : function()
    {
      return kwSearch.Widgets.Util.bPostedSearch;
    },

    setDefaultState : function( bPostedSearch )
    {
      kwSearch.Widgets.Util.bPostedSearch = bPostedSearch || false;
      var iSearchDelay            = -1,
          sDefaultSearchType      = kwSearch.SearchForm.getSearchType(),
          sBaseSearchRequirements = kwSearch.SearchForm.getBaseSearchRequirements(),
          oTmp,
          key;

      if(( sBaseSearchRequirements ) &&
         ( sBaseSearchRequirements != '' ))
      {
        oTmp = JSON.parse( sBaseSearchRequirements );
        if( typeof oTmp != 'undefined' )
        {
          for( key in oTmp )
          {
            if(( kwSearch.Widgets[key] ) &&
               ( typeof kwSearch.Widgets[key].setDefaultState == 'function' ))
            {
              kwSearch.Widgets[key].setDefaultState( oTmp[key] );
            }
          }

          /**
           * Make sure the WORDS widget is always expanded, regardless of
           * what else might have been set.
           * STORY17233
           */
          if( !kwSearch.Widgets.State.isExpanded( 'Words' ))
          {
            kwSearch.Widgets.State.moveWidget( 'Words', kwSearch.Widgets.State.collapsed, kwSearch.Widgets.State.expanded );
          }

          /* Setting default state shouldn't trigger search */
          kwSearch.ContentSearch.stopSearchCountdown();
          if( kwSearch.Widgets.Util.bPostedSearch )
          {
            /**
             * If the user got here as a result of a POSTed search, reduce the
             * delay so that the search is triggered with virtually no wait.
             */
            kwSearch.SearchForm.setSearchType( sDefaultSearchType );
            kwSearch.ContentSearch.performSearch();
          }
        }
      }
    },

    activateWidget : function( sWidgetType )
    {
      var bWidgetActivated = false;

      if( typeof kwSearch.Widgets[sWidgetType] !== 'undefined' )
      {
        /**
         * Just checking to see if there is there is an activate method
         * defined.  This is to allow additional functionality that might
         * be necessary above and beyond the normal expanding of the widget
         * and/or adding back to search
         */
        if( typeof kwSearch.Widgets[sWidgetType].activate == 'function' )
        {
          bWidgetActivated = kwSearch.Widgets[sWidgetType].activate();
        }
        else
        {
          if( typeof kwSearch.Widgets[sWidgetType]['addToSearch'] == 'function' )
          {
            kwSearch.Widgets[sWidgetType].addToSearch();

            bWidgetActivated = true;
          }
        }
      }
      else
      {
        /**
         * This is for those widgets that do not need any specific
         * functionality.  If it's registered but has not been defined
         * as part of the kwSearch.Widgets object, we should still
         * activate it on the front end.
         */
        if( kwSearch.Widgets.State.getRegisteredWidgetTypes().indexOf( sWidgetType ) >= 0 )
        {
          bWidgetActivated = true;
        }
      }

      if( bWidgetActivated )
      {
        kwSearch.Widgets.State.moveWidget( sWidgetType, kwSearch.Widgets.State.collapsed, kwSearch.Widgets.State.expanded );

        /**
         * TODO
         * Need to change the second argument so that it's the return
         * value of a call to a new method for each widget called
         * getCurrentState()
         */
        kwSearch.Widgets.Util.executeWidgetCallback( 'Activate_' + sWidgetType, {} );

        kwSearch.ContentSearch.stopSearchCountdown();
      }
    },

    deactivateWidget : function( sWidgetType )
    {
      var bWidgetDeactivated = false;

      /**
       * Just checking to see if there is there is an deactivate method
       * defined.  This is to allow additional functionality that might
       * be necessary above and beyond the normal collapsing of the widget
       * and/or removing from search
       */
      if( typeof kwSearch.Widgets[sWidgetType].deactivate == 'function' )
      {
        bWidgetDeactivated = kwSearch.Widgets[sWidgetType].deactivate();
      }
      else if( typeof kwSearch.Widgets[sWidgetType].removeFromSearch == 'function' )
      {
        kwSearch.Widgets[sWidgetType].removeFromSearch();

        bWidgetDeactivated = true;
      }
      else
      {
        kwSearch.Widgets.Util.removeFromSearch( sWidgetType );

        bWidgetDeactivated = true;
      }

      if( bWidgetDeactivated )
      {
        kwSearch.SearchForm.setSearchType( '', 'Search' );

        kwSearch.Widgets.State.moveWidget( sWidgetType, kwSearch.Widgets.State.expanded, kwSearch.Widgets.State.collapsed );

        /**
         * TODO
         * Need to change the second argument so that it's the return
         * value of a call to a new method for each widget called
         * getCurrentState()
         */
        kwSearch.Widgets.Util.executeWidgetCallback( 'Deactivate_' + sWidgetType, {} );

//      kwSearch.ContentSearch.stopSearchCountdown();
      }
    },

    removeFromSearch : function( sWidgetType )
    {
      kwSearch.ContentSearch.removeRequirement( sWidgetType );
    },

    registerWidgetCallback : function( sWidgetType, sCallbackFunction )
    {
      if( typeof kwSearch.Widgets.Util.aCallbacks[sWidgetType] == 'undefined' )
      {
        kwSearch.Widgets.Util.aCallbacks[sWidgetType] = [];
      }
      kwSearch.Widgets.Util.aCallbacks[sWidgetType].push( sCallbackFunction );
    },

    executeWidgetCallback : function( sWidgetType, sArguments, sAdditionalArgs )
    {
      if(( typeof kwSearch.Widgets.Util.aCallbacks[sWidgetType] != 'undefined' ) &&
         ( kwSearch.Widgets.Util.aCallbacks[sWidgetType].length > 0 ))
      {
        for( var i = 0; i < kwSearch.Widgets.Util.aCallbacks[sWidgetType].length; i++ )
        {
          if( typeof kwSearch.Widgets.Util.aCallbacks[sWidgetType][i] == 'function' )
          {
            oCallback = kwSearch.Widgets.Util.aCallbacks[sWidgetType][i];
            oCallback( sArguments, sAdditionalArgs );
          }
        }
      }
    }
  }
};

kwSearch.Widgets.Classes = {
  Where : function()
  {
    this.oLocations = {};

    this.addToSearch = function( oWhere )
    {
      if( typeof oWhere == 'string' )
      {
        oWhere = JSON.parse( oWhere );
      }
      if( typeof oWhere == 'object' )
      {
        /**
         * Right now, the functionality is that we'll be getting all the teams
         * at once, as opposed to one team at a time.  If functionality is ever
         * added such that the user can select one team at a time then something
         * will be necessary allowing for the removal of teams/locations from the
         * search.
         **/
        this.oLocations = {};
        for( sKey in oWhere )
        {
          this.oLocations[sKey] = oWhere[sKey];
        }
      }
      kwSearch.Widgets.Util.executeWidgetCallback( 'Where', this.oLocations );

      kwSearch.ContentSearch.addRequirement( 'Where', this.oLocations );

      /**
       * I'm not convinced that WHERE should be changing the search type.
       * I'm leaving this in here in the event that it is later needed.
       **/
      //kwSearch.SearchForm.setSearchType( 'Search' );
    };

    this.setDefaultState = function( oState )
    {
      if( oState )
      {
        kwSearch.Widgets.Where.addToSearch( oState );
      }
    };

    this.removeFromSearch = function() {kwSearch.Widgets.Util.removeFromSearch( 'Where' );};
  }
};

 /**
  * Deactivated Widget Hover Functions
  **/


$('#CollapsedSearchWidgets').find('div').hover(
  function()
  {
    $( this ).addClass( 'ui-state-hover' );
  },
  function()
  {
    $( this ).removeClass( 'ui-state-hover' );
  }
);
