/**
 * File: kwSearch.ResultView.js
 * Copyright 2009 Yakabod, inc.
 *
 * $Revision: 1.9 $
 * $Date: 2012/01/11 15:37:37 $
 * Last edited by: $Author: danderson $
 *
 * Last Error Free JSLint: 2010 03 24 12:47
 **/
( function( global )
{
  "use strict";

  if( global.jQuery && global.kwSearch )
  {
    var Math = global.Math,
        Date = global.Date,
        $ = global.jQuery,
        kwSearch = global.kwSearch;

    /*
     * Result View Handlers
     */

    /* Grid view handler - original search result view */
    global.SearchView_Grid = function() /* Implements kwSearch.ResultView::iHandlerInterface */
    {
      var kwS = kwSearch,
          kwSC = kwSearch.ContentSearch,
          kwSR = kwS.ResultView,
          sRequestPage;

      kwSR.getHandlerInterface().assertImplementation( this );

      if(( kwSearch.sDefaultSearchPage !== null ) &&
         ( $.trim( kwSearch.sDefaultSearchPage ) !== '' ))
      {
        sRequestPage = kwSearch.sDefaultSearchPage;
      }
      else
      {
        sRequestPage = '/library/ContentNavigationGrid.html';
      }

      kwSC.StreamContent.setRequestPage( sRequestPage );
      this.data = null;
      this.$ViewContainer = $( '#' + kwSR.getContainerId() );
    };
    global.SearchView_Grid.prototype = {
      setUp: function()
      {
        return this;
      },
      setData: function( data )
      {
        this.data = data;
        return this;
      },
      render: function()
      {
        var kwS = kwSearch,
            kwSC = kwSearch.ContentSearch,
            kwSF = kwSearch.SearchForm,
            kwSR = kwS.ResultView,
            sSpacelessContent;

        kwSR.clearMessage();

        this.$ViewContainer.append( this.data.page_data );

        sSpacelessContent = $.trim( '' + this.data.page_data );
        if( this.data.endResults || sSpacelessContent === '' || sSpacelessContent === 'No Results' )
        {
          kwSC.StreamContent.endContentSearch();
          kwSR.displayMessage( 'Search complete.' );
        }
        else
        {
          kwSF.setNextStartRecord( this.data.newStart );
        }

        return this;
      },
      tearDown: function()
      {
        kwSearch.ResultView.clearMessage();
        this.$ViewContainer.empty();
        return true;
      }
    };




    /* Thumbnail view handler - display image results in a thumbnail format */
    global.SearchView_Thumbnails = function() /* Implements kwSearch.ResultView::iHandlerInterface */
    {
      var kwS = kwSearch,
          kwSC = kwS.ContentSearch,
          kwSR = kwS.ResultView;

      kwSR.getHandlerInterface().assertImplementation( this );

      kwSC.StreamContent.setRequestPage( '/library/ContentNavigationThumbnails.html' );
      this.data = null;
      this.$ViewContainer = $( '#' + kwSR.getContainerId() );
    };
    global.SearchView_Thumbnails.prototype = {
      setUp: function()
      {
        return this;
      },
      setData: function( data )
      {
        this.data = data;
        return this;
      },
      render: function()
      {
        var kwS = kwSearch,
            kwSC = kwS.ContentSearch,
            kwSF = kwS.SearchForm,
            kwSR = kwS.ResultView,
            /*bChooserEnabled = this.data.chooserEnabled,*/
            resultData,
            item,
            result,
            $UL = this.$ViewContainer.find( 'ul.ui-yakawidget-list-thumbnail' ),
            $tmpUL = $( '<ul />' );

        if( $UL.length === 0 )
        {
          $UL = $( '<ul class="ui-yakawidget-list-thumbnail ui-yakawidget-list-horizontal" />' ).appendTo( this.$ViewContainer );
        }

        kwSR.clearMessage();

        if( typeof this.data === 'object' && this.data !== null &&
            typeof this.data.resultData === 'object' && this.data.resultData !== null
          )
        {
          resultData = this.data.resultData;
          for( item in resultData )
          {
            if( typeof resultData[item] === 'object' && resultData[item] !== null )
            {
              /* Each result item will have the following properties:
               * id, objecttype, urn, profileURL, thumbnail, icon, downloadURL, title
               */
              result = resultData[item];

              /* Although these element creations and appends *are* off-DOM, it would be nice to avoid so many calls to the jQ API (we're inside a loop)
               * However, the use of .data() causes the need to use the API as is.  I believe this is offset, however, but the lesser use of the API later
               * when the decorator reads in the meta data.
               */
               $tmpUL.append(
                $(
                  [
                    '<li class="kwsearch-result-thumbnail-item">',
                      '<a href="/library/downloadDocument.html?docId=' + result.id + '" target="_blank" title="' + result.title + '">',
                        '<img src="', result.thumbnail, '" alt="', result.title, '" class="kwsearch-result-thumbnail-img" />',
                      '</a>',
                      '<a href="/library/downloadDocument.html?docId=' + result.id + '" target="_blank"  title="' + result.title + '">',
                        result.title ,
                      '</a>' ,
                      'orig size',
                      '<a href="' + result.profileURL + '" target="_blank">',
                        'Image Profile',
                      '</a>' ,
                    '</li>'
                  ].join( '' )
                ).data( 'resultmeta', {
                    id: result.id,
                    name: result.title,
                    type: result.objectType,
                    image: result.icon,
                    thumbnail: result.thumbnail,
                    height: result.height,
                    width: result.width,
                    link: result.profileURL,
                    urn: result.urn
                } )
              );
            }
          }

          $UL.append( $tmpUL.children() );
        }

        if( this.data.endResults )
        {
          kwSC.StreamContent.endContentSearch();
          kwSR.displayMessage( 'Search complete.' );
        }
        else
        {
          kwSF.setNextStartRecord( this.data.newStart );
        }

        return this;
      },
      tearDown: function()
      {
        kwSearch.ResultView.clearMessage();
        this.$ViewContainer.empty();
        return true;
      }
    };




    /* Calendar view handler - display 100 results in a calendar format */
    global.SearchView_Calendar = function() /* Implements kwSearch.ResultView::iHandlerInterface */
    {
      var oSV_C = this,
          kwS = kwSearch,
          kwSR = kwS.ResultView;

      kwSR.getHandlerInterface().assertImplementation( this );

      this.bSetupComplete = false;
      this.$ViewContainer = null;
      this.sWhenWidgetName = 'When';
      this.data = null;
      this.bWhenActiveOnStart = false;

      this.fcOptions = {
        weekMode: 'liquid',
        disableDragging: true,
        disableResizing: false,
        theme: true

      };

      this.makeCalendar = function()
      {
        var $VC = this.$ViewContainer,
            kwS = kwSearch,
            kwSR = kwS.ResultView;

        $VC.fullCalendar( this.fcOptions );

        $VC.find( '.fc-button-today, .fc-button-prev, .fc-button-next' ).click( function()
        {
          var oFCStart = oSV_C.getCalendarStart(),
              iWhenYear = null,
              iWhenMonth = null;

          $VC.hide();
          kwSR.clearMessage();

          if( oFCStart !== null )
          {
            iWhenYear = oFCStart.getFullYear();
            iWhenMonth = oFCStart.getMonth();
          }
          oSV_C.setWhen.call( oSV_C, iWhenYear, iWhenMonth );

        } );
      };

      this.destroyCalendar = function()
      {
        this.$ViewContainer.removeData( 'fullCalendar' ).empty();
      };

      this.setWhen = function( iWhenYear, iWhenMonth )
      {
        var kwS = kwSearch,
            kwSWhen = kwS.Widgets[this.sWhenWidgetName],
            oNow = new Date();

        if( typeof iWhenYear !== 'number' )
        {
          iWhenYear = oNow.getFullYear();
        }
        if( typeof iWhenMonth !== 'number' )
        {
          iWhenMonth = oNow.getMonth();
        }

        this.fcOptions.year = iWhenYear;
        this.fcOptions.month = iWhenMonth;

        kwSWhen.addStartDate( Math.floor( ( new Date( iWhenYear, iWhenMonth, 1 ).getTime() ) / 1000 ) );
        kwSWhen.addEndDate( Math.floor( ( ( new Date( iWhenYear, iWhenMonth + 1, 1 ) ) - 1 ) / 1000 ) );
      };

      this.getCalendarStart = function()
      {
        var oFCView = this.$ViewContainer.fullCalendar( 'getView' ),
            oFCStart = null;
        if( typeof oFCView === 'object' &&
            oFCView !== null &&
            typeof oFCView.start === 'object' &&
            oFCView.start !== null
          )
        {
          oFCStart = oFCView.start;
        }

        return oFCStart;
      };
    };
    global.SearchView_Calendar.prototype = {
      setUp: function()
      {
        var kwS = kwSearch,
            kwSWS = kwS.Widgets.State,
            kwSWU = kwS.Widgets.Util,
            kwSC = kwS.ContentSearch,
            kwSR = kwS.ResultView,
            kwSWhen = kwS.Widgets[this.sWhenWidgetName],
            oWhenDates,
            oStartDate,
            iWhenYear = null,
            iWhenMonth = null,
            oFCStart;

        kwSC.StreamContent.setRequestPage( '/library/ContentNavigationCalendar.html' );
        this.$ViewContainer = $( '#' + kwSR.getContainerId() ).hide();

        if( kwSWS.isExpanded( this.sWhenWidgetName ) )
        {
          this.bWhenActiveOnStart = true;

          oWhenDates =  kwSWhen.getDateRange();
          if( typeof oWhenDates.StartDate === 'number' )
          {
            oStartDate = new Date();
            oStartDate.setTime( oWhenDates.StartDate * 1000 );

            iWhenYear = this.fcOptions.year = oStartDate.getFullYear();
            iWhenMonth = this.fcOptions.month = oStartDate.getMonth();
          }
        }
        else
        {
          kwSWU.activateWidget( this.sWhenWidgetName );
          this.bWhenActiveOnStart = false;
        }
        kwSWS.hideWidget( this.sWhenWidgetName );

        this.FlashRecordLimit = kwSC.getRecordLimit();
        kwSC.setRecordLimit( 100 );

        this.makeCalendar();

        if( ! this.bWhenActiveOnStart )
        {
          oFCStart = this.getCalendarStart();
          if( oFCStart !== null )
          {
            iWhenYear = oFCStart.getFullYear();
            iWhenMonth = oFCStart.getMonth();
          }
        }

        this.setWhen( iWhenYear, iWhenMonth );

        this.bSetupComplete = true;
        return this;
      },
      setData: function( data )
      {
        this.data = data;
        return this;
      },
      render: function()
      {
        var kwS = kwSearch,
            kwSC = kwS.ContentSearch,
            kwSR = kwS.ResultView,
            sMessage;

        if( this.bSetupComplete !== true )
        {
          throw new Error( 'SearchView_Calendar::render() cannot be run until SearchView_Calendar::setUp() has been run.' );
        }

        this.destroyCalendar();
        this.$ViewContainer.show();

        delete this.fcOptions.events;

        if( typeof this.data === 'object' && this.data !== null )
        {
          if( typeof this.data.resultData !== 'undefined' && this.data.resultData instanceof Array )
          {
            this.fcOptions.events = this.data.resultData;
          }

          sMessage = 'Search complete.';
          if( typeof this.data.endResults !== 'boolean' || this.data.endResults === false )
          {
            sMessage = 'There are more results than could be displayed.  Please refine your search terms or switch to the Grid view.';
          }

          kwSR.displayMessage( sMessage );
        }

        this.makeCalendar();

        kwSC.StreamContent.endContentSearch();

        return this;
      },
      tearDown: function()
      {
        var kwS = kwSearch,
            kwSC = kwS.ContentSearch,
            kwSF = kwS.SearchForm,
            kwSR = kwS.ResultView,
            kwSWS = kwS.Widgets.State,
            kwSWU = kwS.Widgets.Util,
            bReturnValue = false;

        if( this.bSetupComplete !== true )
        {
          throw new Error( 'SearchView_Calendar::tearDown() cannot be run until SearchView_Calendar::setUp() has been run.' );
        }

        kwSF.setSearchType( '' );
        kwSC.setRecordLimit( this.FlashRecordLimit );
        kwSR.clearMessage();

        kwSWS.showWidget( this.sWhenWidgetName );
        if( this.bWhenActiveOnStart === false )
        {
          kwSWU.deactivateWidget( this.sWhenWidgetName );
        }
        else
        {
          bReturnValue = true;
        }

        this.destroyCalendar();
        this.bSetupComplete = false;

        return bReturnValue;
      }
    };




    /*
     * Result View control
     */
    kwSearch.ResultView = ( function()
    {
      var iHandlerInterface, oHandler, sViewContainerId, sMessageContainerId, $MessageContainer;

      iHandlerInterface = new Object.Interface(
        'iSearchView',
        [
          'setUp', /* should return instance of the view handler (this) for chaining method calls */
          'setData', /* should return instance of the view handler (this) for chaining method calls */
          'render', /* should return instance of the view handler (this) for chaining method calls */
          'tearDown' /* should return boolean true if setHandler shold trigger a search after replacing the view, false if not */
        ]
      );
      oHandler = null;

      return {
        setHandler : function( oResultViewHandler )
        {
          var kwS = kwSearch,
              kwSC = kwS.ContentSearch,
              bSearchOnHandlerSetup;

          iHandlerInterface.assertImplementation( oResultViewHandler );

          if( iHandlerInterface.checkImplementation( oHandler ) )
          {
            bSearchOnHandlerSetup = oHandler.tearDown();
          }

          oHandler = oResultViewHandler;
          oHandler.setUp();
          if( bSearchOnHandlerSetup )
          {
            kwSC.stopSearchCountdown();
            kwSC.performSearch();
          }
        },
        produceHandler : function()
        {
          if( ! iHandlerInterface.checkImplementation( oHandler ) )
          {
            oHandler = new kwSearch.ResultView.defaultHandlerConstructor();
            oHandler.setUp();
          }

          return oHandler;
        },
        getHandler : function()
        {
          return oHandler;
        },
        setContainerId: function( sContainerId )
        {
          sViewContainerId = '' + sContainerId;
        },
        getContainerId: function()
        {
          return sViewContainerId;
        },
        setMessageContainerId: function( sContainerId )
        {
          sMessageContainerId = '' + sContainerId;
          $MessageContainer = $( '#' + sMessageContainerId );
        },
        getMessageContainerId: function()
        {
          return sMessageContainerId;
        },
        displayMessage: function( sMessage, bAppend )
        {
          if( typeof bAppend === 'boolean' && bAppend === true )
          {
            $MessageContainer.html( sMessage );
          }
          else
          {
            $MessageContainer.append( sMessage );
          }

          $MessageContainer.show();
        },
        clearMessage: function()
        {
          $MessageContainer.empty().hide();
        },
        getHandlerInterface: function()
        {
          return iHandlerInterface;
        },
        defaultHandlerConstructor: global.SearchView_Grid
      };
    }() );
  }
}( window ) );

