var Denham = {
  gridManager: null,
  cardStack: null,
  resizeTimeout: null,
  flashBlocked: false,
  config: {
    container: 'container',
    pageSize: 20,
    insertDomId: 'insert-dom',
    cssTransClass: 'csstrans',
    closedInnerWidth: 220,
    closedOuterWidth: 222,
    closedInnerHeight: 330,
    closedOuterHeight: 332
  },

  initialize: function () {
    var container = document.id(Denham.config.container);
    container.empty(); // empty the container. Contents will be refreshed
    noSplash = $$('html')[0].hasClass('nosplash');

    if ($('splash')) {
      if (noSplash) {
        $('splash').destroy();
        $$('html')[0].removeClass('nosplash')
      } else {
        $('splash').getElements('a').addEvent('click', function () {
          $('splash').destroy();
          $$('html')[0].removeClass('nosplash')
        });
      }
    }

    // Create an invisible element to convert HTML strings to DOM structures
    var insertDomElm = new Element('div', {'id': Denham.config.insertDomId})
    $$('body')[0].grab(insertDomElm);

    // When CSS animations are present use them instead of JS animations
    var tempDiv = new Element('div');
    $$('body')[0].grab(tempDiv);

    tempDiv.setStyles({
      '-webkit-transition': 'top 1s',
      '-moz-transition': 'top 1s',
      'transition': 'top 1s',
      '-o-transition': 'top 1s',
      '-ms-transition': 'top 1s'
    });

    var webkitStyle = tempDiv.getStyle('-webkit-transition-duration');
    var mozStyle    = tempDiv.getStyle('-moz-transition-duration');
    var w3cStyle    = tempDiv.getStyle('transition-duration');
    var operaStyle  = tempDiv.getStyle('-o-transition-duration');
    var msStyle     = tempDiv.getStyle('-ms-transition-duration');

    var webkitTrans = (webkitStyle != '' && webkitStyle != 'null' && webkitStyle != 'undefined' && webkitStyle != undefined);
    var mozTrans    = (mozStyle != '' && mozStyle != 'null' && mozStyle != 'undefined' && w3cStyle != undefined);
    var w3cTrans    = (w3cStyle != '' && w3cStyle != 'null' && w3cStyle != 'undefined' && w3cStyle != undefined);
    var operaTrans  = (operaStyle != '' && operaStyle != 'null' && operaStyle != 'undefined' && operaStyle != undefined);
    var msTrans     = (msStyle != '' && msStyle != 'null' && msStyle != 'undefined' && msStyle != undefined);

    if (webkitTrans || mozTrans || w3cTrans || operaTrans || msTrans) {
      $$('body')[0].addClass(Denham.config.cssTransClass);
    }

    tempDiv.dispose();

    // Get an relationship between section ids and slugs
    var sections = new Hash();
    $$('#descriptions p').each(function (el) {
      if (!el.get('id')) return el;

      var idChunks = el.get('id').match(/section\-([0-9]+)\-([^"]+)/);
      sections.set(idChunks[1], idChunks[2]);
    });

    Denham.sections = sections;

    // Rewrite all the section filters to AJAX urls
    Denham.sections.each(function (sectionSlug, sectionId) {
      var sectionFilter1 = document.id('section-' + sectionId + '-filter1');

      if (sectionFilter1) {
        sectionFilter1.getElements('a').each(function (link) {
          var filter = link.getParent().get('id').split('-')[0];
          link.set('href', '/#/' + sectionSlug + '/' + filter + '/all/1/');
        });
      }

      var sectionFilter2 = document.id('section-' + sectionId + '-filter2');

      if (sectionFilter2) {
        sectionFilter2.getParent().addClass('showdivider');
        sectionFilter2.getElements('a').each(function (link) {
          var filter = link.getParent().get('id').split('-')[0];
          link.set('href', '/#/' + sectionSlug + '/all/' + filter + '/1/');
        });
      }
    });

    $$('#submenu form')[0].addEvent('submit', function (e) {
      var field   = $('q'),
          query   = field.get('value'),
          defaultValueInstance = field.retrieve('instance'),
          webstoreMatches = defaultValueInstance._defaultValue.match(/webstore/i),
          section = webstoreMatches != null ? 'webstore' : 'all';

      e.stop();
      document.location.href = '/#/cards/search/' + section + '/1/' + query + '/';
    });

    if (Browser.Plugins.Flash.version > 0 && Browser.Plugins.Flash.build)
      new Swiff('/flash/denham-scissors.swf', {'container': 'animation', 'width': '180', 'height': '120'});

    // Determine the dimensions of the cards (used in the GridManager)
    var gridManagerOptions = {
      closedInnerWidth: Denham.config.closedInnerWidth,
      closedOuterWidth: Denham.config.closedOuterWidth,
      closedInnerHeight: Denham.config.closedInnerHeight,
      closedOuterHeight: Denham.config.closedOuterHeight
    }

    // Initialize the gridmanager
    Denham.gridManager = new GridManager(container, gridManagerOptions);

    // Create the card stack  
    Denham.cardStack = new CardStack();

    // Add an handler to the resize function to reflow the cards
    window.addEvent('resize', function () {
      var headerWidth = $('header').getSize().x;

      // use hard 440 value for IE (ignores margin-right on #descriptions)
      $('descriptions').setStyle('width', headerWidth - 395);

      window.clearTimeout(Denham.resizeTimeout);
      Denham.resizeTimeout = Denham.gridManager.distribute.delay(100, Denham.gridManager)
    });

    // Function attached as eventhandler to SWFAddress events
    // Handles only external changes and initial settings.
    // Opening of a card by clicking on it is handled in the container clickhandler
    var urlChangeHandler = function (e) {
      _gaq.push(['_trackPageview', document.location.toString()]);

      if (e.pathNames[0] != 'card') { // Page of cards
        var options = {};
        options.pageSize = Denham.config.pageSize;

        if (e.pathNames[1] == 'search') { // Search page
          options.section  = e.pathNames[2];
          options.page     = e.pathNames[3];
          options.query    = e.pathNames[4] || '';

        } else { // Regular page
          options.section  = e.pathNames[0] || 'all';
          options.category = e.pathNames[1] || 'all';
          options.filter   = e.pathNames[2] || 'all';
          options.page     = parseInt(e.pathNames[3]) > 0 ? e.pathNames[3] : '1';

          Denham.slideshow.updateSlideshow(options.section, options.category, options.filter);
        }

        // determine the menu item
        var section;
        if (e.pathNames[0] == 'all' || e.pathNames[1] == 'search') {
          if (e.pathNames[2] == 'webstore') {
            section = 'webstore';
          } else {
            section = 'home';
          }
        } else {
          section = e.pathNames[0];
        }

        section = section || 'home';

        Denham.showPage(options);

      } else { // Detail view of a card
        if (Denham.gridManager.cards.length == 0) {
          var options = {
            section: 'all',
            category: 'all',
            filter: 'all',
            page: '1',
            pageSize: Denham.config.pageSize
          }

          Denham.showPage(options);
        }

        Denham.showCard('card-' + e.pathNames[1]);

        if (Denham.cardStack.cards['card-' + e.pathNames[1]]) {
          var cardToShow = Denham.cardStack.cards['card-' + e.pathNames[1]];

          if (cardToShow.element.hasClass('brand')) {
            section = 'brand';
          } else if (cardToShow.element.hasClass('collection')) {
            section = 'collection';
          } else if (cardToShow.element.hasClass('garment-library')) {
            section = 'garment-library';
          } else if (cardToShow.element.hasClass('reports')) {
            section = 'reports';
          } else if (cardToShow.element.hasClass('cutters-council')) {
            section = 'cutters-council';
          } else if (cardToShow.element.hasClass('webstore')) {
            section = 'webstore';
          } else {
            section = 'home';
          }
        } else {
          section = 'home';
        }
      }

      var selectedLink = $$('#nav-' + section + ' a')[0];
      Menu.setSelected(selectedLink);

      if (section == 'webstore') {
        $('q').retrieve('instance')._defaultValue = 'Search webstore';
        $('q').set('value', 'Search webstore');

        Denham.gridManager.options.maxRowWidth = 4;

      } else {
        $('q').retrieve('instance')._defaultValue = 'Search';
        $('q').set('value', 'Search');

        Denham.gridManager.options.maxRowWidth = 6;
      }

      Denham.gridManager.distribute.delay(200, Denham.gridManager);
    }

    SWFAddress.addEventListener(SWFAddressEvent.INTERNAL_CHANGE, urlChangeHandler); //somehow needed for IE
    SWFAddress.addEventListener(SWFAddressEvent.EXTERNAL_CHANGE, urlChangeHandler);
    
    if (noSplash)
      SWFAddress.addEventListener(SWFAddressEvent.INIT, urlChangeHandler);

    // Add a click delegate on the container. Opens the card or switches the large image in a gallery
    container.addEvent('click', function (e) {
      var target = document.id(e.target),
          card = target.getParent('.card'),
          deeplink, largeId;

      //check if the close button was clicked
      if (target.hasClass('close-btn')) {
        Denham.gridManager.openCard = '';
        Denham.gridManager.distribute.delay(200, Denham.gridManager);

      // check if the thumb in an image gallery was clicked
      } else if (target.get('id') && target.get('id').match(/^small\-[0-9]+/) && target.get('tag') == 'img') {
        target.getParent('ul').getElements('li').removeClass('active');
        target.getParent().addClass('sticky');
        target.getParent().addClass('active');

        target.getParent('.mod-gallery').getElements('.view .bigimage').addClass('hide');
        largeId = target.get('id').replace('small-', 'large-');
        document.id(largeId).getParent().removeClass('hide');

      //check if the triangle linking to a different card is checked
      } else if (target.getParent().hasClass('state') && (target.getParent().hasClass('buy_now') || target.getParent().hasClass('read_review'))) {
        deeplink = target.get('href');

        if (deeplink.match(/^http/))
          deeplink = deeplink.replace('http://' + document.location.hostname, '');

        urlChunks = deeplink.split('/');

        document.location.hash = '#' + deeplink;

        e.preventDefault();
        e.stop();

      } else if (!target.hasClass('section-overview')) {
        if (card && !card.hasClass('custom-url')) {
          if (Denham.gridManager.openCard != card.id) {
            var deeplink = card.getElement('.readmore a').get('href');

            if (deeplink.match(/^http/))
              deeplink = deeplink.replace('http://' + document.location.hostname, '');

            if ('#' + deeplink == document.location.hash) {
              Denham.showCard(card.id);
              Denham.gridManager.distribute();
            } else {
              SWFAddress.setValue(deeplink);
              e.preventDefault();
            }
          }
        }
      }
    });

    container.addEvent('mouseover', function (e) {
      var target = document.id(e.target);

      if (target.get && target.get('id') && target.get('id').match(/^small\-[0-9]+/) && target.get('tag') == 'img') {
        if (!target.getParent('.mod-gallery').getElement('.sticky')) {
          target.getParent('.mod-gallery').getElements('.view .bigimage').addClass('hide');
          var largeId = target.get('id').replace('small-', 'large-');
          document.id(largeId).getParent().removeClass('hide');

          target.getParent('ul').getElements('li').removeClass('active');
          target.getParent('li').addClass('active');
        }
      }
    });
  },


  /**
   * Handles the switch to another page
   * @param {Object} options
   */
  showPage: function (options) {
    // Compare both selections and take out the elements that are not in the new selection
    var oldSelection = Denham.gridManager.cards;
    var newSelection = Denham.cardStack.getSelection(options);

    // Remove the cards from the old selection that are not in the new selection
    oldSelection.each(function (card) {
      if (!newSelection.contains(card))
        card.removeFromDom();
    });

    // Place all the cards from the new selection in the container
    newSelection.each(function (card) {
      card.placeInDom();
    });

    // Update the gridmanager with the new cards and distribute them
    Denham.gridManager.openCard = '';
    Denham.gridManager.cards = newSelection;

    // Build the pagination. Include previous / next buttons.
    // Use page numbers in webstore, offsets in other sections
    var paginators = $$('.pagination');
    var numPages   = Denham.cardStack.pagesForSelection;

    paginators.each(function (item) {
      item.empty();

      if (options.section == 'webstore') {
        item.appendText('Page: ');
      } else {
        item.appendText('Cards: ');
      }
    });

    var url, pageText, prev, next, prevUrl, nextUrl;
    for (var page=1; page<numPages+1; page++) {
      if (options.query) {
        url = '/#/cards/search/' + page + '/' + options.query +'/'; 
      } else {
        url = '/#/' + options.section + '/' + options.category + '/' + options.filter + '/' + page + '/';
      }

      if (options.section == 'webstore') {
        pageText = page;
      } else {
        pageText  = (((page - 1) * 20) + 1).toString();
        pageText += ' - ';

        //Make sure the last button corresponds to the correct number of cards (might not be 20)
        if (page == numPages) {
          pageText += Denham.cardStack.totalInSelection.toString();     
        } else {
          pageText += (page * 20).toString();
        }
      }

      prev = null;
      next = null;

      if (page == 1 && options.page > 1) {
        prevUrl = url.replace(/\/[0-9]+\//, '/' + (parseInt(options.page)-1) + '/'); 
        prev = new Element('a', {'href': prevUrl, 'text': 'Previous'});
      }

      if (page == numPages && options.page < numPages) {
        nextUrl = url.replace(/\/[0-9]+\//, '/' + (parseInt(options.page)+1) + '/'); 
        next = new Element('a', {'href': nextUrl, 'text': 'Next'});
      }

      paginators.each(function (item) {
        if (prev !== null) {
          item.grab(prev.clone());
        }

        if (page == options.page) {
          item.grab(new Element('span', {'text': pageText}));
        } else {
          item.grab(new Element('a', {'href': url, 'text': pageText}));
        }

        if (next !== null) {
          item.grab(next.clone());
        }
      });
    }

    // Set the page title
    if (options.query) {
      document.title = 'Search results for: "' + options.query + '"'
    } else {
      var title = 'Overview for "' + options.section + '"';

      if (options.category != 'all' && options.filter != 'all') {
        title += ' filtered on "' + options.category + '" and "' + options.filter + '"';
      } else if (options.category != 'all') {
        title += ' filtered on "' + options.category + '"';
      } else if (options.filter != 'all') {
        title += ' filtered on "' + options.filter + '"';
      }

      document.title = title;
    }
  },


  /**
   * Opens a card
   */
  showCard: function (cardId) {
    var cardOnPage = false;
    for (var i=0; i<Denham.gridManager.cards.length; i++) {
      if (Denham.gridManager.cards[i].id == cardId) {
        cardOnPage = true;
        break;
      }
    }

    // if the card is not on the page, make sure that it will be
    if (!cardOnPage) {
      if (!Denham.cardStack.cards[cardId]) {
        (new Request({
          url: document.location.href.split('#')[1],
          async: false,
          method: 'get',
          evalScripts: true,
          onComplete: function (responseText) {
            var insertDom = document.id(Denham.config.insertDomId);
            insertDom.innerHTML = responseText;

            var cardTitle = insertDom.getFirst().getElement('h1').get('text');
            var cardSubTitle = insertDom.getFirst().getElement('h2').get('text');

            var card = new Card(insertDom.getFirst(), document.id(Denham.config.container));
            card.title = cardTitle;
            card.subTitle = cardSubTitle;
            card.removeFromDom();
            Denham.cardStack.cards[cardId] = card;
          }
        })).send();
      }

      // Set the options for the surrounding cards
      var pageOptions = {
        section: 'all',
        category: 'all',
        filter: 'all',
        page: 1,
        pageSize: 20
      };

      var cardToShow = Denham.cardStack.cards[cardId];
      if (cardToShow.element.hasClass('brand')) {
        pageOptions.section = 'brand';
      } else if (cardToShow.element.hasClass('collection')) {
        pageOptions.section = 'collection';
      } else if (cardToShow.element.hasClass('garment-library')) {
        pageOptions.section = 'garment-library';
      } else if (cardToShow.element.hasClass('reports')) {
        pageOptions.section = 'reports';
      } else if (cardToShow.element.hasClass('cutters-council')) {
        pageOptions.section = 'cutters-council';
      } else if (cardToShow.element.hasClass('webstore')) {
        pageOptions.section = 'webstore';
      }

      // Fetch all the cards for the first page of the home view.
      Denham.showPage(pageOptions);

      //Do a final check to see if the open card is not also in the other cards
      Denham.gridManager.cards.each(function (card, index, cards) {
        if (card && card.id == cardId)
          cards.splice(index, 1);
      });

      //Remove the open spot left by the splice action
      Denham.gridManager.cards = Denham.gridManager.cards.clean();

      // Place the card to open at the beginning of the array
      Denham.gridManager.cards.unshift(cardToShow);

      //Place the card in the DOM
      cardToShow.placeInDom();

    } else {
      var card = Denham.cardStack.cards[cardId],
          deeplink = '';

      if (card.element.getElement('.readmore a')) {
        deeplink = card.element.getElement('.readmore a').get('href');
      } else if (card.element.getElement('.state a')) {
        deeplink = card.element.getElement('.state a').get('href');
      }

      if (deeplink.match(/^http/)) {
        deeplink = deeplink.replace('http://' + document.location.hostname, '');
      }

      SWFAddress.setValue(deeplink);
    }

    Denham.gridManager.openCard = cardId;

    var title = Denham.cardStack.cards[cardId].title;
    title += ', ' + Denham.cardStack.cards[cardId].subTitle;

    document.title = title;
  },


  /**
   * Creates one or more cards from a string of HTML (might want to rewrite the header replacing bit using regexp & innerHTML)
   * @param {Object} string
   */
  createCardsFromHTML: function (string) {
    var insertDom  = document.id(Denham.config.insertDomId);
    var cardOffset = Denham.gridManager.options.margin;
    var container  = document.id(Denham.config.container);

    insertDom.innerHTML = string;

    insertDom.getElements('.footer a.section-overview').each(function (link) {
      var url = link.get('href');
      var ajaxURL  = '';
      var matches  = url.match(/([0-9]+)-([0-9]+)/);
      var offset   = matches[1];
      var pagesize = matches[2];
      var page = (offset / pagesize) + 1;

      ajaxURL = url.replace(/^\/cards\//, '/#/');
      ajaxURL = ajaxURL.replace(/([0-9]+)-([0-9]+)/, page);
      
      link.set('href', ajaxURL);
    });

    insertDom.getElements('.card').each(function (cardNode) {
      // Replace the <h1> and <h2> with a flash header

      var h1       = cardNode.getElement('h1');
      var h2       = cardNode.getElement('h2');
      var header   = cardNode.getElement('.header');
      var title    = h1.get('text');
      var subTitle = h2.get('text');

      // Set the card on the top left so that it animates when it is shown
      cardNode.setStyles({'top': cardOffset, 'left': cardOffset});

      // Create a card element and place it on the stack
      var card = new Card(cardNode, container);
      card.removeFromDom();
      card.title = title;
      card.subTitle = subTitle;
      Denham.cardStack.cards[card.id] = card;
    });
  },

  showNoCardsMessage: function () {
    var noCards = document.id('nocards'),
        message,
        button;

    if (Menu.selected && Menu.selected.getParent().get('id') == 'nav-webstore') {
      message = new Element('p', {'text': 'There are no cards for your selection. We will show the webstore.'});
      button  = new Element('a', {'href': '/#/webstore/all/all/1/', 'text': 'OK'})
    } else {
      message = new Element('p', {'text': 'There are no cards for your selection. We will show the homepage.'});
      button  = new Element('a', {'href': '/#/all/all/all/1/', 'text': 'OK'})
    }

    if (noCards) {
      noCards.setStyle('display', 'block');
      noCards.getElement('p').destroy();
      noCards.getElement('a').destroy();
    } else {
      noCards  = new Element('div', {'id': 'nocards'});

      $$('body')[0].grab(noCards);
    }

    noCards.adopt(message, button);
  },

  hideNoCardsMessage: function () {
    if (document.id('nocards'))
      document.id('nocards').setStyle('display', 'none');
  },

  refreshWebstoreIframe: function (url) {
    var iframe = $$('#descriptions .webstore iframe')[0];
    url = iframe.get('src');

    iframe.set('src', url);
  },

  showCheckout: function (url) {
    //document.domain = 'denhamthejeanmaker.com';

    var backdrop = new Element('div', {'id': 'backdrop'}),
        panel    = new Element('div', {'id': 'checkoutpanel'}),
        iframe   = new Element('iframe', {'src': url}),
        close    = new Element('img', {'src': '/images/header-icon-close.gif', 'class': 'close'}),
        panelHeight, closeBtnHeight;

    close.addEvent('click', function () {
      Denham.closeCheckout();
    });

    panel.adopt(close);

    panel.adopt(iframe);
    $$('body')[0].adopt(backdrop, panel);
    
    panelHeight = panel.getSize().y;
    closeBtnHeight = close.getSize().y;

    iframe.setStyle('height', panelHeight - closeBtnHeight);
  },

  closeCheckout: function () {
    var firstDotIndex = document.location.host.indexOf('.');

    document.domain = document.location.host.substr(firstDotIndex+1);
    
    $$('#checkoutpanel, #backdrop').destroy();
  }
};

window.addEvent('domready', Denham.initialize);

