ClaMenu = function (target, items, options) {
	// current object closure
	var self = this;
	var content = jQuery('#content');


	/**
	 * Toggle hide/show functions
	 */
	self.toggle = function(target) {
		if (self.window.current === target && jQuery(self.window).css('display') === 'block') {
			return self.hide();
		} else {
			return self.show(target);
		}
	};
	/**
	 * Hide the menu
	 */
	self.hide = function() {
		jQuery(self.window).hide();
		content.empty();
	};
	/**
	 * Show the menu
	 */
	self.show = function(target) {
		// var content = jQuery('#content');
		self.window.current = target;
		// clear menu
		content.empty();
		// clone content of hidden div
		var cloned = jQuery(self.block).clone(true);
		content.append(cloned);
		// Set popup position
		var coord = jQuery(target).offset();
		jQuery(self.window).css('top', coord.top + jQuery(target).height());
		jQuery(self.window).css('left', coord.left + 5);
		// Show popup
		jQuery(self.window).show();
	};
	/**
	 * Create an unordered list of items
	 */
	self.buildItems = function() {
		self.block = jQuery('<ul/>');

		for(var key = 0; key < self.items.length; key++) {
			var entry = self.items[key];
			if ((entry !== null || entry !== '') && entry !== undefined) {
				var attributes = {};
				// It's been assumed that the first and the second values are always the html text
				// and the link address.
				if (entry.length > 2) {
					for(i = 2; i < entry.length; i++) { // Walks trough all extra attributes passed.
						if (entry[i].event) { // Get the events attributes.
							attributes[entry[i].event] = entry[i].action ? entry[i].action : cla.hideMenu();
						}
						else if (entry[i].attribute) { // Get all other attributes passed.
							attributes[entry[i].attribute] = entry[i].value ? entry[i].value : '';
						}
					}
				}
				var list_item;
				if (entry.length > 0) {
					attributes['html'] = entry[0];
					attributes['href'] = entry[1];
					list_item = jQuery('<li/>').append(jQuery('<a/>', attributes));
				} else {
					list_item = jQuery('<li/>').append(jQuery('<a/>'));
				}

				self.block.append(list_item);
			}
		}
		self.checkEvents(self.block);
	};
	/**
	 * Check if onclick property present add a menu hide if it's not'
	 */
	self.checkEvents = function(target) {
		jQuery('a', target).each(function(index, el) {
			el = jQuery(el);
			var action = el.attr('onclick');
			if (action) {
				el.prop('onclick', '');
				el.click(function(e) {
					eval(action);
					e.stopPropagation();
					cla.hideMenu();
					return false;
				});
			} else {
				el.prop('onclick', 'cla.hideMenu()');
			}
		});
	};
	/**
	 * Default options
	 */
	self.options = {
		win_id : 'cla_default_menu',
		items_prototype : 'menu_items'
	};
	/**
	 * Add any options passed to default options
	 */
	if (options) {
		jQuery.extend(self.options, options);
	}

	/**
	 * If click event is anywhere except a menu item close the menu
	 */
	jQuery('html').click(function() {
		self.hide();
	});

	self.window = document.getElementById(self.options.win_id);
	self.window.current = target;
	self.item_prototype = jQuery(document.getElementById(self.options.items_prototype));
	self.items = items;
	self.buildItems();
};

////////////////////////////////////////////////////////////
// wrapping object for Claromentis core functions
var cla = {
	init : function(){
		cla.notifications.init();	// notifications
		cla.confirmation.init();	// listener for confirmation dialog's
		cla.focus.init();			// listener for page focus/blur
		cla.checkIE();
		cla.pagetop.init();
		cla.enforceFocus.init();			// Fix for select2 when used in modal windows on IE11
		cla.isTouchDevice.init();
	},

	showMenu : function(event, items, options) {
		event = jQuery.event.fix(event);
		event.preventDefault();
		event.stopPropagation();

		var $target = jQuery(event.target);

		$target.unbind('click');
		event.target.menu = new ClaMenu(event.target, items, options);
		$target.click(function(e) {
			e.preventDefault();
			e.stopPropagation();
			this.menu.toggle(e.target);
		});
		event.target.menu.toggle(event.target);
	},
	hideMenu : function() {
		var menu = new ClaMenu('', []);
		menu.hide();
		return false;
	},
	setStatus: function (message, is_error) {
		var cm = jQuery('#common_message');
		document.title = (is_error ? 'ERROR: `' : '') + message;
		if (cm.length > 0)
		{
			if (is_error)
				message = '<font color="red">' +  message + '</font>';

			cm.html(message);
		} else
		{
			if (is_error)
				cla.showMessage(message, '', true);
		}
	},
	setPageTitle: function (title)
	{
		document.title = title;
	},
	showMessage: function (title, message, is_error)
	{
		var m_class;
		if (is_error === 'info')
			m_class = 'inner-info';
		else
			m_class = is_error ? 'inner-error' : 'inner-success';

		jQuery.meow({
			'title': title,
			'message': message,
			'duration' : (m_class === 'inner-error' ? Infinity : 5000),
			'sticky' : (m_class === 'inner-error'),
			'className' : m_class
		});
	},
	stripHTML: function(html) {
		var tmp = document.createElement('div');
		tmp.innerHTML = html;
		return tmp.textContent || tmp.innerText || '';
	},
	textWidth: function(text) {
		var $tempSpan = $('<span>').css({
			position: 'absolute',
			visibility: 'hidden',
			whiteSpace: 'nowrap'
		}).text(text).appendTo('body');

		var textWidth = $tempSpan.width();

		$tempSpan.remove();

		return textWidth;
	},
    // Middle truncation helpers
    truncateMiddleTwoLines: function (filename, charsPerLine) {
        charsPerLine = charsPerLine || 20;
        var totalChars = charsPerLine * 2;

        if (filename.length <= totalChars) return filename;

        var lastDot = filename.lastIndexOf('.');
        var ext = lastDot !== -1 ? filename.slice(lastDot) : '';
        var name = filename.slice(0, lastDot !== -1 ? lastDot : filename.length);

        var available = totalChars - 1 - ext.length;
        var frontChars = Math.ceil(available * 0.7);
        var backChars = Math.floor(available * 0.3);

        return name.slice(0, frontChars) + '\u2026' + name.slice(-backChars) + ext;
    },
    getCharsPerLine: function (containerWidth, font) {
        font = font || '14px sans-serif';
        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');
        ctx.font = font;
        var avgCharWidth = ctx.measureText('abcdefghijklmnopqrstuvwxyz').width / 26;
        return Math.floor(containerWidth / avgCharWidth);
    },
    truncateFilename: function (el, filename, font) {
        // Use data-original-title as source of truth, set it once
        if (!el.getAttribute('data-original-title')) {
            el.setAttribute('data-original-title', filename);
        }

        var originalFilename = el.getAttribute('data-original-title');

        // Always reset to full filename first
        el.textContent = originalFilename;
        el.removeAttribute('title');
        el.classList.remove('filename-truncated');

        // Temporarily clamp to 2 lines to measure overflow
        var lineHeight = parseFloat(window.getComputedStyle(el).lineHeight);
        var maxHeight = lineHeight * 2;

        el.style.maxHeight = maxHeight + 'px';
        el.style.overflow = 'hidden';

        var isOverflowing = el.scrollHeight > el.clientHeight;

        el.style.maxHeight = '';
        el.style.overflow = '';

        if (isOverflowing) {
            var charsPerLine = cla.getCharsPerLine(el.offsetWidth, font);
            el.textContent = cla.truncateMiddleTwoLines(originalFilename, charsPerLine);
            el.setAttribute('title', originalFilename);
            el.classList.add('filename-truncated');
        }
    }
};

/*
 sElementId is 'id' attribut of the element to switch visibility
 sImageElementId is 'id' attribute of the image element that should switch
 between two images shows "hide/show" states
 sImgSrcToShow is a path to the image that should be taken for the 'hidden' state
 and for action 'Show'
 sImgSrcToHide is a path to the image that should be taken for the 'displayed'
 state and for action 'hide'
 */
function changeElementVisibility(sElementId, sImgElementId, sImgSrcToShow, sImgSrcToHide) {
	// Check if we have to switch image
	var img;
	var switch_image = false;
	if (sImgElementId && sImgSrcToShow && sImgSrcToHide) {
		img = jQuery('#' + sImgElementId).get(0);
		if (img) {
			switch_image = true;
		}
	}
	var el = jQuery('#' + sElementId);
	if (el.hasClass("d-none")) {
		el.removeClass("d-none");
		if (switch_image) {
			img.src = sImgSrcToHide;
		}
	} else {
		el.addClass("d-none");
		if (switch_image) {
			img.src = sImgSrcToShow;
		}
	}
	return false;
}

var JSLoaded = {};
//Create empty object

function LoadGlobalJSOnce(sJSFile, sCallFunc) {
	//Primary JSLoaded check
	if (!JSLoaded.core) {
		JSLoaded.core = {};
	}
	// Create core as its own object
	var ScriptPath = "/intranet/js/" + sJSFile + ".js";
	if (!JSLoaded.core[sJSFile]) {
		var tCallFunc = sCallFunc;
		jQuery.getScript(ScriptPath, function() {
			tCallFunc.call();
		});
	} else {
		sCallFunc.call();
	}
	JSLoaded.core[sJSFile] = true;
}

// similar to PHP function, this one can take additional parameters
function lmsg(message_key) {
	var out = '';
	if (!document.lc || document.lc[message_key] === null) {
		return message_key;
	}

	if (arguments.length > 1) {
		function localize_number(substring, number, strings) {
			var strs = strings.split('|');
			var index = lang_get_number_index(parseInt(number), document.lc['_cur_language']);
			var val = strs[index - 1];
			if (typeof val == 'undefined')
			{
				index = lang_get_number_index(parseInt(number), 'en');
				val = strs[index - 1];
			}
			if (val.indexOf('%d') === -1) {
				return number + ' ' + val;
			} else {
				return val.replace('%d', number);
			}
		}

		function lang_get_number_index(number, lang) {
			// see http://translate.sourceforge.net/wiki/l10n/pluralforms for other languages
			switch (lang) {
				// if you change this (add a new language), don't forget to do the same in localization.php
				case 'ru':
					return (number % 10 === 1 && number % 100 !== 11 ? 1 : (number % 10 >= 2 && number % 10 <= 4 && (number % 100 < 10 || number % 100 >= 20) ? 2 : 3));
				case 'cz':
					return (number === 1) ? 1 : ((number >= 2 && number <= 4) ? 2 : 3);
				case 'jp':
					return number === 0 ? 1 : 2;
				default:
					return number === 1 ? 1 : 2;
			}
		}

		var params = Array.prototype.slice.call(arguments, 1);
		if (typeof(document.lc[message_key]) === 'undefined')
		{
			console.log("Localization key " + message_key + " doesn't exist");
			out = message_key;
		} else
		{
			out = cla_sprintf_min(document.lc[message_key], params);
			if (document.lc[message_key].match(/\{%d/)) {
				out = out.replace(/\{(\d+) (.*?\|.*?)\}/g, localize_number);
			}
		}
	} else {
		out = document.lc[message_key];
	}
	return out;
}

function lmsg_key_exist(localization_key) {
	return !(typeof (localization_key) !== 'string'
		|| !document.lc
		|| document.lc[localization_key] === null
		|| typeof (document.lc[localization_key]) === 'undefined');
}

// Returns formatted string similar to sprintf, but supports only %s, %d and %%
function cla_sprintf_min(format, params) {
	var regex = /%%|%(\d+\$)?([-+#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([sid])/g;
	var i = 0;

	// finalFormat()
	var doFormat = function(substring, valueIndex, flags, minWidth, _, precision, type) {
		if (substring === '%%') {
			return '%';
		}

		// grab value using valueIndex if required?
		var value = valueIndex ? params[valueIndex.slice(0, -1)] : params[i++];

		switch (type) {
			case 's':
				return String(value);
			case 'i':
			case 'd':
				return parseInt(+value, 10);
			default:
				return substring;
		}
	};
	return format.replace(regex, doFormat);
}

(function($){
	$(document).ready(function(){
		// show nav in small devices
		$(".show_nav").click(function(){
			$("#head_nav_ul").slideToggle();
		});

		// app menu
		$("#toggle-app").click(function(){
			$(this).parent().toggleClass("active");
			return false;
		});

		// main nav clock
		setInterval("cla.ui_update_clock()", 60000 );

		// stop disabled icon default action
		$('body').on('click', '.cla-icon-disabled', function(){
			return false;
		});

		$('.label-contrast').getContrast()

		// bootstrap popover selector (live)
		$('body').popover({selector:"*[rel='popover']"});


		// initialise some start-up functions
		cla.init();

		// bootstrap tooltip selector (live)
		if ( $('html').hasClass('no-touch') ) {
			// Only enable tooltips on non-touch devices
			jQuery('body').tooltip({
				selector: "*[rel='tooltip']",
				container : 'body'
			});
		}

		// remove message and is_error_message from the address bar if possible (if history API is supported)
		cla.ui_strip_keys();

		// automated tab binding
		$("div[data-controls-tabs]").each(function(){
			cla_tabs_init($(this));
		});

		$('[data-toggle-disable="true"]').change(function(){
			toggleCheckboxDisabled(this);
		}).each(function(){
			toggleCheckboxDisabled(this);
		});

		// Sets the max size (before scrolling) for the dropdown menus in the header.
		$('.claro-navbar').find('.dropdown, .application-toggle, .autocomplete').on('click', function(){
			var menu = $(this);
				setDropdownMaxHeight(menu.find('.js-app-wrapper-list'), 180);
				setDropdownMaxHeight(menu.find('.js-search-suggestions-inner'), 180);

				var basicMenuOffset = 96;
				setDropdownMaxHeight(menu.find('.js-company-links-list'), basicMenuOffset);
				setDropdownMaxHeight(menu.find('.js-bookmarks-list'), basicMenuOffset);
				setDropdownMaxHeight(menu.find('.js-logged-on-list'), basicMenuOffset);
		})
	});


	// Textarea maxlength - Implementing support for this on browsers that don't support it
	if(!Modernizr.input.max){
		$("textarea").each(
			function(){
				if ($(this).attr("maxlength") !== "") {
					$(this).keyup(function(e){
						var msg = $(this),
							len = msg.val().length,
							maxlen = msg.attr('maxlength');

						if(len > maxlen) {
							msg.val(msg.val().substr(0,maxlen));
							e.preventDefault();
						}
					});
				}
			}
		);
	}

	//
	cla.enforceFocus = {
		init : function() {
			// Fix for dealing with focus issues when an absolutely positioned element cannot receive focus in a bootstrap modal window
			// https://github.com/twbs/bootstrap/issues/6996
			$.fn.modal.Constructor.prototype._enforceFocus = function() {
				$(document).on('focusin.modal', function(e) {
					if ($(e.target).hasClass('select2-input')) {
						return true;
					}
				});
			};
		}
	};


	/*
	 * Detect when the page has focus
	 * If cla.focus.hasFocus is true then continue your client-side process
	 *
	 */
	cla.focus = {
		init : function(){
			var that = this;
			$(window).on('focus', function(){
				// that.hasFocus = true;
				that.setFocus(true);
			}).on('blur', function(){
				// that.hasFocus = false;
				that.setFocus(false);
			});
		},

		setFocus : function(focusState){
			this.hasFocus = focusState;
		},

		hasFocus : true
	};

	/*
	 * Create a confirmation pop-up when an element is clicked
	 * add the following 2 attributes to an element to add the confirmation pop-up
	 *
	 * data-toggle="confirm":  binds a click event to the element
	 *
	 * data-confirm="":        this is the message content for the confirmation pop-up
	 *
	 */
	cla.confirmation = {
		init : function(){
			var confirm = this;
			$("[data-toggle='confirm']").each(function(){
				$(this).on('click', function(){
					confirm.doConfirm(this);
				});
			});
		},

		doConfirm : function(elem){
			var confirmation = $(elem).data( 'confirm' );
			if(!window.confirm(confirmation)) {
				return false;
			}
		}
	};

})(jQuery);


 // page top
 // searching for application menu
cla.pagetop = {
	init : function(){
		// bind search input to filter apps on key press
		jQuery('#searchApp').on('keyup', cla.pagetop.filterApps);

		// auto focus on search box
		jQuery('#appMenu').on('click', function(){
			setTimeout(function(){
				// ?? needs setTimeout otherwise it doesn't focus!
				jQuery("#searchApp").focus();
				cla.pagetop.filterReset();
			}, 0);
			cla.pagetop.keyEvent(true);
		});

		// clear search box
		jQuery('.app-wrapper-search-close').on('click', cla.pagetop.filterReset);

		// stop dropdown menu closing when clicking inside this menu
		jQuery('.app-wrapper').on('click', function(e){
			e.stopPropagation();
		})
	},

	keyEvent : function(state){
	 	if(state){
	 		jQuery('body').on('keydown', function(e){
	 			if(e.keyCode === 27) {
	 				jQuery('#appMenu').parent().removeClass('open');
	 				cla.pagetop.filterReset();
	 			}

	 			if (e.keyCode === 40 || e.keyCode === 38) {
					cla.pagetop.appSelect(e.keyCode);
					e.preventDefault();
				}
				if (e.keyCode === 13) {
					var term = jQuery('#searchApp').val();
					if (term.length > 0)
					{
						var first_found = jQuery('#applications').find('li:visible');
						if (first_found.length === 1)
						{
							var url = first_found.find('a').prop('href');
							if (url !== undefined){
								window.location.href = url;

								//open in new window
								// var redirectWindow = window.open(url);
								// redirectWindow.location;
							}
						}

					}
				}
			});
	 	} else {
	 		jQuery('body').unbind('keydown');
	 	}
	},

	appSelect : function(keycode){
		var prev = keycode === 38,
			appList = jQuery('.app-wrapper-list').find('li:visible'),
			currApp = appList.find('a:focus').parent(),
			item = currApp.nextAll(':visible').first().length === 0,
			currLink = currApp.nextAll(':visible');

		// if previous (up arrow), change our selectors to cycle up the list
		if( prev ) {
			item = currApp.prevAll(':visible').first().length === 0;
			currLink = currApp.prevAll(':visible');
		}

		// if focus is on search, goto the first or last visible app in the list
		if( jQuery('#searchApp:focus').length !== 0 ) {
			var nextApp = prev ? appList.last() : appList.first();
			nextApp.find('a').focus();
			return;
		}

		// if there are no next/prev apps cycle back to the search box
		if( item ){
			jQuery('#searchApp').focus();
			return;
		}

		currLink.first().find('a').focus();
	},

	filterReset : function(){
		jQuery('#searchApp').val('').focus();
		cla.pagetop.filterApps();
		return false;
	},

	filterApps : function(){
		var term = jQuery('#searchApp').val();

		if (term.length == 0)
		{
			jQuery('#applications').find('li').toggleClass('d-none', false);
		}
		else
		{
			jQuery('#applications').find('li').each(function(){
				var check = jQuery(this).find('a:Contains("' + term + '")').length === 0;
				jQuery(this).toggleClass('d-none', check);
			});
		}
		if(jQuery('html').hasClass('ie9')) {
			jQuery(".app-wrapper").css('zoom', 0).css('zoom', 1);
		}
	}
};

// check for touch devices
cla.isTouchDevice = {
	init : function(){
		var touchClass = 'no-touch';

		if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
			touchClass = 'touch-enabled';
		}

		jQuery('html').addClass(touchClass);
	}
}

// notifications panel in navbar
cla.notifications = {
	template: null,
	mouse_is_in: false,
	unread_count: 0,
	firstListLoad: true,

	close: function(){
		jQuery('body').unbind('click', cla.notifications.closeOnClickOutside);
		jQuery('#notifications').removeClass('open');
		jQuery('.js-unread-marker').removeClass('marker-fade');

	},

	show : function(){
		var list_el = jQuery('#notificationWrapper');

		jQuery.post('/intranet/communication/im_ajax_handler.php', {'get': 1}, function (data) {
			if (cla.notifications.template === null) {
				cla.notifications.template = _.template(jQuery('#notification_template').html());
			}

			list_el.empty();

			var messages = data.messages;
			var notification_html
			//append messages to notification template
			if (messages.length!==0) {
				jQuery.each(messages, function (idx, el) {
					el.isLastItem = idx === (messages.length - 1);
					notification_html = cla.notifications.template(el);
					list_el.append(notification_html);
				});
			} else {
				cla.notifications.template_no_messages = _.template(jQuery('#notification_template_no_messages').html());
				list_el.append(cla.notifications.template_no_messages);
			}

			//fade in unread marker if it's the first load of the notification list
			if (cla.notifications.firstListLoad){
				jQuery('.js-unread-marker').addClass('marker-fade');
				cla.notifications.firstListLoad = false;
			}

			cla.notifications.setNewCount(data.unread);
		}, 'json');

		jQuery('.dropdown.open').removeClass('open');
		jQuery('#notifications, .dropdown.open').toggleClass('open', true);
		cla.notifications.resize();
		cla.notifications.mouse_is_in = true;

		// close notification list when clicking outside the container
		jQuery('body').bind('click', cla.notifications.closeOnClickOutside);
	},

	resize : function(){
		// Sets the max size (before scrolling) for the dropdown menus.
		setDropdownMaxHeight('#notificationWrapper', 140);
	},

	markAsRead : function(el, updateCount){
		var msgid = jQuery(el).data('messageid');

		if (msgid) {
			jQuery.post('/intranet/communication/im_ajax_handler.php', {read: msgid}, function (result) {
				el.removeClass('notification-unread');

				if (updateCount)
					cla.notifications.setNewCount(cla.notifications.unread_count - 1);
			});
		}
	},

	markAllAsRead : function(){
		var messages = jQuery("#notification_list").find(".notification-unread");

		// Get messages and their ids (to be marked as read)
		var messagesToMarkAsRead = [];
		var messagesToMarkAsReadIds = [];
		if (messages) {
			messages.each(function () {
				if (jQuery(this).data('messageid')) {
					messagesToMarkAsRead.push(jQuery(this));
					messagesToMarkAsReadIds.push(jQuery(this).data('messageid'));
				}
			});

			jQuery.post('/intranet/communication/im_ajax_handler.php', {read: messagesToMarkAsReadIds}, function (result) {

				jQuery(messagesToMarkAsRead).each(function () {
					jQuery(this).removeClass('notification-unread');
				});

				var newCount = (cla.notifications.unread_count - messages.length);
				newCount = newCount >= 0 ? newCount : 0;

				cla.notifications.setNewCount(newCount);
				cla.notifications.checkNewNotifications();
				cla.notifications.close();
				cla.notifications.show();
			});
		}
	},

	init : function(){
		// track mouse position for the notification list
		jQuery('#notification_list, #msg, #notifications').mouseenter(function(){
			cla.notifications.mouse_is_in = true;
		}).mouseleave(function(){
			cla.notifications.mouse_is_in = false;
		});

		// toggle notification list
		jQuery('.notification-toggle').click(function(event){
			if (cla.notifications.isListOpen()) {
				cla.notifications.close();
			} else {
				cla.notifications.show();
			}
		});

		// mark all as read
		jQuery("#notification_list").find(".markAllAsRead").click(function(){
			cla.notifications.markAllAsRead();
			return false;
		});

		// delete notification
		jQuery('#notification_list').on('click', '.js-notification-delete', function (event) {
			var el = jQuery(event.currentTarget).parents('[data-messageid]');
			var msgid = el.data('messageid');
			if (msgid) {
				jQuery.post('/intranet/communication/im_ajax_handler.php', {'del': msgid}, function (result) {
					el.remove();
				});
			}
			return false;
		});

		// close sibling notifications that are open
		jQuery('#notification_list').on('click', '.js-details', function (event) {
			var el = jQuery(event.currentTarget).parents('.notification');

			if (el.hasClass('active_notification')) {
				jQuery('.notification-text', el).collapse('hide');
				el.removeClass('active_notification');
			} else {
				jQuery('.notification-text', el).collapse('show');
				el.addClass('active_notification')
					.siblings()
					.removeClass('active_notification')
					.find('.collapse.in')
					.collapse('hide');

				if (el.hasClass('notification-unread')) {
					cla.notifications.markAsRead(el,true);
				}
			}

			return false;
		});
	},

	isListOpen : function ()
	{
		return jQuery('#notifications').hasClass('open');
	},

	closeOnClickOutside: function () {
		if (!cla.notifications.mouse_is_in) {
			cla.notifications.close();
		}
	},

	setNewCount: function (count) {
		var obj = jQuery('.js-notify-count'); //actually two objects
		var msg;
		obj.text(count);

		if (count <= 0) {
			msg = lmsg("infobar.notifications.no_message");

			// Hide if 0
			obj.hide(0, function(){
				jQuery(this).remove('notify-important');
			});
		} else {
			msg = lmsg("infobar.notifications.new_messages", count);

			// Show indication that it has changed
			if (cla.notifications.unread_count != count)
			{
				obj.removeClass('notify-important').hide();
				//make sure it is displayed
				obj.show(0, function(){
					jQuery(this).addClass('notify-important').show();
				});

			}
		}

		cla.notifications.unread_count = count;
		if (count > 0)
			jQuery('#notificationMarkAsRead').show();
		else
			jQuery('#notificationMarkAsRead').hide();
		// Set the tooltip
		jQuery('#infobar_new_imessage_icon').attr('data-original-title', msg);
		// Set the aria label
		jQuery('#infobar_new_imessage_icon').attr('aria-label', msg);
		jQuery('#infobar_new_imessage_mobile_icon').attr('aria-label', msg);
	},


	// IM background check, moved from im_check.html
	IM_check_period: 30,
	IM_check_show_mode: 1,
	IM_user_id: 0,
	IM_prev_request: null,

	checkNewNotifications: function() {
		if (cla.focus.hasFocus) {
			if(cla.notifications.IM_prev_request !== null)
				cla.notifications.IM_prev_request.abort();
			var url = "/intranet/communication/im_ajax_handler.php?uid=" + cla.notifications.IM_user_id + "&"+Math.random();
			cla.notifications.IM_prev_request = jQuery.get(url, null, function (result, status, xhr) {
				if (status === 'success' && result) {
					cla.notifications.setNewCount(result.unread);
				}
				cla.notifications.IM_prev_request = null;
			}, 'json');
		}
	},

	startChecking: function ()
	{
		cla.notifications.checkNewNotifications();
		setTimeout(cla.notifications.startChecking, cla.notifications.IM_check_period * 1000);
	},

	bgCheckInit: function (IM_check_period, IM_check_show_mode, IM_user_id)
	{
		cla.notifications.IM_check_period = IM_check_period;
		cla.notifications.IM_check_show_mode = IM_check_show_mode;
		cla.notifications.IM_user_id = IM_user_id;
		cla.notifications.startChecking();
	}
};

cla.checkIE  = function () {
	var ie = cla.detectIE();

	if(ie) {
		if(ie <= 8) {
			jQuery('html').addClass('ie-old');
		}
		jQuery('html').addClass('ie');
	}
	return ie;
}

cla.detectIE  = function () {
	var ua = window.navigator.userAgent;
	var msie = ua.indexOf('MSIE ');

	if (msie > 0) {
		// IE 10 or older => return version number
		return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
	}

	var trident = ua.indexOf('Trident/');
	if (trident > 0) {
		// IE 11 => return version number
		var rv = ua.indexOf('rv:');
		return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
	}

	// other browser
	return false;
};

cla.CList = {
	load: function (the_list, full_url, callback) {
			var params = {
				'data': the_list.attr('data-data')
			};

			if (params.data && full_url) {
				params.href = full_url.split('?', 2)[1];

				jQuery.post('/intranet/common/common_list_server.php', params, function (data) {
					// The new data will contain paging markup so remove the existing one in case it is outside the list
					$('.CommonListAjaxPaging').remove();
					the_list.replaceWith(data);

					if (callback)
						callback(the_list, full_url);
				});
			}
		},

	click: function (event) {
			var the_link = jQuery(event.currentTarget);
			var the_list = the_link.parents('.CommonListAjaxWrapper');

			// If the list is not a direct parent, try to find it as a sibling to the pagination wrapper (as in common_list_inc.html)
			if (the_list.length === 0)
				var the_list = the_link.closest('.js_common_list_pagination_wrapper').siblings('.CommonListAjaxWrapper');

			var full_url = the_link.prop('href');
			if (the_list.attr('data-data') && full_url)
			{
				event.preventDefault();
				cla.CList.load(the_list, full_url, cla.CList.history_push);
			}
		},

	history_push: function (the_list, full_url) {
			if (Modernizr.history)
			{
				history.replaceState(the_list.attr('id'), null, location.href);
				history.pushState(the_list.attr('id'), null, full_url);
			}
		},

	history_pop: function(e) {
			if (typeof e.state === 'string')
			{
				var the_list = jq_$(e.state);
				if (the_list.hasClass('CommonListAjaxWrapper'))
					cla.CList.load(the_list, location.href);
			}
		},

	init: function () {
		jQuery(document).on('click', '.CommonListAjaxPaging a',null, cla.CList.click)
			.on('click', 'a.CommonListAjaxHeader', null, cla.CList.click);

		window.setTimeout(function() {
			if(window.attachEvent) {
				window.attachEvent("popstate", cla.CList.history_pop, false);
			} else {
				window.addEventListener("popstate", cla.CList.history_pop, false);
			}
		}, 1);
	}
};

cla.GREPicker = {
	Init: function (type, element_id, query_params, placeholder, allow_unset) {
			var el = jq_$(element_id);
			el.select2({
				placeholder: placeholder,
				allowClear: allow_unset,
				width: '100%',
				ajax: {
					url: "/intranet/common/gre_picker_server.php?"+query_params,
					dataType: 'json',
					delay: 250,
					data: function (params) {
						params.page = params.page || 0;
						return {
							kw: params.term, // search term
							type: type,
							page: params.page
						};
					},
					processResults: function (results) {
						return {
							results: results.data,
							pagination: {
								more: results.more
							}
						};
					}
				}
			});
		}
};

// clock -
cla.ui_update_clock = function() {

	var dataTime = jQuery('#navClock').attr('data-time'),
		dataFormat = jQuery('#navClock').attr('data-format');

	if (dataFormat !== undefined)
	{
		var stored_time = parse_time(dataTime);
		stored_time.minutes ++;
		if (stored_time.minutes === 60 && stored_time.hours === 23)
		{
			jQuery('#navClock').attr('title', '').attr('data-original-title', '');
		}

		jQuery("#navClock").attr("data-time",
			format_time_string(stored_time, "H:i")
		);

		jQuery('#navClockTime').text(
			format_time_string(stored_time, dataFormat)
		);
	}

	function parse_time(time)
	{
		var currentTime = time.split(":");
		return {hours: currentTime[0], minutes: currentTime[1]};
	}
};

cla.ui_strip_keys = function() {
	if (!Modernizr.history)
		return;

	var new_url = location.href;
	var keysToStrip = ["message", "is_error_message", "from_search", "from_list"];
	var queryParams=[];
	var anchor = "";

	if(new_url.indexOf('#') > -1) {
		fragments = new_url.split('#');
		new_url = fragments[0];
		anchor = fragments[1];
	}

	if(new_url.indexOf('?') > -1) {
		var fragments = new_url.split('?');
		new_url = fragments[0];
		queryParams = fragments[1].split('&').map(function(elem){
			return elem.split('=');
		});
	}

	//strip out excluded keys
	queryParams = queryParams.filter(function(param){
		return keysToStrip.indexOf(param[0]) === -1;
	});

	//re-construct query string
	queryString = queryParams.map(function(elem){
		return elem[0] + "=" + elem[1];
	}).join('&');

	if(queryString !== "")
		new_url += '?' + queryString;

	//add the anchor back on, if there was one
	if(anchor !== "")
		new_url += "#" + anchor;

	//if the url actually changed as a result of this, overwrite it in the history
	if (location.href !== new_url)
	{
		history.replaceState(history.state, null, new_url);
	}
};


// takes time object {hours: NN, minutes: NN} and formats it
function format_time_string(time, format) {
	// set defaults
	var replaceHours = "h"; // 12 hour clock
	var	hours = time.hours,
		minutes = time.minutes;

	// check for the hourly increment
	if (minutes >= 60) {
		// reset minutes and increment the hour
		minutes = 0;
		hours++;
	}
	if (hours >= 24)
		hours = 0;

	var suffix = (hours >= 12) ? "pm" : 'am';

	var hours12 = hours % 12;
	if (hours12 === 0) hours12 = 12;

	return format.
		replace("A", suffix.toUpperCase()).
		replace("a", suffix.toLowerCase()).
		replace('H', pad(hours, 2)).
		replace('h', pad(hours12, 2)).
		replace('G', hours).
		replace('g', hours12).
		replace("i", pad(minutes, 2));

	// padding zero's function
	function pad(number, length) {
		var str = '' + number;
		while (str.length < length) {
			str = '0' + str;
		}
		return str;
	}
}


// special symbols safe loading of jQuery-wrapped DOM object by ID. jQuery('#' +
// id) is unsafe as 'id' needs to be escaped
function jq_$(id) {
	return jQuery(document.getElementById(id));
}

// Init jQuery UI tabs. With support for "open all" and hash in URL
function cla_tabs_init(selector, options) {
	var cur_tab = window.location.hash.substring(2);

	if (cur_tab == 'all') {
		cur_tab = '';
		var all_active = true;
	}

	var all_element = jQuery(selector).find('ul li a[href="#all"]');
	if (all_element.size() > 0) {
		jQuery(selector).append('<div id="all" class="d-none"></div>');
	}

	if (options === undefined) {
		options = {};
	}

	if ( typeof options.show_override === 'function') {
		options.activate = options.show_override;
	} else {
		var orig_show_function = function() {};
		var orig_beforeActivate_function = function() {};
		if ( typeof options.activate === 'function') {
			orig_show_function = options.activate;
		}
		if ( typeof options.beforeActivate === 'function') {
			orig_beforeActivate_function = options.beforeActivate;
		}
		options.activate = function(event, ui) {
			window.location.hash = '_' + ui.newPanel.prop('id');
			if (ui.newPanel.prop('id') === 'all') {
				selector.find(".ui-tabs-panel").show().addClass('show').attr('aria-expanded', true).attr('aria-hidden', false);
				//jQuery(selector + " .ui-tabs-hide").removeClass("ui-tabs-hide");
			} else {
				orig_show_function(event, ui);
			}
		};

		options.beforeActivate = function(event, ui) {
			if (ui.oldPanel.prop('id') === 'all') {

				selector.find(".ui-tabs-panel").hide().attr('aria-expanded', false).attr('aria-hidden', true);
			}
			orig_beforeActivate_function(event, ui);
		};
	}

	if (cur_tab.length > 0) {
		var tabs_elements = jQuery('ul li a', selector);
		var cur_element_idx = tabs_elements.index(jQuery('ul li a[href="#' + cur_tab + '"]', selector));
		if (cur_element_idx > 0)
			options.active = cur_element_idx;
	}

	if (typeof jQuery.fn.__tabs == 'undefined') {
		jQuery.fn.__tabs = function (a, b, c, d, e, f) {
			// Strip message must happen before we generate new hrefs or the tabs will have different base URLs
			// from the current page and the anchors will cause a bad reload loop inside the tab panel.
			cla.ui_strip_keys();

			if (jQuery('base').length > 0) {
				var base = location.href.replace(/#.*$/, '');
				jQuery('ul>li>a[href^="#"]', this).each(function () {
					var href = jQuery(this).attr('href');
					jQuery(this).attr('href', base + href);
				});
			}

			jQuery(this).tabs(a, b, c, d, e, f);
		};
	}


	jQuery(selector).__tabs(options);

	// switch to all tab once the tab are loaded.
	if (all_element.size() > 0 && all_active) {
		jQuery(all_element).click();
	}

	/**
	 * BT-5140, BT-4308
	 *
	 * The commented out code below is a change that added 'sticky' behaviour
	 * for tabs across multiple page loads. Unfortunately it's buggy, using only a single
	 * local storage variable for any set of tabs in multiple places across the site, and
	 * does this automatically anywhere we use tabs with seemingly no way to turn it
	 * off when we need to, such as for viewing infocapture tickets, which should
	 * always default to the main ticket view tab and not remember which tab was
	 * active on some other ticket.
	 *
	 * The code has been commented out rather than deleting so it can be referred to
	 * in future if we want to implement this correctly. For now, we're rolling it back.
	 * (Tez)
	 */
    //Retain correct navigation tab pill on page reload
    // jQuery('a[data-toggle="pill"]').on('show.bs.tab', function(e) {
    //     localStorage.setItem('activeTab', jQuery(e.target).attr('href'));
    // })
    // var activeTab = localStorage.getItem('activeTab');
	//
    // if(activeTab && jQuery(selector).find('a[href="' + activeTab + '"]').length > 0 ) {
    //     jQuery(selector).find('a[href="' + activeTab + '"]').tab('show');
    //     jQuery(selector).find(activeTab).attr('aria-hidden', 'false').show();
    // }
}

// new Contains method for case insensitive searching
/**
 * @return {boolean}
 */
jQuery.expr[':'].Contains = function(a, i, m) {
	return jQuery(a).text().toUpperCase()
		.indexOf(m[3].toUpperCase()) >= 0;
};

// Disables (toggle) the given elements.
function toggleCheckboxDisabled(elem){
	var target = jQuery(elem).data('toggle-target'),
		isChecked = jQuery(elem).prop('checked');
	jQuery(target).prop("disabled", !isChecked);
}

/**
 * Sets the max height of a dropdown menu based on the page height
 * @param targetMenu - target dropdown menu to set max height on.
 */
 function setDropdownMaxHeight(targetMenu, bottomOffset){
	 var menu = jQuery(targetMenu);
	 var dropdownBottomHeight = bottomOffset;
	 var maxWindowSize = 767;

	 // Checks that the window is above the max window size and applies the dropdown height limit if true
	 if (menu.length && window.innerWidth > maxWindowSize) {
		 var windowHeight = window.innerHeight;

		 // calculates the height of the dropdown as the window height minus the offset
		 var maxHeight = windowHeight - dropdownBottomHeight;

		 menu.css({'max-height' : maxHeight}).addClass('overflow-auto');

	 }
 }

cla.colours = {

    getColourContrast: function (hexcolor) {

        // WCAG luminance crossover point
        // Above this -> black text contrasts better
        var threshold = 0.179;

        var thresholdcolors = ['#ffffff', '#000000'];

        return cla.colours.getColorByThreshold(
            hexcolor,
            threshold,
            thresholdcolors
        );
    },

    getContrastYIQ: function (hexcolor){
        return cla.colours.getColourContrast(hexcolor);
    },

    getColorByThreshold: function (
        hexcolor,
        threshold,
        thresholdcolors
    ) {

        // convert rgb() -> hex if needed
        hexcolor = cla.colours.rgb2hex(hexcolor);

        var rgb = cla.colours.hex2rgb(hexcolor);

        if (!rgb) {
            return thresholdcolors[1];
        }

        var luminance = cla.colours.relativeLuminance(
            rgb.r,
            rgb.g,
            rgb.b
        );

        // Below threshold:
        // use light text
        return (luminance < threshold)
            ? thresholdcolors[0]
            : thresholdcolors[1];
    },

    relativeLuminance: function (r, g, b) {

        return (
            0.2126 * cla.colours.inverseGamma(r) +
            0.7152 * cla.colours.inverseGamma(g) +
            0.0722 * cla.colours.inverseGamma(b)
        );
    },

    inverseGamma: function (value) {

        value = value / 255;

        if (value <= 0.04045) {
            return value / 12.92;
        }

        return Math.pow((value + 0.055) / 1.055, 2.4);
    },

    hex2rgb: function (hex) {

        if (!hex) {
            return null;
        }

        hex = hex.replace('#', '');

        // Expand shorthand (#abc -> #aabbcc)
        if (hex.length === 3) {

            hex =
                hex.charAt(0) + hex.charAt(0) +
                hex.charAt(1) + hex.charAt(1) +
                hex.charAt(2) + hex.charAt(2);
        }

        if (hex.length !== 6) {
            return null;
        }

        return {
            r: parseInt(hex.substr(0, 2), 16),
            g: parseInt(hex.substr(2, 2), 16),
            b: parseInt(hex.substr(4, 2), 16)
        };
    },

    rgb2hex: function (colour) {

        var rgb = colour.match(
            /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/
        );

        if (rgb) {

            function hex(x) {
                return (
                    "0" + parseInt(x, 10).toString(16)
                ).slice(-2);
            }

            return (
                "#" +
                hex(rgb[1]) +
                hex(rgb[2]) +
                hex(rgb[3])
            );
        }

        return colour;
    }
};

jQuery.fn.extend({
	getContrast: function() {
		var labels = jQuery(this);

		if (labels) {
			labels.each(function(){
				var colour = jQuery(this).css('background-color');
				jQuery(this).attr("style", jQuery(this).attr('style') + '; ' + "color: " + cla.colours.getColourContrast(colour) + " !important" );
			})
		}
	},

	// get the offset width of an element whose parent is hidden
	getHiddenOffsetWidth: function () {
		// save a reference to a cloned element that can be measured
		var $hiddenElement = $(this).clone().appendTo('body');

		// calculate the width of the clone
		var width = $hiddenElement.outerWidth() || 0;

		// remove the clone from the DOM
		$hiddenElement.remove();

		return width;
	}

});

// adds backdrop styling to top level modal when there are nested modals
jQuery(function ($) {
	$(document).on('show.bs.modal', '.modal', function () {
		var openModals = $('.modal.show');

		if (openModals.length >= 1) {
			$(this).addClass("modal-dialog-backdrop");
		}
	});

	$(document).on('hidden.bs.modal', '.modal', function () {
		$(this).removeClass("modal-dialog-backdrop");
	});
});
