(function($){

  var global = this;

  var recentlyViewedText = this.recentlyViewedText || "Vus récemment";

  // On DOM loaded:
  $(function() {
    $('#productselector').N_productSelector().addClass('js');
  });

  /*------------------------------------------------------------------------*/

  /* Products */

  var NPS = {};

  $.fn.N_productSelector = function(options) {
    var options = jQuery.extend({
      groupPath:  'div.group',
      itemPath:   'li',
      headerPath: 'h3:first'
    }, options);

    if (!this.length || this.length > 1) return this;

    var selector = this;
    NPS.selector = selector;

    var isServices = !!selector.find('.products.services').length;
    if (isServices) return this;

    // Create data object
    var groups = selector.find(options.groupPath);
    NPS.collectData.call(groups, options);

    NPS.hoverThumbs.init.call(groups, options);

    var viewNav = selector.find('ul.views');

    viewNav.find('li a').click(function() {
      var link = $(this);
      if (link.parent().hasClass('thumbnails')) {
        NPS.setView('thumbnails');
      } else {
        NPS.setView('text');
      }
      return false;
    });

    NPS.productsArea = selector.find('div.products:first');
    NPS.viewNav = viewNav;
    NPS.setView('mostwanted');

    NPS.paginator.init();

    var showAll = selector.find('.showall a');
    showAll.click(function() {
      NPS.setView('thumbnails');
      $(this).parent().remove();
      return false;
    });
    NPS.showAll = showAll;

    NPS.initTypesNav();
    NPS.addNavigation();
    NPS.addImages();

    return this;
  };

  NPS.collectData = function(options) {
    var groups = this;
    var data   = { "items": [], "series": [], "itemsPerRow": 7, "isAccessories": false };
    var isAccessories = !!groups.slice(0,1).parents('.accessories').length;
    if (isAccessories) {
      data.itemsPerRow   = 6;
      data.isAccessories = true;
    }

    groups.each(function() {
      var group  = $(this);
      var items  = group.find(options.itemPath);

      data.series.push(group);

      items.each(function(i) {
        var item  = $(this);
        var types = ['undefined'];
        var link  = item.find('a');
        var name  = link.text();
        var sName = link.attr('title');

        var typeRE = item[0].className.match(/type_([^\s]+)/g);
        if (typeRE) {
          types = [];
          for (var i = 0; i < typeRE.length; i++) {
            types.push(typeRE[i].match(/type_([^\s]+)/)[1]);
          }
        }

        link.click(NPS.setCookie);

        item.prodName  = name;
        item.shortName = sName;
        item.types     = types;

        data.items.push(item);

        if (i % data.itemsPerRow == 0) {
          item.addClass('newline');
          if ($.browser.msie) item.before('<br style="clear:both;line-height:0;"/>');
        }
      });
    });

    NPS.data = data;
  };

  NPS.addImages = function() {
    var data = NPS.data;
    var pathPrefix = "http://www.nokia.ie/NOKIA_FINLAND_50/Get_Support/Common_elements/product_selector/";

    // Check for "recently viewed" cookie
    var deviceCookieRE    = document.cookie.match(/last_visited_device=([^;]+)/);
    var accessoryCookieRE = document.cookie.match(/last_visited_accessory=([^;]+)/);
    var recentDevice = (deviceCookieRE) ? deviceCookieRE[1] : "";
    var recentAccessory = (accessoryCookieRE) ? accessoryCookieRE[1] : "";

    var mostwanted = [];
    var recentIsAccessory;
    var mostwantedIsRecent;

    for (var i = 0; i < data.items.length; i++) {
      if (!data.items[i]) break;
      var item = data.items[i];
      var jqItem = $(item);
      var link = jqItem.find('a:first');
      link.prepend('<img src="'+pathPrefix+'images/products/'+item.shortName+'.jpg" />');

      if (jqItem.hasClass('mostwanted')) mostwanted.push(item);

      if (item.shortName == recentDevice || item.shortName == recentAccessory) {
        mostwantedIsRecent = !!(jqItem.hasClass('mostwanted'));
        jqItem.addClass('recent').addClass('mostwanted');
        jqItem.append('<em class="recent">'+recentlyViewedText+'</em>');
        recentIsAccessory = !!(item.shortName == recentAccessory);
        NPS.productsArea.addClass('hasrecent');
        if (data.isAccessories) NPS.productsArea.addClass('accessories_hasrecent');
      }
    }

    var lastMostwanted = mostwanted[mostwanted.length-1];
    if (
      (deviceCookieRE || accessoryCookieRE)
      && ((data.isAccessories && recentIsAccessory) || (!data.isAccessories && !recentIsAccessory))
      && !mostwantedIsRecent
    ) {
      lastMostwanted.removeClass('mostwanted');
    }
  };

  NPS.initTypesNav = function() {
    var selector = NPS.selector;
    var header = selector.find('.types-nav h3');

    var container = header.parent();
    var selection = container.find('ul.selection');
    var nav = container.find('ul.types');
    var navItems = nav.find('li');

    var originalHeight = container.height();
    container.css('height', originalHeight);

    var rows = (Math.ceil(navItems.length / 3));
    var extraHeight = 45*rows;
    
    selector.find('.types-nav h3').click(function(){
      if (header.hasClass('expanded')) { // minimize
        container.animate({ height: originalHeight }, 200);
        selection.fadeOut(200);
        nav.fadeOut(200);
      
        header.removeClass('expanded');
      
        nav.find('li.checked a').trigger('click');
        NPS.showTypes([]);
      } else {
        container.animate({ height: originalHeight+extraHeight }, 200);
        selection.fadeIn(200);
        nav.fadeIn(200);
      
        header.addClass('expanded');
      
        NPS.productsArea.removeClass('mostwanted').removeClass('hasrecent').removeClass('accessories_hasrecent');
        NPS.removeShowAll();
        NPS.redraw();
        NPS.paginator.show();
      }

      return false;
    });
  };

  NPS.addNavigation = function() {
    var selector = NPS.selector;

    /* Type navigation */
    var checked = {};
    var timer;

    var typeContainer = selector.find('.types-nav');

    var switchTypes = function(type) {
      var link = $(this);
      var item = link.parent();
      if (item.hasClass('checked')) {
        checked[type] = false;
        item.removeClass('checked');
      } else {
        checked[type] = true;
        item.addClass('checked');
      }

      timer = setTimeout(function() {
        var types = [];
        for (t in checked) {
          if (checked[t]) types.push(t);
        }
        NPS.showTypes(types);
      }, 50);
    };

    // Select all/none buttons
    var selectAllButton  = typeContainer.find('.all a');
    var selectNoneButton = typeContainer.find('.none a');

    selectAllButton.click(function() {
      typeContainer.find('.types li:not(.checked) a').trigger('click');
      return false;
    });
    selectNoneButton.click(function() {
      typeContainer.find('.types li.checked a').trigger('click');
      return false;
    });

    // Buttons for each type
    selector.find('.types li a').each(function() {
      var link = $(this);
      var item = link.parent();
      var type = 'Undefined';
      var typeRE = item[0].className.match(/type_([^\s]+)/);
      if (typeRE) type = typeRE[1];

      checked[type] = false;

      link.click(function() {
        switchTypes.call(this, type);
        return false;
      });
    });
  };

  NPS.redraw = function() {
    var data = NPS.data;

    for (var i = 0; i < data.series.length; i++) {
      var group = $(data.series[i]);
      var items = group.find('li:visible');
      if (!items.length) group.css('display', 'none');
      else {
        items.each(function(k) {
          if (k % data.itemsPerRow == 0) {
            var item = $(this);
            item.addClass('newline');
            if ($.browser.msie) item.before('<br style="clear:both;line-height:0;"/>')
          }
        });
      }
    }
  };

  NPS.hoverThumbs = {
    init: function(options) {
      var items = this.find(options.itemPath);
      items.bind('mouseenter', function(e) {
        if (!$(this).parents('.thumbnails').length) NPS.hoverThumbs.show.call(this, options);
      }).bind('mouseleave', function(e) {
        NPS.hoverThumbs.hide();
      });
    },

    create: function(options) {
      if (NPS.hoverThumbs.thumb) return;

      var thumb = $('<div id="productselector_thumb" />');
      var img   = $('<img />');

      thumb.append(img);

      thumb.bind('mouseenter', function() {
        NPS.hoverThumbs.show();
      }).bind('mouseleave', function() {
        NPS.hoverThumbs.hide();
      });

      $('body').append(thumb);

      NPS.hoverThumbs.thumb = thumb;
      NPS.hoverThumbs.img   = img;

      NPS.hoverThumbs.xPos = 0;

      $().mousemove(function(e) {
        if (thumb.is(':visible')) thumb.css('left', e.pageX+5);
      });
    },

    show: function(options) {
      NPS.hoverThumbs.create(options);
      var item;

      if (this.nodeName) {
        item  = $(this);
      } else {
        item = NPS.hoverThumbs.item;
      }

      var thumb = NPS.hoverThumbs.thumb;
      var img   = NPS.hoverThumbs.img;

      if (NPS.hoverThumbs.item != item) {
        NPS.hoverThumbs.item = item;

        var oImg = item.find('img');
        img.attr('src', oImg.attr('src'));

        var offset = item.offset();
        var height = item.height();
        var width  = item.width();
        thumb.css('top', offset.top+24);
      }

      thumb.show();
    },

    hide: function() {
      if (NPS.hoverThumbs.thumb) NPS.hoverThumbs.thumb.hide();
    }
  };

  NPS.showTypes = function(types) {
    if (!types || !types.push) return false;

    clearTimeout(NPS.showTypesTimer);

    NPS.showTypesTimer = setTimeout(function() {
      var data = NPS.data;
      var area = NPS.productsArea;
      var renderItems = function() {
        for (var i = 0; i < data.items.length; i++) {
          var item = data.items[i];
          var iTypes = "|"+item.types.join("|")+"|";
          var show = !types.length ? true : false;
          for (var t = 0; t < types.length; t++) {
            if (iTypes.indexOf("|"+types[t]+"|") >= 0) show = true;
          }
          if (show) {
            item.parents('.group:first').show();
            item.stop().fadeIn(300);
          } else {
            item.stop().fadeOut(200);
          }
        }

        setTimeout(function() {
          NPS.redraw();
          NPS.paginator.redraw();
          NPS.paginator.flipTo(1);
          NPS.paginator.show();
        }, 210);
      };

      area.find('li.newline').removeClass('newline');
      if ($.browser.msie) area.find('br').remove();

      if (area.hasClass('mostwanted')) {
        for (var i = 0; i < data.items.length; i++) {
          var item = $(data.items[i]);
          item.css('display', 'none');
        }
        area.removeClass('mostwanted').removeClass('hasrecent').removeClass('accessories_hasrecent');
        NPS.removeShowAll();
        NPS.paginator.show();
        renderItems();
      } else {
        renderItems();
      }
    }, 200);
  };

  NPS.setView = function(type) {
    var area = NPS.productsArea;
    var viewNav = NPS.viewNav;
    viewNav.find('li.active').removeClass('active');

    area.find('li.newline').removeClass('newline');
    if ($.browser.msie) area.find('br').remove();

    if (type == 'thumbnails') {
      area.removeClass('mostwanted').removeClass('hasrecent').removeClass('accessories_hasrecent');
      area.addClass('thumbnails');
      viewNav.find('.thumbnails').addClass('active');
      NPS.redraw();
      NPS.paginator.show();
    } else if (type == 'mostwanted') {
      area.addClass('mostwanted');
      area.addClass('thumbnails');
      viewNav.find('.thumbnails').addClass('active');
    } else {
      area.removeClass('mostwanted').removeClass('hasrecent').removeClass('accessories_hasrecent');
      area.removeClass('thumbnails');
      viewNav.find('.text').addClass('active');
      NPS.redraw();
      NPS.paginator.show();
    }

    NPS.removeShowAll();
  };

  NPS.removeShowAll = function() {
    if (NPS.showAll) {
      NPS.showAll.parent().remove();
      NPS.showAll = null;
    }
  };

  NPS.paginator = {
    init: function(perPage) {
      var selector = NPS.selector;
      var info = {};
      
      info.perPage = 3;
      info.container = selector.find('.paginator');
      info.list = info.container.find('ul');
      info.prevLink = info.list.find('li.prev');
      info.nextLink = info.list.find('li.next');
      info.countElm = info.container.find('p.pagecount');
      info.allLink = info.container.find('p.all a');
      info.allCountElm = info.container.find('p.all em');

      // Bind previous/next and Show all events
      info.prevLink.click(NPS.paginator.flipToPrev);
      info.nextLink.click(NPS.paginator.flipToNext);
      info.allLink.click(function() {
        NPS.paginator.flipTo('all');
        return false;
      });

      // Store variables for future use
      NPS.paginator.info = info;
    },

    redraw: function() {
      var area = NPS.productsArea;
      var info = NPS.paginator.info;

      var visibleGroups = area.find('.group:visible');
      var totalPages = (Math.ceil(visibleGroups.length/info.perPage));
      info.totalPages = totalPages;

      // Create page links
      info.list.find('li:not(.prev):not(.next)').remove();
      for (var i = 0; i < totalPages; i++) {
        var page = i+1;
        var link = $('<a href="#">'+page+'</a>');
        var item = $('<li />');

        if (i==0) item.addClass('first');

        link.bind('click', { page: page }, function(e) {
          NPS.paginator.flipTo(e.data.page, true);
          $(this).trigger('blur');
          return false;
        });

        item.append(link);
        info.nextLink.before(item);
      }

      info.container.show();

      var visibleItems = area.find('.group li:visible');
      info.allCountElm.text('('+visibleItems.length+')');
    },

    flipTo: function(page, scroll) {
      setTimeout(function() {
        var selector = NPS.selector;
        var area = NPS.productsArea;
        var info = NPS.paginator.info;
        var data = NPS.data;
        var items = info.list.find('li:not(.prev):not(.next)');

        if (page == 'all') { // Show all pages
          info.container.hide();
          for (var i = 0; i < data.series.length; i++) {
            var group = $(data.series[i]);
            if (group.find('li:visible').length) group.css('display', '');
          }
        } else { // Do the page flip
          var x = 0;
          var current = 1;
          var visibleGroups = selector.find('.group:has(li:visible)');
          visibleGroups.each(function() {
            var group = $(this);
            if (current == page) {
              group.show();
            } else {
              group.hide();
            }
            x++;
            if (x == info.perPage) {
              x = 0;
              current++;
            }
          });

          items.removeClass('current');
          items.slice(page-1, page).addClass('current');
          info.currentPage = page;

          var tmp = info.countElm.text();
          tmp = tmp.replace(/^([^\d]*)\d([^\d]*)\d$([^\d]*)/, '$1'+page+'$2'+info.totalPages+'$3');
          info.countElm.text(tmp);
        }

        if (scroll) $('html,body').animate({ scrollTop: area.offset().top });
      }, 10);
    },

    flipToNext: function() {
      var info = NPS.paginator.info;
      if (info.currentPage < info.totalPages) NPS.paginator.flipTo(info.currentPage+1, true);
      return false;
    },

    flipToPrev: function() {
      var info = NPS.paginator.info;
      if (info.currentPage > 1) NPS.paginator.flipTo(info.currentPage-1, true);
      return false;
    },

    show: function() {
      var info = NPS.paginator.info;
      if (!info.container.is(':visible')) {
        NPS.paginator.redraw();
        NPS.paginator.flipTo(1);
        info.container.show();
      }
    }
  };

  NPS.setCookie = function() {
    var link = $(this);
    var id   = link.attr('title');

    var days = 365;
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = date.toGMTString();

    var type = (link.parents('.accessories:first').length) ? "accessory" : "device";
    document.cookie = 'last_visited_'+type+'='+id+'; expires='+expires+';';
  };

  NPS.cleanName = function(str) {
    str = str.toLowerCase();
    str = str.replace(/^nokia[\s]*/, '');
    str = str.replace(/[^\w\d]+/g, '_');
    return str;
  };

  global.NPS = NPS;

}(jQuery));
