﻿

<!--
[].indexOf || (Array.prototype.indexOf = function (v, n) {
    n = (n == null) ? 0 : n; var m = this.length;
    for (var i = n; i < m; i++) if (this[i] == v) return i;
    return -1;
});
[].map || (Array.prototype.map = function(fun /*, thisp*/) {
    var len = this.length;
    if (typeof fun != "function") throw new TypeError();
    var res = new Array(len);
    var thisp = arguments[1];
    for (var i = 0; i < len; i++) {
      if (i in this) res[i] = fun.call(thisp, this[i], i, this);
    }
    return res;
});
(function ($) {
    $.fn.toString = function () {
        var rS = [];
        this.each(function () { rS.push($('<span>').append($(this).clone()).remove().html()); });
        return rS.join('');
    }
})(jQuery);
(function($){
 /**
  * Obiekt krajalnicy breadcrumbów. Ustawia opcje oraz odpala caly mechanizm.
  * @param {dom object} B obiekt kontenera breadcrumbów
  * @param {json}   O ustawienia krajalnicy (opcjonalne)
  */
 var BreadCutter = function(B, O){
  this.breadcrumb = $(B);
  this.options = $.extend({}, this.defaults, O);
  this.init();
 };
 BreadCutter.prototype = {
  /**
   * domyślne opcje systemowe;)
   * {integer} maxCharCount    maksymalna liczba znaków jaka ma być wyświetlana w breadcrumbie<br/>
   *           z pominięciem tych pozycji, których indeksy są podane w exceptionCrumbs
   * {array}  exceptionCrumbs    lista pozycji breadcrumba, które mają być pominięte w zliczaniu znaków<br/>
   *           oddzielone przecinkami jeśli wiecej niż 1
   * {string}  dots      ciąg wstawiany w skrót zamiast chowanych crumbów
   * {json}  events      obsługa zdarzeń przypisanych skrótom do kryjówek<br/>
   *           obsługiwane zdarzenia to click, mouseenter, mouseleave
   */
  defaults: {
   maxCharCount: 300,
   exceptionCrumbs: '0',
   dots: '...',
   events: {
    click: false,
    mouseenter: false,
    mouseleave: false
   }
  },
  /**
   * Metoda uruchamiajaca cały mechanizm krojenia.
   */
  init: function(){                        
   this.setExceptions();
   this.prepareCrumbsToHide();
   this.groupDots();
   this.hideCrumbs();
   this.setEvents();
  },
  setExceptions: function(){
   var _this = this;   
   this.exceptions = this.options.exceptionCrumbs ? this.options.exceptionCrumbs.split(',').map(function(e){ return parseInt(e, 10); }) : [];
   this.breadcrumb.children('li').each(function(i){ if(_this.exceptions.indexOf(i) == -1) $(this).addClass('BC-available'); });
  },
  /**
   * Metoda pobierająca długość tekstu w breadcrumbie z pominięciem wyjątków zawartych na liście 'exceptions'.
   * @param {string} opcjonalny parametr wskazujacy, których elementów nie brać pod uwagę w liczeniu długości
   */
  getBreadcrumbTextLength: function(){            
   var _this = this;
   var filter = arguments[0] ? ':not('+arguments[0]+')':'';
   return (function(){
     var len = 0;                                        
     _this.breadcrumb.children(filter).each(function(i){                                 
        var txt = $(this).text();        
        len += $.trim(txt).length; 
     });
     return len;
    })();
  },
  /**
   * Przygotowanie crumbów do schowania poprzez zabranie im klasy definującej widoczność i nałożenie klasy wskazujacej,<br/>
   * że element ma być przeniesiony do kryjówki i zamieniony na skrót.
   * @param {object} argument przekazywany tylko gdy metoda jest wywoływana przez samą siebie. Przechowuje obiekt krajalnicy (this)
   */
  prepareCrumbsToHide: function prepare(){
   var _this = arguments[0] || this;
   if (_this.getBreadcrumbTextLength('.dots') > _this.options.maxCharCount){
    _this.breadcrumb.find('li.BC-available').first().removeClass('BC-available')/*.clone().appendTo(_this.crumbsHideout).end().end()*/.addClass('dots');
    prepare(_this);
   };
  },
  /**
   * Metoda grupująca elementy breadcrumba. Przypisuje konkretne crumby do konkretnych kryjówek.
   */
  groupDots: function(){
   var i = 0;
   var dots = this.breadcrumb.find('.dots');
   dots.each(function(){
    $(this).addClass('dots-' + i);
    if (!$(this).next().is('.dots')) i++;
   });
   this.hideoutCount = i;
  },
  /**
   * Właściwe przeniesienie crumbów do ich kryjówek i zamiana grup na skróty do kryjówek.
   */
  hideCrumbs: function(){
   var _this = this;
   if (_this.hideoutCount > 0) {
    for (var i = 0; i < _this.hideoutCount; i++) {
     var tmpHideout = ['<ul class="BC-hideout BC-hideout-' + i + '">']; 
     _this.breadcrumb.find('.dots-' + i).each(function(){ tmpHideout.push($(this).toString()); }).first().before('<li class="BC-shortcut" rel="BC-hideout-' + i + '">' + _this.options.dots + '</li>').end().remove();
     tmpHideout.push('</ul>');
     $('body').append(tmpHideout.join(''));
     
    };
   };
  },
  /**
   * Przypisanie opcjonalnych zdarzeń do poszczególnych skrotów do kryjówek.
   */
  setEvents: function(){
   for (e in this.options.events) {
    if (this.options.events[e]) this.breadcrumb.delegate('.BC-shortcut', e, this.options.events[e]);
   }
  }
 };
 $.fn.breadCutter = function(options){
  return this.each(function(){
   new BreadCutter(this, options);
  });
 };
})(jQuery);
//-->

