YAHOO.namespace("ibe.deals");

YUI({
  modules :{
    'slideshow' :{},
    'ibe-anim' : {}
  }
}).use('node', 'anim', 'overlay', 'slideshow', 'ibe-anim', function(Y) {
  var DEAL = YAHOO.ibe.deals;

  Y.on('domready', function() {
    DEAL.initPage();
  });

  YAHOO.ibe.deals.initPage = function() {
    // Containers
    DEAL.fullBestDealsList = null;

    // Element id definitions
    DEAL.pageMapElementId = 'pageMapDiv';
    DEAL.pageListElementId = 'pageList';
    DEAL.pageErrorElementId = 'pageErrorDiv';
    DEAL.pageLoadingElementId = 'pageLoadingDiv';
    DEAL.pageNoDealsFoundElementId = 'pageNoDealsFoundElementDiv';
    DEAL.pageOverlayDiv = 'pageOverlayDiv';
    DEAL.pageHotelImagesContainerElementId = '';

    DEAL.pageNoImagesForHotelElementId = null;
    DEAL.noImagesForHotel = new Array();
    DEAL.max = undefined;

    // Views
    DEAL.listView = null;
    DEAL.hotelImagesView = null;

    // Components
    DEAL.fullList = null;
    DEAL.imagesList = null;
    DEAL.compImages = new Array(); // Hotels systemHotelCode is index!

    DEAL.lockedAtErrorPage = false; // If true, cannot load new sub pages, error page is locked in place.
    DEAL.processManager = new IBEProcessManager('pushover');

    DEAL.currentSubPage = undefined;
    DEAL.currentSortOption = undefined;
    DEAL.currentHotelSystemCode = undefined;
    DEAL.currentIndex = undefined;
    DEAL.currentUniqueId = undefined;

    // Slide show
    DEAL.currentPhotoIconElementId = undefined;
    DEAL.currentSlideshowContainerId = undefined;
    DEAL.currentSlideshowId = undefined;
    DEAL.openedSlideshowContainerId = undefined;
    DEAL.currentSlideshowHeaderId = undefined;
    DEAL.slideshowOverlays = new Array();
    DEAL.slideshows = new Array();
    DEAL.renderHotelImagesInTabView = false;

    // Price information
    DEAL.priceOverlays = new Array();
    DEAL.priceOverlayElementId = 'priceOverlay_';

    DEAL.setUpAllViews();
    DEAL.getBestDealsListAndRender();
    DEAL.showLoadingAnimation();
  };

  YAHOO.ibe.deals.dataFetchCausedError = function() {
    ibelog('The search result is no longer active. Please search again. Replace this with an automatic search.');
    YAHOO.ibe.deals.lockedAtErrorPage = true;
  };

  YAHOO.ibe.deals.dataFetchWasCancelled = function() {};

  YAHOO.ibe.deals.setUpAllViews = function() {
    DEAL.listView = new IBEWebComponentView(DEAL.listViewAction);
    if (DEAL.searchType == 'Hotel' || DEAL.searchType == 'Combo' || DEAL.searchType == 'Vacation') {
      DEAL.hotelImagesView = new IBEWebComponentView('/ajax.component.view.holidaydeal.hotelImagesView.action');
      DEAL.hotelImagesView.fetchView();
    }
  };

  YAHOO.ibe.deals.getBestDealsListAndRender = function() {
    DEAL.processManager.addProcess(new IBEProcess(DEAL.resultListAction + DEAL.searchParams, undefined,
                                                  DEAL.dataHasBeenFetched, DEAL.dataFetchCausedError, DEAL.dataFetchWasCancelled));
  };

  YAHOO.ibe.deals.getDeal = function(atIndex) {
    if (!DEAL.fullBestDealsList) {
      ibeerror('No result list available on page.');
      return;
    }
    return DEAL.fullBestDealsList[atIndex];
  };

  /**
   * This function is callback when best deals list has been fetched. Setup components and render the page. And if
   * sort option is already selected, then sort the list before rendering it.
   *
   * @param result JSON-result.
   */
  YAHOO.ibe.deals.dataHasBeenFetched = function(result) {
    // Populate the list
    try {
      DEAL.fullBestDealsList = eval(result.responseText);
    } catch (e) {
      ibeerror('Unable to parse best deals list, is containing faulty characters.');
    }

    if (DEAL.currentSortOption != undefined) {
      DEAL.updateFilterAndSort(
        DEAL.currentSortOption.getId(),
        DEAL.currentSortOption.isDescSortOrder(),
        DEAL.currentSortOption.getSortValue(),
        true
        );
    } else {
      DEAL.setupSubPages();
    }
  };

  YAHOO.ibe.deals.showSubPage = function(id) {
    if (DEAL.lockedAtErrorPage) {
      id = DEAL.pageErrorElementId;
    }
    setHidden(DEAL.pageLoadingElementId, true);
    setVisible(id, true);
    DEAL.currentSubPage = id;
  };

  YAHOO.ibe.deals.hideSubPage = function(id) {
    if (DEAL.lockedAtErrorPage) id = DEAL.pageErrorElementId;
    setHidden(id, true);
  };

  YAHOO.ibe.deals.display = function(id) {
    if (id) setVisible(id, true);
  };

  YAHOO.ibe.deals.hide = function(id) {
    if (id) setHidden(id, true);
  };

  YAHOO.ibe.deals.showLoadingAnimation = function() {
    DEAL.hideAllSubPages();
    DEAL.showSubPage(DEAL.pageLoadingElementId);
  };

  YAHOO.ibe.deals.hideAllSubPages = function() {
    setHidden(DEAL.pageListElementId, true);
    setHidden(DEAL.pageErrorElementId, true);
    setHidden(DEAL.pageLoadingElementId, true);
    setHidden(DEAL.pageDetailsElementId, true);
    setHidden(DEAL.pageNoDealsFoundElementId, true);
  };

  YAHOO.ibe.deals.setupSubPages = function() {
    if (DEAL.noDealsFound()) {
      DEAL.renderNoDealsFoundComponent();
    } else {
      DEAL.fullList = new IBEWebComponentList('pageList', DEAL.listView, DEAL.fullBestDealsList, DEAL.pageListElementId, undefined, DEAL.listPageHasBeenRendered);
      DEAL.fullList.rendersPerPass = DEAL.max !== undefined ? DEAL.max : 10;
      DEAL.fullList.showLoadingWhileRendering = true;
      DEAL.fullList.showMoreText = UiText.get(DEAL.searchType + '.Result.List.ShowMoreButton.Label') + '&nbsp;&raquo;';
      DEAL.fullList.showMoreDivCssClass = 'hotelShowMoreButtonDiv';
      DEAL.fullList.render();
    }
  };

  YAHOO.ibe.deals.listPageHasBeenRendered = function () {
    if (DEAL.fullList) {
      DEAL.showSubPage(DEAL.pageListElementId);
      DEAL.initPriceOverlays();
      DEAL.subscribeAirInfoEvents();
    }
  };

  YAHOO.ibe.deals.noDealsFound = function() {
    return DEAL.fullBestDealsList == null || DEAL.fullBestDealsList.length == 0;
  };

  YAHOO.ibe.deals.renderNoDealsFoundComponent = function() {
    Y.one('#' + DEAL.pageNoDealsFoundElementId).set('innerHTML', UiText.get(DEAL.searchType + '.Result.NoDealsFound'));
    DEAL.showSubPage(DEAL.pageNoDealsFoundElementId);
  };

  YAHOO.ibe.deals.updateFilterAndSort = function(id, desc, sortValue, listAlreadySorted) {
    if (!id) {
      ibeerror('No filters component available on page.');
      return;
    }

    var SortOption = function(id, sortValue, desc) {
      this.id = id;
      this.sortValue = sortValue;
      this.desc = desc;

      this.getId = function() {
        return this.id;
      };

      this.getSortValue = function() {
        return this.sortValue;
      };

      this.isDescSortOrder = function() {
        return this.desc;
      };

      this.toString = function() {
        return '\nSortOption {id : ' + this.id + ",\nsortValue : " + this.sortValue + ",\ndesc : " + this.desc + "}";
      };
    };

    var e = document.getElementById(id);
    if (e) {
      if (!desc) desc = false;
      if (!sortValue) sortValue = e.name;

      if (DEAL.currentSortOption == undefined) {
        DEAL.currentSortOption = new SortOption(id, sortValue, desc);
      } else {
        if (DEAL.currentSortOption.getId() == id && !listAlreadySorted) {
          return;
        }
      }

      DEAL.currentSortOption = new SortOption(id, sortValue, desc);

      IBESorter.bubbleSort(DEAL.fullBestDealsList, sortValue, desc);

      DEAL.setupSubPages();

      DEAL.resetOverlayHolders();
    }
  };

  YAHOO.ibe.deals.updateFilterAndRefresh = function(form) {
    if (!form) {
      ibeerror('No filters component available on page.');
      return;
    }

    var url = DEAL.createFilterOptionsUrl(form);
    if (url) {
      var p = new IBEProcess(url, undefined, DEAL.dataHasBeenFetched, DEAL.dataFetchCausedError, DEAL.dataFetchWasCancelled);
      p.startProcess();
      DEAL.showLoadingAnimation();
    }

  };

  YAHOO.ibe.deals.createFilterOptionsUrl = function(form) {
    var url = undefined;
    var first = true;
    var args = "";

    if (DEAL.searchParams) {
      first = false;
      args += DEAL.searchParams;
    }

    for (var i = 0; i < form.length; i++) {
      var e = form[i];
      if (e && e.value) {
        if ((e.type == 'radio' && e.checked) || (e.type == 'checkbox')) {
          // Nothing yet.
        } else {
          if (first) {
            args += '?';
            first = false;
          } else {
            args += "&";
          }
          if (e.name == 'max') DEAL.max = e.value;
          args += e.name + "=" + e.value;
          url = DEAL.resultListAction + args;
        }
      }
    }

    if (url == undefined) {
      url = DEAL.resultListAction + DEAL.searchParams;
    }

    DEAL.resetOverlayHolders();

    return url;
  };

  YAHOO.ibe.deals.showHotelImages = function(atIndex) {
    var deal = DEAL.getDeal(atIndex);
    DEAL.renderHotelImagesInTabView = false;
    DEAL.currentIndex = atIndex;
    DEAL.currentHotelSystemCode = deal.systemHotelCode;
    DEAL.currentUniqueId = DEAL.currentIndex + "_" + DEAL.currentHotelSystemCode;

    DEAL.closeOpenedHotelDetails();
    DEAL.closeOpenedSlideshow();

    DEAL.currentPhotoIconElementId = 'photoIcon_' + DEAL.currentUniqueId;
    DEAL.currentSlideshowContainerId = 'pageHotelImagesContainerElementDiv_' + DEAL.currentUniqueId;
    DEAL.currentSlideshowId = 'slideshow_' + DEAL.currentUniqueId;
    DEAL.currentSlideshowHeaderId = 'slideshow_' + DEAL.currentUniqueId + '_header';
    DEAL.pageNoImagesForHotelElementId = 'noImagesForHotel_' + DEAL.currentUniqueId;
    DEAL.openedSlideshowContainerId = DEAL.currentSlideshowContainerId;
    DEAL.openedSlideshowId = DEAL.currentSlideshowId;
    DEAL.slideshowLoadingAnimationElementId = 'animation_' + DEAL.currentUniqueId;

    DEAL.displaySlideshowOverlay();

    DEAL.fetchAndRenderHotelImages(deal);
  };

  YAHOO.ibe.deals.fetchAndRenderHotelImages = function(deal) {
    if (DEAL.compImages[DEAL.currentUniqueId] === undefined) {
      if (deal.images === undefined || deal.images.length == 0) {
        DEAL.fetchHotelImages(deal);
      } else {
        DEAL.renderHotelImages();
      }
    }
    DEAL.renderHotelImages();
  };

  YAHOO.ibe.deals.subscribeAirInfoEvents = function() {
    // Air information
    DEAL.airInfoElementId = undefined;
    DEAL.airInfoAnim = new Array();

    var nodes = Y.all('.airInfo');

    var display = function(e) {
      var id = e.currentTarget.get('id');
      var unique = DEAL.getUniqueId(id);
      var alreadyOpenedAirInfoElementId = undefined;

      if (unique !== undefined) {
        if (DEAL.airInfoElementId === undefined) {
          DEAL.airInfoElementId = 'airInfo_' + unique;
          if (DEAL.airInfoAnim[DEAL.airInfoElementId] === undefined) {
            DEAL.airInfoAnim[DEAL.airInfoElementId] = new Y.SlideDownUp(DEAL.airInfoElementId);
            DEAL.airInfoAnim[DEAL.airInfoElementId].open();
          }
        } else {
          if (DEAL.airInfoElementId === 'airInfo_' + unique) {
            DEAL.airInfoAnim[DEAL.airInfoElementId].toggle();
          } else {
            DEAL.airInfoAnim[DEAL.airInfoElementId].close();
            alreadyOpenedAirInfoElementId = DEAL.airInfoElementId;
            DEAL.airInfoElementId = 'airInfo_' + unique;
            if (DEAL.airInfoAnim[DEAL.airInfoElementId] === undefined) {
              DEAL.airInfoAnim[DEAL.airInfoElementId] = new Y.SlideDownUp(DEAL.airInfoElementId);
            }
            DEAL.airInfoAnim[DEAL.airInfoElementId].open();
          }
        }
        toggleIcons(unique, alreadyOpenedAirInfoElementId);
      }
    };

    var toggleIcons = function(id, alreadyOpenedAirInfoElementId) {
      if (alreadyOpenedAirInfoElementId !== undefined) {
        var openedId = DEAL.getUniqueId(alreadyOpenedAirInfoElementId);
        DEAL.hide('airInfoMinusIcon_' + openedId);
        DEAL.display('airInfoPlusIcon_' + openedId);
      }

      if (DEAL.airInfoAnim[DEAL.airInfoElementId].isOpened) {
        DEAL.display('airInfoMinusIcon_' + id);
        DEAL.hide('airInfoPlusIcon_' + id);
      } else {
        DEAL.hide('airInfoMinusIcon_' + id);
        DEAL.display('airInfoPlusIcon_' + id);
      }
    };

    if (nodes) nodes.on('click', display);
  };

  /**
   * Splits id 'airInfoText_0_7_184176' --> [airInfoText, 0, 7, 184176] and creates an index = '0_7_184176', which is
   * the unique id composed by index position in the result list and hotelSystemCode.
   *
   * @param id HTML element id. EX_ 'airInfoText_0_7_184176'
   */
  YAHOO.ibe.deals.getUniqueId = function(id) {
    var unique = undefined;

    if (id) {
      unique = '';
      var argv = id.split('_');
      for (var i = 1; i < argv.length; i++) {
        if (i == 1) {
          unique += argv[i];
        }
        else {
          unique += '_' + argv[i];
        }
      }
    }
    return unique;
  };

  YAHOO.ibe.deals.fetchHotelImages = function(deal) {
    if (deal) {
      var url = '/ajax.component.model.hotel.imagesforhotel.action?systemHotelCode=' + DEAL.currentHotelSystemCode + '&hotelImagesFromDB=true';
      deal.images = new Array();
      var p = new IBEProcess(url, deal.images, DEAL.imagesHasBeenFetched, DEAL.dataFetchCausedError, DEAL.dataFetchWasCancelled);
      p.evaluateResponse = true;
      p.startProcess();
    }
  };

  YAHOO.ibe.deals.imagesHasBeenFetched = function(result) {
    var deal = DEAL.getDeal(DEAL.currentIndex);

    try {
      deal.images = eval(result.responseText);
    } catch (e) {
      ibeerror('Unable to parse best deals list, is containing faulty characters.');
    }

    if (deal.images.length == 0) {
      DEAL.noImagesForHotel[DEAL.pageNoImagesForHotelElementId] = true;
    }
    DEAL.renderHotelImages();
  };

  YAHOO.ibe.deals.renderHotelImages = function() {
    var deal = DEAL.getDeal(DEAL.currentIndex);
    if (deal) {
      var component;
      if (DEAL.renderHotelImagesInTabView === true) {
        var placeHolder = 'images_' + DEAL.currentUniqueId;
        component = new IBEWebComponent('hotelTabImagesId', DEAL.hotelImagesTabView, deal, placeHolder, DEAL.showImagesInTabContainer);
        component.showLoadingWhileRendering = true;
      } else {
        component = new IBEWebComponent('hotelSlideshowImagesId', DEAL.hotelImagesView, deal, DEAL.currentSlideshowContainerId, DEAL.showImagesContainer);
        component.showLoadingWhileRendering = false;
      }

      component.render();
      DEAL.compImages[DEAL.currentUniqueId] = component;
    }
  };

  YAHOO.ibe.deals.generateHtmlForImageList = function(images) {
    var html = "";
    for (var i = 0; i < images.length; i++) {
      html += '<div class="slideshowImgDiv"><img src="' + images[i].url + '"/></div>';
    }
    return html;
  };

  YAHOO.ibe.deals.displaySlideshowOverlay = function() {
    if (DEAL.slideshowOverlays[DEAL.currentSlideshowContainerId] === undefined) {
      DEAL.slideshowOverlays[DEAL.currentSlideshowContainerId] = new Y.Overlay({
        contentBox : '#' + DEAL.currentSlideshowContainerId,
        visible : true,
        align : {
          node : '#' + DEAL.currentPhotoIconElementId,
          points:[Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.RC]
        }
      });
    }
    DEAL.slideshowOverlays[DEAL.currentSlideshowContainerId].render();

    DEAL.display(DEAL.currentSlideshowContainerId);
  };

  YAHOO.ibe.deals.showImagesContainer = function() {
    DEAL.display(DEAL.slideshowLoadingAnimationElementId);

    var deal = DEAL.getDeal(DEAL.currentIndex);
    if (deal.images.length > 0) {
      DEAL.slideshows[DEAL.currentSlideshowId] = new Y.Slideshow(DEAL.currentSlideshowId, {
        interval : 4000,
        duration : 0.5,
        nextButton: '#slideshowNext_' + DEAL.currentUniqueId,
        previousButton: '#slideshowPrev_' + DEAL.currentUniqueId,
        playButton: '#slideshowPlay_' + DEAL.currentUniqueId,
        pauseButton: '#slideshowPause_' + DEAL.currentUniqueId
      });

      DEAL.hide(DEAL.slideshowLoadingAnimationElementId);
      DEAL.display(DEAL.currentSlideshowId);
      DEAL.display(DEAL.currentSlideshowHeaderId);

      var playButton = Y.one('#slideshowPlay_' + DEAL.currentUniqueId);
      var pauseButton = Y.one('#slideshowPause_' + DEAL.currentUniqueId);
      var nextButton = Y.one('#slideshowNext_' + DEAL.currentUniqueId);
      var prevButton = Y.one('#slideshowPrev_' + DEAL.currentUniqueId);

      var play = function() {
        if (DEAL.slideshows[DEAL.currentSlideshowId] !== undefined) {
          DEAL.hide('slideshowPlay_' + DEAL.currentUniqueId);
          DEAL.display('slideshowPause_' + DEAL.currentUniqueId);
        }
      };

      var pause = function() {
        if (DEAL.slideshows[DEAL.currentSlideshowId] !== undefined) {
          DEAL.hide('slideshowPause_' + DEAL.currentUniqueId);
          DEAL.display('slideshowPlay_' + DEAL.currentUniqueId);
        }
      };

      playButton.on('click', play);
      pauseButton.on('click', pause);
      nextButton.on('click', pause);
      prevButton.on('click', pause);
    }

    DEAL.setNoImagesForHotelText();
  };

  YAHOO.ibe.deals.initPriceOverlays = function() {
    var priceNodes = Y.all('.holidayPrice');

    var displayOverlay = function(e, display) {
      var priceLabelId = e.currentTarget.get('id');
      var contentId = priceLabelId + "_overlay";

      if (priceLabelId && contentId) {
        if (display) {
          if (DEAL.priceOverlays[priceLabelId] === undefined) {
            DEAL.priceOverlays[priceLabelId] = new Y.Overlay({
              contentBox : '#' + contentId,
              visible : true,
              zIndex: 6,
              align : {
                node : '#' + priceLabelId,
                points:[Y.WidgetPositionAlign.TL, Y.WidgetPositionAlign.RC]
              }
            });
          }
          DEAL.priceOverlays[priceLabelId].render('#' + DEAL.pageOverlayDiv);

          DEAL.display(contentId);

          new Y.IBEFade(contentId, {
            from : { opacity : 0,width : '180px',height : '100%' },
            to : { opacity : 1, width : '180px', height : '100%' }
          }).fadeIn();
        } else {
          new Y.IBEFade(contentId).fadeOut();
        }
      }
    };

    priceNodes.on('mouseover', displayOverlay, this, true);
    priceNodes.on('mouseout', displayOverlay, this, false);
  };

  YAHOO.ibe.deals.closeOpenedSlideshow = function() {
    if (DEAL.openedSlideshowContainerId !== undefined) {
      var slideshowToClose = DEAL.slideshows[DEAL.openedSlideshowId];
      if (slideshowToClose !== undefined) {
        slideshowToClose.stopSlideshow();
      }
      DEAL.hide(DEAL.openedSlideshowContainerId);
    }
  };

  YAHOO.ibe.deals.setNoImagesForHotelText = function() {
    if (DEAL.noImagesForHotel[DEAL.pageNoImagesForHotelElementId] === true) {
      DEAL.hide(DEAL.slideshowLoadingAnimationElementId);
      setInnerHTML(DEAL.pageNoImagesForHotelElementId, DEAL.noImagesForHotelText);
      DEAL.display(DEAL.pageNoImagesForHotelElementId);
    }
  };

  YAHOO.ibe.deals.index = function() {
    return YAHOO.ibe.deals.currentIndex;
  };

  YAHOO.ibe.deals.resetOverlayHolders = function() {
    DEAL.priceOverlays = new Array();
    DEAL.slideshowOverlays = new Array();
    DEAL.compImages = new Array();
  };

});
