/**
 * Function to get the number of Days in a year
 * @return {Integer} [description]
 */
Date.prototype.getNumberDaysInYear = function(){
    if(this.isLeapYear()){ return 365;} else { return 366;}
};

/**
 * Function to get the number of the week in the month of the Date.
 * @param  {boolean} exact [description]
 * @return {Integer}       [description]
 */
Date.prototype.getWeekOfMonth = function(exact) {
        var month = this.getMonth(),
            year = this.getFullYear(),
            firstWeekday = new Date(year, month, 1).getDay(),
            lastDateOfMonth = new Date(year, month + 1, 0).getDate(),
            offsetDate = this.getDate() + firstWeekday - 1,
            index = 1, // start index at 0 or 1, your choice
            weeksInMonth = index + Math.ceil((lastDateOfMonth + firstWeekday - 7) / 7),
            week = index + Math.floor(offsetDate / 7);
        if (exact || week < 2 + index) return week;
        return week === weeksInMonth ? index + 5 : week;
};

/**
 * Function to know if a date belongs to leap year.
 * @return {Boolean} [description]
 */
Date.prototype.isLeapYear = function() {
    var year = this.getFullYear();
    if((year & 3) !== 0) return false;
    return ((year % 100) !== 0 || (year % 400) === 0);
};

/**
 * Function to get the number of date in that year.
 * @return {Integer} [description]
 */
Date.prototype.getDOY = function() {
    var dayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
    var mn = this.getMonth();
    var dn = this.getDate();
    var dayOfYear = dayCount[mn] + dn;
    if(mn > 1 && this.isLeapYear()) dayOfYear++;
    return dayOfYear;
};



try {
	$(".monthEvents").perfectScrollbar();
}
catch(err) {
	if(console){
		console.log("Error implementing PerfectScroll on Calendar: " + err.message);
	}

}

function isElemOfCalendar(el){
    var list = el.parents();
    var elem1 = el[0].id;
    for (var i = 0; i < list.length; i++) {
        if((list[i].id === "calendarBox") || (elem1 === "calendarImgId")){
            return true;
        }
    }
    return false;
}

function removeAllModals(){
  $(".customModal").each(function () {
    $(this).remove();
  });
}

/**
 * Function to build the modals for the events description modal
 * @param id
 */
function openCalendarModal(id, fullpage){
  removeAllModals();
    for (var t = 0; t < listEventsJS.length; t++) {
    	if(listEventsJS[t].id === id){
    		var eventId = listEventsJS[t].id;
    		var eventName = listEventsJS[t].name;
    		var desc1 = decodeURI(listEventsJS[t].description);
    		desc1 = desc1.replace(/"/g, '\'');
    		if(desc1.length > 0){
    			// modal for each event
    			var modal = '<div id="myModalbyCat' + eventId +'" class="modal fade customModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"><div class="modal-header"><h3 id="myModalLabel">' + eventName + '</h3><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button></div><div class="modal-body">'+desc1+'</div></div>';
    			$('body').append(modal);
    		}
    	}
    }
	$('#myModalbyCat'+id).modal("toggle");
  if (!fullpage) {
    $('#myModalbyCat'+id).on('hidden', function () {
        toogleCalendar(false);
    });
  }

}


/**
 * Function to show/hide the calendar.
 */
function toogleCalendar(mobile) {
    // desktop
    if (!mobile) {
        if ($("#calendarBox").css('display') == "none") {
        	$(document).on('click',function (e) {
                el = $('#calendarBox');
                if (!isElemOfCalendar($(e.target))){
                	$("#calendarBox").css('display', 'none');
                    $(".calendarImg").attr('src', '/portal/o/ifap-theme/images/custom/calendar.png');
                }
            });
            $("#calendarBox").css(
                'left', (
                    $(".calendarLink img").offset().left -
                    $("#calendarBox").width() +
                    $(".calendarLink img").width() +
                    20
                ));
            $(".calendarImg").attr('src', '/portal/o/ifap-theme/images/custom/calendar_select.png');
            $("#calendarBox").css('display', 'block');
            if(isSignedIn){
                $("#calendarBox").css('left', "842.062px");
            }else{
                $("#calendarBox").css('left', "710.062px");
            }
        } else {
            $("#calendarBox").css('display', 'none');
            $(".calendarImg").attr('src', '/portal/o/ifap-theme/images/custom/calendar.png');
        }
    } else {
        // mobile
        if ($("#calendarBox").css('display') == "none") {
            var leftValue = $(".mobileCalendarIcon img").offset().left - $("#calendarBox").width() + $(".mobileCalendarIcon img").width() + 20;
            if( leftValue < 5 ){ leftValue = 5;}
            $("#calendarBox").css('left', leftValue);
            $(".calendarImg").attr('src', '/portal/o/ifap-theme/images/custom/calendar_select.png');
            $("#calendarBox").css('display', 'block');
        } else {
            $("#calendarBox").css('display', 'none');
            $(".calendarImg").attr('src', '/portal/o/ifap-theme/images/custom/calendar.png');
        }
    }
}

/**
 * Function to update the list of events on month change
 * @param  {Integer} month [Months range 0-11]
 * @param  {Integer} year  [description]
 */
function _buildEventsList(month, year){
    // if a list exists, removes it.
    $("#monthEventsUL").children().remove();
    // build of the new list.
    var ul =$("#monthEventsUL");
    for (var i = 0; i < listEventsJS.length; i++) {
    	if(year == listEventsJS[i].year && month == listEventsJS[i].month){
            var date = listEventsJS[i].day + "." + (listEventsJS[i].month+1) + "." + listEventsJS[i].year;
            var span = $("<span>");
            span.html("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
            var li1 = $("<li>", {"class": "eventDate"});
            li1.append(span);
            li1.append(date);
            ul.append(li1);
            var li2 = $("<li>", {"class": "eventName"});
            li2.html(listEventsJS[i].name);
            ul.append(li2);
            var li3 = $("<li>", {"class": "eventCat"});
            li3.html(listEventsJS[i].categoryName);
            ul.append(li3);
            var desc1 = decodeURI(listEventsJS[i].description);
            desc1 = desc1.replace(/"/g, '\'');
            if(desc.length > 0){
                var ali7 = $('<a data-target="#myModal'+ i +'" onclick="openCalendarModal(\''+ listEventsJS[i].id + '\', true)">Detalhes</a>');
                var li7 = $("<li id='eventDetails"+ i +"'>");
                li7.addClass('eventDetails');
                li7.append(ali7);
                ul.append(li7);
            } else {
                var li7a = $("<li id='eventDetails"+ i +"'>");
                li7a.addClass('eventDetails');
                ul.append(li7a);
            }
        }

    }
}

/**
 * Function to add recursive event info to the listEventsJS
 * @param  {Object} calEvent           The event object
 * @param  {String} recursiveDateDay   The day of the new date
 * @param  {String} recursiveDateMonth The month of the new date
 * @param  {String} recursiveDateYear  The Year of the new date
 * @return {void}
 */
function _buildRecursiveEventsList(calEvent, recursiveDateDay, recursiveDateMonth, recursiveDateYear){
    // if a list don't exists create it, else ignore it.
	if(!$('.mainList')){
        $(".monthEvents").children().remove();
	    $(".monthEvents").append('<ul class="mainList"></ul>');
	}
    var ul =$(".mainList");
    var date = recursiveDateDay + "." + recursiveDateMonth + "." + recursiveDateYear;
    var span = $("<span>");
    span.html("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
    var li1 = $("<li>", {"class": "eventDate"});
    li1.append(span);
    li1.append(date);
    ul.append(li1);
    var li2 = $("<li>", {"class": "eventName"});
    li2.html(calEvent.name);
    ul.append(li2);
    var li3 = $("<li>", {"class": "eventCat"});
    li3.html(calEvent.categoryName);
    ul.append(li3);
}

// variable to control the speed in which the calendar is show/hide.
var speedMenuFilter = 300;

/**
 * Function to collapse or expand the menus of the full calendar page if selected
 * in the category counter
 * @param  {String} identifierClass [the class identifies the menu to open/close]
 */
function toggleCalendarMenuCollapseSpecial(identifierClass){
    // closing everything
    $(".searchPeriodResults span").removeClass('open');
    $(".searchPeriodResults").children('ul').hide(speedMenuFilter, function() {});
    for (var y = 0; y < listOfEventsToShowFiltered.length; y++) {
        var idClass = listOfEventsToShowFiltered[y].name + "OR";
        $("." + idClass + " span").removeClass('open');
        $("." + idClass).children('ul').hide(speedMenuFilter, function() {});
    }
    toggleCalendarMenuCollapse(identifierClass);
}

/**
 * Function to collapse and expand the menus of the full calendar page
 * @param  {String} identifierClass [the class identifies the menu to open/close]
 */
function toggleCalendarMenuCollapse(identifierClass) {
    if($("." + identifierClass).children('ul').css('display') == 'none'){
        $("." + identifierClass + " span").addClass('open');
        $("." + identifierClass).children('ul').show(speedMenuFilter, function() {
        });
    } else {
        $("." + identifierClass + " span").removeClass('open');
        $("." + identifierClass).children('ul').hide(speedMenuFilter, function() {
        });
    }
}

$('#calendarBoxFullCalendar div').on('changeDate', function(event) {
    // everytime that the month is changed the
    // list of events must be updated
    event.preventDefault();
    /* Act on the event */

    var m = event.date.getMonth();
    var y = event.date.getFullYear();
    var d = event.date.getDate();
    var list = [];
    // create a list of date objects, one per day in the month.
    for (var i = 1; i < daysInMonth(m+1,y)+1; i++) {
        var el = new Date(y,m,i);
        list.push(el);
    }
    // Paint in the full calendar the days afected by the recurring events.
    setTimeout(function () {
        paintEventDay(d, m, dealWithRecurrency(list, "full"), "full");
    }, 10);
    // build the event counter.
    _buildTypeOfEventCounter(m, y);
    // build the events list.
    _buildEventsListFullCalendar(m, y);
});

/**
 * Bind of "change month" event to the full calendar.
 */
$('#calendarBoxFullCalendar div').on('changeMonth', function(event) {
    // everytime that the month is changed the
    // list of events must be updated
    event.preventDefault();
    /* Act on the event */

    var m = event.date.getMonth();
    var y = event.date.getFullYear();
    var d = event.date.getDate();
    var list = [];
    // create a list of date objects, one per day in the month.
    for (var i = 1; i < daysInMonth(m+1,y)+1; i++) {
        var el = new Date(y,m,i);
        list.push(el);
    }
    // Paint in the full calendar the days afected by the recurring events.
    setTimeout(function () {
        paintEventDay(d, m, dealWithRecurrency(list, "full"), "full");
    }, 10);
    // build the event counter.
     _buildTypeOfEventCounter(m, y);
     // build the events list.
      _buildEventsListFullCalendar(m, y);
});

/**
 * Bind of the "on show" event to the full Calendar.
 */
$('#calendarBoxFullCalendar div').on('show', function(event) {
    event.preventDefault();
    /* Act on the event */
    var today = new Date();
    var m = today.getUTCMonth();
    var y = today.getUTCFullYear();
    // build the event list and the event counter for the current date.
    _buildTypeOfEventCounter(m,y);
    _buildEventsListFullCalendar(m,y);

});

/**
 * Initialization of the full Calendar
 */
$('#calendarBoxFullCalendar div').datepicker({
    todayBtn: "linked",
    language: "pt",
    todayHighlight: false,
    immediateUpdates: true,
    //to highlight the days in which there are events
    beforeShowDay: function(date)
    {
        // create a string for further comparison.
        var dateFormat = date.getFullYear() + '/' + date.getMonth() + '/' + date.getDate();
        var str = null;
        var strName = null;
        // find matching events
        for (var i = 0; i < listEventsJS.length; i++) {
        	if ((listEventsJS[i].year == (date.getYear()+1900)) &&(listEventsJS[i].month == date.getMonth()) && (listEventsJS[i].day == date.getDate())) {
                str = listEventsJS[i].year + "/" + (listEventsJS[i].month) + "/" + listEventsJS[i].day;
                if(!strName){
                    strName = listEventsJS[i].name;
                } else {
                    strName = strName + "; " + listEventsJS[i].name;
                }

            }
        }

        // if no event is found, a recurrent one could be.
        if (!str) {
            var str2 = null;
            str2 = dealWithRecurrency([date], "full")[0];
            if(dateFormat == str2) {
                return {classes: 'highlight', tooltip: strName};
            }
        }
        if (dateFormat === str) {
            return {classes: 'highlight', tooltip: strName};
        }
    },
    templates: {
        leftArrow: '<div class="arrow-left"></div>',
        rightArrow: '<div class="arrow-right"></div>'
    }
});



/**
 * Function to build the list of categories and the event counter.
 * @param  {Integer} month [description]
 * @param  {Integer} year  [description]
 */
function _buildTypeOfEventCounter(month, year){
    var listOfEventsToShow = [];
    $(".categories").children('ul').remove();
    $(".categories").append('<ul></ul>');
    for (var i = 0; i < listEvents1JS.length; i++) {
        if(month === listEvents1JS[i].eventMonth &&
            year == listEvents1JS[i].eventYear &&
            listEvents1JS[i].name !== "")
            {
                listOfEventsToShow.push(listEvents1JS[i]);
        }
    }
    listOfEventsToShowFiltered = [];
    for (var j = 0; j < listOfEventsToShow.length; j++) {
        var duplicateFound = false;
        for (var t = 0; t < listOfEventsToShowFiltered.length; t++) {
            if(listOfEventsToShowFiltered[t].id == listOfEventsToShow[j].id){
                duplicateFound = true;
                listOfEventsToShowFiltered[t].assetCount++;
            }
        }
        if(!duplicateFound){
            listOfEventsToShow[j].assetCount = 1;
            listOfEventsToShowFiltered.push(listOfEventsToShow[j]);
        }
    }
    for (var g = 0; g < listOfEventsToShowFiltered.length; g++) {
        $(".categories ul").append('<li></li>');
        var catLabel = listOfEventsToShowFiltered[g].name;
        $(".categories ul li:last-child").append('<a></a>');
        $(".categories ul li:last-child a").attr("onclick", "toggleCalendarMenuCollapseSpecial('" + catLabel + "OR')");
        $(".categories ul li:last-child a").attr('id', listOfEventsToShowFiltered[g].id);
        $(".categories ul li:last-child a").html(listOfEventsToShowFiltered[g].name);
        $(".categories ul li:last-child").append('<span></span>');
        $(".categories ul li:last-child span").attr('class', 'customBadge');
        $(".categories ul li:last-child span").html(listOfEventsToShowFiltered[g].assetCount);
    }
}



/**
 * Function to build the menu of the results by month
 * For full list and by category
 * @param  {String} month [description]
 * @param  {String} year  [description]
 */
function _buildEventsListFullCalendar(month, year){
    // creating an array with categories list.
    var catList = ["searchPeriodResults"];
    for (var y = 0; y < listOfEventsToShowFiltered.length; y++) {
        catList.push(listOfEventsToShowFiltered[y].name);
    }
    $(".categoriesOrderedResults").children().remove();
    var li = $(".categoriesOrderedResults");
    for (var i = 1; i < catList.length; i++) {
        if (catList[i] !== "") {
            var cat = $("<li>", {"id": catList[i] + "OR"});
            cat.addClass('categoriesOrderedResults ' + catList[i] + 'OR');
            var cata = $("<a>");
            var catSpan = $("<span>", {"class": "filterCalCollapseBtn closed", "onclick": "toggleCalendarMenuCollapse('" + catList[i] + "OR')"});
            cata.html(catList[i]);
            cat.append(cata);
            cat.append(catSpan);
            li.append(cat);
        }
    }
    var catArray = $(".categoriesOrderedResults").children('li');
    for (var f = 0; f < catArray.length; f++) {
        $(".searchPeriodResults").children('ul').remove();
        $(".searchPeriodResults").append('<ul class="mainListsearchPeriodResults1"></ul>');
        var ul2 = $("<ul>", {"class": "mainListsearchPeriodResults1"});
        for (var t = 0; t < listEventsJS.length; t++) {

            if(year == listEventsJS[t].year &&
                month == listEventsJS[t].month &&
                catArray[f].id === listEventsJS[t].categoryName + "OR")
                {
                     var date1 = listEventsJS[t].day + "." + (listEventsJS[t].month+1) + "." + listEventsJS[t].year;
                     var span1 = $("<span>");
                     span1.html("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
                     var li6 = $("<li>", {"class": "eventDate", "id": f});
                     li6.append(span1);
                     li6.append(date1);
                     ul2.append(li6);
                     var li5 = $("<li>", {"class": "eventName"});
                     li5.html(listEventsJS[t].name);
                     ul2.append(li5);
                     var li4 = $("<li>", {"class": "eventCat"});
                     li4.html(listEventsJS[t].categoryName);
                     ul2.append(li4);
                     var desc1 = decodeURI(listEventsJS[t].description);
                     desc1 = desc1.replace(/"/g, '\'');
                     if(desc1.length > 0){
                         var ali8 = $('<a data-target="#myModalbyCat' + t + '"data-toggle="modal">Detalhes</a>');
                         var li8 = $("<li id='eventDetails"+ t +"'>");
                         li8.addClass('eventDetails');
                         li8.append(ali8);
                         ul2.append(li8);
                         // modal for each event
                         var modal1 = '<div id="myModalbyCat' + t +'" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"><div class="modal-header"><h3 id="myModalLabel">' + listEventsJS[t].name + '</h3><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button></div><div class="modal-body">'+desc1+'</div></div>';
                         ul2.append(modal1);
                     } else {
                         var li8a = $("<li id='eventDetails"+ t +"'>");
                         li8a.addClass('eventDetails');
                         ul2.append(li8a);
                     }
                     $("#" + catArray[f].id).append(ul2);
                     toggleCalendarMenuCollapse(catArray[f].id);
                }
        }
    }
    // Create list of all events and ordered by category.
    for (var j = 0; j < catList.length; j++) {
        if(catList[j] == "searchPeriodResults"){
            $("#searchPeriodResultsId").children('ul').remove();
            $("#searchPeriodResultsId").append('<ul id="mainListsearchPeriodResultsId" class="mainListsearchPeriodResults"></ul>');
            var ul =$("#mainListsearchPeriodResultsId");
            for (var k = 0; k < listEvents1JS.length; k++) {
                if(year === listEventsJS[k].year && month === listEventsJS[k].month){
                    var date = listEventsJS[k].day + "." + (listEventsJS[k].month+1) + "." + listEventsJS[k].year;
                    var span = $("<span>");
                    span.html("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
                    var li1 = $("<li id='eventDate"+ k +"'>");
                    li1.addClass('eventDate');
                    li1.append(span);
                    li1.append(date);
                    ul.append(li1);
                    var li2 = $("<li id='eventName"+ k +"'>");
                    li2.addClass('eventName');
                    li2.html(listEventsJS[k].name);
                    ul.append(li2);
                    var li3 = $("<li>", {"class": "eventCat"});
                    li3.html(listEventsJS[k].categoryName);
                    ul.append(li3);
                    var desc = decodeURI(listEventsJS[k].description);
                    desc = desc.replace(/"/g, '\'');
                    if(desc.length > 0){
                        var ali7 = $('<a data-target="#myModal'+ k +'" onclick="openCalendarModal(\''+ listEventsJS[k].id + '\', true)">Detalhes</a>');
                        var li7 = $("<li id='eventDetails"+ k +"'>");
                        li7.addClass('eventDetails');
                        li7.append(ali7);
                        ul.append(li7);
                    } else {
                        var li7a = $("<li id='eventDetails"+ k +"'>");
                        li7a.addClass('eventDetails');
                        ul.append(li7a);
                    }
                }
            }
        }
    }
}



/**
 * Function to add to the event list the information of recursive events
 * @param  {Object} calEvent           [Event Object]
 * @param  {Integer} recursiveDateDay   [description]
 * @param  {Integer} recursiveDateMonth [description]
 * @param  {Integer} recursiveDateYear  [description]
 */
function _buildRecursiveEventsListFullCalendar(calEvent, recursiveDateDay, recursiveDateMonth, recursiveDateYear){
    // creating the list of all categories.
    var catList = ["searchPeriodResults"];
    for (var y = 0; y < listCategoriesJS.length; y++) {
        catList.push(listCategoriesJS[y].id);
    }
    // Create list of all events and ordered by category.
    for (var j = 0; j < catList.length; j++) {
        if(catList[j] == "searchPeriodResults"){
            // if list exists remove it and create a new one.
            if ($(".searchPeriodResults")) {
                $(".searchPeriodResults").children('ul').remove();
                $(".searchPeriodResults").append('<ul class="mainListsearchPeriodResults"></ul>');
            }
            var ul =$(".mainListsearchPeriodResults");
            var date = calEvent.day + "." + (calEvent.month+1) + "." + calEvent.year;
            var span = $("<span>");
            span.html("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
            var li1 = $("<li>", {"class": "eventDate"});
            li1.append(span);
            li1.append(date);
            ul.append(li1);
            var li2 = $("<li>", {"class": "eventName"});
            li2.html(calEvent.name);
            ul.append(li2);
            var li3 = $("<li>", {"class": "eventCat"});
            li3.html(calEvent.categoryName);
            ul.append(li3);
        } else {
            // if list exists remove it and create a new one.
            if ($('.' + catList[j])) {
                $('.' + catList[j]).children('ul').remove();
                $('.' + catList[j]).append('<ul class="mainList'+catList[j]+'"></ul>');
            }
            var ul1 =$(".mainList"+catList[j]);
            if(catList[j] == calEvent.categoryId ){
                var date1 = calEvent.day + "." + (calEvent.month+1) + "." + calEvent.year;
                var span1 = $("<span>");
                span1.html("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
                var li11 = $("<li>", {"class": "eventDate"});
                li11.append(span1);
                li11.append(date1);
                ul1.append(li11);
                var li21 = $("<li>", {"class": "eventName"});
                li21.html(calEvent.name);
                ul1.append(li21);
                var li31 = $("<li>", {"class": "eventCat"});
                li31.html(calEvent.categoryName);
                ul1.append(li31);
            }
        }
    }
}



/**
 * Function to paint the days with events in both calendars.
 * @param  {Integer} d             [description]
 * @param  {Integer} m             [description]
 * @param  {array} list          [list of dates to paint in the calendar]
 * @param  {String} whichCalendar ["small" and "full"  to choose which calendar to paint]
 */
function paintEventDay(d, m, list, whichCalendar){
    // for the small calendar in the header.
    if (whichCalendar === "small") {
        // the days in the calendars don't have an id, must be added for easier identification.
        var calDays = [];
        calDays = $("#calendarBox > div.cal > div > div.datepicker-days > table > tbody > tr > td.day");
        for (var i = 1; i <= 6; i++) {
            for (var l = 1; l <= 7; l++) {
                if (!$("#calendarBox tr:nth-child("+ i +") > .day:nth-child("+ l +")").hasClass('old') &&
                !$("#calendarBox tr:nth-child("+ i +") > .day:nth-child("+ l +")").hasClass('new')) {
                    var newId = $("#calendarBox tr:nth-child("+ i +") > .day:nth-child("+ l +")").html();
                    $("#calendarBox tr:nth-child("+ i +") > .day:nth-child("+ l +")").attr('id', newId);
                }
            }
        }
        // find matching days and paint them.
        for (var k = 0; k < calDays.length; k++) {
            for (var j = 0; j < list.length; j++) {
                if(calDays[k].innerHTML == list[j].slice(list[j].lastIndexOf("/")+1)){
                    $("#calendarBox > div.cal > div > div.datepicker-days > table > tbody > tr > td#" + list[j].slice(list[j].lastIndexOf("/")+1)).addClass('highlight');

                }

            }

        }
    // similiar for the full calendar.
    } else if (whichCalendar === "full") {
        var calDays2 = [];
        calDays2 = $("#calendarBoxFullCalendar > div > div.datepicker > div.datepicker-days > table > tbody > tr > td.day");
        for (var f = 1; f <= 6; f++) {
            for (var h = 1; h <= 7; h++) {
                if (!$("#calendarBoxFullCalendar tr:nth-child("+ f +") > .day:nth-child("+ h +")").hasClass('old') &&
                !$("#calendarBoxFullCalendar tr:nth-child("+ f +") > .day:nth-child("+ h +")").hasClass('new')) {
                    var newId2 = $("#calendarBoxFullCalendar tr:nth-child("+ f +") > .day:nth-child("+ h +")").html();
                    $("#calendarBoxFullCalendar tr:nth-child("+ f +") > .day:nth-child("+ h +")").attr('id', newId2);
                }
            }
        }
        // find matching days and paint them.
        for (var k1 = 0; k1 < calDays2.length; k1++) {
            for (var j1 = 0; j1 < list.length; j1++) {
                if(calDays2[k1].innerHTML == list[j1].slice(list[j1].lastIndexOf("/")+1)){
                    $("#calendarBoxFullCalendar > div > div.datepicker > div.datepicker-days > table > tbody > tr > td#" + list[j1].slice(list[j1].lastIndexOf("/")+1)).addClass('highlight');
                }
            }
        }
    }
}

/**
 * Function to get the number of days in a month
 * @param  {Integer} month [description]
 * @param  {Integer} year  [description]
 * @return {Integer}       Number of days in the month.
 */
function daysInMonth(month,year) {
    return new Date(year, month, 0).getDate();
}

/**
 * Function to manage the recursives events.
 * @param  {array} listOfDates   List of dates of the month to analyze.
 * @param  {String} whichCalendar "small" and "full" are acepted.
 * @return {array}               Array of String with the dates to paint.
 */
function dealWithRecurrency(listOfDates, whichCalendar){
    var dateListTemp = [];
    for (var j = 0; j < listOfDates.length; j++) {
        for (var i = 0; i < listEventsJS.length; i++) {
            // if exists a matching date and its older that time the event was created.
            if (listEventsJS[i].recurrency != "null" &&
                (listOfDates[j].getTime() >
                    (new Date(listEventsJS[i].year, listEventsJS[i].month, listEventsJS[i].day)))
                ) {
                    // get that date in string form with the recursive managed.
                     var dateToAdd = _recurrency(listEventsJS[i], listOfDates[j]);
                     if(dateToAdd !== null){
                         dateListTemp.push(dateToAdd);
                         // arrange data to supply the build of the events list.
                         var y = dateToAdd.slice(0, dateToAdd.indexOf("/"));
                         var m = dateToAdd.slice(dateToAdd.indexOf("/")+1, dateToAdd.lastIndexOf("/"));
                         var d = dateToAdd.slice(dateToAdd.lastIndexOf("/")+1);
                         if (whichCalendar === "small") {
                             _buildRecursiveEventsList(listEventsJS[i], d, m, y);
                         } else if (whichCalendar === "full") {
                             //_buildRecursiveEventsListFullCalendar(listEventsJS[i], d, m, y);
                         }
                     }
             }
         }
     }
    return dateListTemp;
}

/**
 * Analysis of the recurrence given the event date and a date for comparison.
 * @param  {Object} event [description]
 * @param  {Date} date  [description]
 * @return {String}       Date in the format: "yyyy/mm/dd".
 */
function _recurrency(event, date) {
    var eventDate = null; // new recurring date of the event.
    // var eventDateDayOfWeek = null;
    var t = JSON.parse(event.recurrency)[0]; // event recurrence data.
    var frequency,      // frequency of the recurrence.
        interval,       // interval of the recurrence.
        until,          // recurrence until a specified date.
        count,          // recurrence until a specific number of ocurrences.
        byDay,          // recurrence in a specific day of the week.
        byDayStart,     // day of the week fo the recurrence.
        byWeekDayStart; // first, second, third, fourth or endless weekday.
    frequency = interval = until = count = byDay = byDayStart = byWeekDayStart = null;
    if(t.UNTIL){ until = t.UNTIL;}
    if(t.COUNT){ count = t.COUNT;}
    if(t.FREQ){ frequency = t.FREQ; }
    if(frequency == "MONTHLY"){
        if(t.INTERVAL){ interval = t.INTERVAL;}
        if(t.BYDAY){
            byDay = t.BYDAY;
            var lastWeekDayOfTheMonth = false;
            if(byDay.startsWith("-")){
                // this means that the event has to be showed
                // for week day of the month
                byWeekDayStart = byDay.substring(1, byDay.length-2);
                byDayWeek = byDay.substring(2, byDay.length);
                lastWeekDayOfTheMonth = true;
            } else {
                byWeekDayStart = byDay.substring(0, byDay.length-2);
                byDayWeek = byDay.substring(1, byDay.length);
            }
        }
        // analyse interval
        var d = event.day;
        var m = (event.month+1);
        var y = event.year;
        var calendarMonth = date.getMonth();
        var calendarYear = date.getFullYear();
        var calendarDay = date.getDate();
        var result = m;
        if(interval !== null){
            if(event.day == date.getDate()){
                var foundRecurrency = false;
                if (d == calendarDay) {
                    while(!foundRecurrency){
                        if(result ==  calendarMonth && y == calendarYear) {
                            foundRecurrency = true;
                            eventDate =  calendarYear + "/" + (result) + "/" + d;
                            // eventDateDayOfWeek = new Date(calendarYear, result, d).getDay();
                            break;
                        }
                        if(y > calendarYear && result > calendarMonth){
                            break;
                        }
                        result = m + interval;
                        while(result > 12){
                            result = result - 12;
                            y++;
                            if(result < 12){
                                foundRecurrency = true;
                                break;
                            }
                        }
                        m = result;
                    }
                }
            }
            if (byDay !== null) {
                var weekDayList = ["MO", "TU", "WE", "TH", "FR", "SA", "SU"];
                var jsMatchCode = [1,2,3,4,5,6,0];
                // must get the event week day
                var eventWeekDayNumber = jsMatchCode[weekDayList.indexOf(byDayWeek)];
                // must find calendar current week day
                var cwd = date.getDay();
    			var mList = []; // list will dates of the month
                for (var i = 1; i < daysInMonth(calendarMonth+1,calendarYear)+1; i++) {
                    var el = new Date(calendarYear,calendarMonth,i);
                    mList.push(el);
                }
                // analyse week day
                if (!lastWeekDayOfTheMonth) {
                    if (eventWeekDayNumber == cwd) {
                        if (date.getWeekOfMonth() == byWeekDayStart) {
    						eventDate = date.getFullYear() + "/" + (date.getMonth()) + "/" + date.getDate();
    					} else { eventDate = null; }
                    } else { eventDate = null; }
                } else {
    				var mListFiltered = []; // filtered list with the dates matching the weekday
                    for (var w = 0; w < mList.length; w++) {
                        if (mList[w].getWeekOfMonth(true) == eventWeekDayNumber) {
                            mListFiltered.push(mList[w]);
                        }
                    }
                    if (mListFiltered.length < eventWeekDayNumber) {
                        mListFiltered = [];
                        for (var p = 0; i < mList.length; p++) {
                            if (mList[p].getWeekOfMonth(true) == (eventWeekDayNumber-1)) {
                                mListFiltered.push(mList[p]);
                            }
                        }
                    }
                    var lastOne = mListFiltered[eventWeekDayNumber];
                    if (lastOne !== null) {
                        eventDate = lastOne.getFullYear() + "/" + (lastOne.getMonth()) + "/" + lastOne.getDate();
                    }
                }
            }
        }
    } else if (frequency === "DAILY") {
        eventDate = setDailyEventsOnCalendar(event, date, t);
    }
    // analyse COUNT
    // it only exists if interval is present
    if(count !== null){
        if( date.getMonth() >= (event.month + count) ){
            eventDate = null;
        }
    }

    // analyse UNTIL
    if(until !== null){
        if(y > date.getFullYear()){
            if(m > date.getMonth()){
                if(event.day > date.getDate()){
                    eventDate = null;
                }
            }
        }
    }
    return eventDate;
}

/**
 * Function set Daily recurrence of events.
 * @param {Object} event [description]
 * @param {Date} date  [description]
 * @param {Object} t     Recurrence date.
 */
function setDailyEventsOnCalendar(event, date, t){
    if(t.INTERVAL){ interval = t.INTERVAL;}
    // event
    var evDay = event.day;
    var evMonth = event.month;
    var evYear = event.year;
    var evDate = new Date(evYear, evMonth, evDay);
    var diff = getNumberOfDaysBetweenToDates(evDate, date) - 2;
    var eventDate = null;
    if(((diff) % interval) === 0){
        eventDate = date.getFullYear() + "/" + (date.getMonth()) + "/" + date.getDate();
    }
    return eventDate;
}

/**
 * Function to get the number of days between two dates.
 * @param  {Date} dateStart [description]
 * @param  {Date} dateEnd   [description]
 * @return {Integer}           [description]
 */
function getNumberOfDaysBetweenToDates(dateStart, dateEnd){
    // first block
    var daysInFirstBlock = dateStart.getDOY();
    // last block
    var daysInLastBlock = dateEnd.getDOY();
    // middle block(s)
    var numberOFDaysOfMiddleBlocks = 0;
    var numberOfMiddleBlocks = dateEnd.getFullYear() - dateStart.getFullYear() - 1;
    if(numberOfMiddleBlocks > 0){
        for (var i = dateStart.getFullYear() + 1; i < dateEnd.getFullYear(); i++) {
                var d = new Date(i, 1, 1);
                numberOFDaysOfMiddleBlocks += d.getNumberDaysInYear();
            }
    }
    return daysInFirstBlock + numberOFDaysOfMiddleBlocks + daysInLastBlock;
}

