const 	DOMAIN_RECORDS			= 1;
const 	ROOT_DNS				= 2;
const 	HTTP_WEBSITE			= 4;
const 	US_TM					= 8;
const 	ALEXA_DATA				= 16;
const 	PING_RESPONSE			= 32;
const 	SSL_CERTS				= 64;
const 	IP_WHOIS				= 128;
const 	AUTH_DOMAIN_RECORDS		= 256;
const 	SUB_DOMAINS				= 512;
const 	GOOGLE_INDEX			= 1024;

/////////////////////////////////////////////////////////////////////////////////////////

const 	ALLOW_VIEW_BITPOS 		= 0;
const	ALLOW_EDIT_BITPOS		= 1;
const	ALLOW_ADD_BITPOS		= 2;
const	ALLOW_DELETE_BITPOS		= 3;
const	ALLOW_LOOKUP_BITPOS		= 4;
const	ALLOW_UICHANGE_BITPOS	= 5;
const	ALLOW_DOWNLOAD_BITPOS	= 6;
const	ALLOW_CATEDIT_BITPOS	= 7;
const	ALLOW_ALLDOMAINS_BITPOS	= 8;
const	ALLOW_AQUERY_BITPOS		= 9;

/////////////////////////////////////////////////////////////////////////////////////////

const   BRWIN_REPORT_PREVIEW	= 'sed-report-preview';
const	BRWIN_HELP				= 'sedhelp';
const	BRWIN_DOMAIN_TOOLS		= 'sedtools';
const   BRWIN_APPS				= 'sedapp';

/////////////////////////////////////////////////////////////////////////////////////////


$(function()
{
	new ColorMode();
	var ui = new UserInput();
	ui.eventHandler('#license-code-box');

	if(typeof user_details != "undefined") {
		if(user_details['rights'] != 65535)
			$('.opt-admin').hide();
		if(!allow_category_edit())
			$('.opt-catedit').hide();
		if(!allow_autoquery_edit())
			$('.opt-queryedit').hide();
		if(!allow_download()) 
			$('.opt-download').hide();
	}
});


class UserInput {
	constructor(options={escape:false}) {
		if(!UserInput._instance) {
			this.init(options);
			UserInput._instance = this;
		}
		return UserInput._instance;
	}
	
	/////////////////////////////////////////////////////////////////////////////////////////
	
	init(options) {
		this.options = options;
		if(!this.options)
			this.options = {};
		if(!this.options.handlers)
			this.options.handlers = {};
		
		if(options.escape === true) {
			var instance = this;
			$(window).keydown(function(event) {
				if(!instance.escapeKey(event))
					return false;
			});
		}
		this.hideUnsupported();
	}
	
	hideUnsupported() {
		if(typeof user_details != "undefined") {
			let user_access_rights = parseInt(user_details['rights']);
			if(!bit_test(user_access_rights, ALLOW_CATEDIT_BITPOS)) {
				// Hide buttons that are not allowed for the user.
				$(".require-catedit-rights").hide();
			}
			if(!bit_test(user_access_rights, ALLOW_AQUERY_BITPOS)) {
				// Hide buttons that are not allowed for the user.
				$(".require-queryedit-rights").hide();
			}
			if(!is_an_admin_user()) {
				$(".require-admin-rights").hide();
			}
		}
	}
	
	eventHandler(elemid, bindto=null) {
		var instance = this;
		$(elemid).on('click keypress', '.event', function(event) {
			let cs = UserInput.a11yClick(event);
			if(cs == 1 || cs == 3) {
				event.preventDefault();
				var classList = $(this).attr('class').split(/\s+/);
				$.each(classList, function(index, item) {
					if(item.indexOf("event-") == 0) {
						// format: event-parameter-funcname or event-funcname
						var fnName = item.replace("event-", '');
						var pos = fnName.indexOf("-");
						if(pos > 0) {
							var paramId = fnName.substring(0, pos);
							instance.doEvent(fnName.substring(pos+1), bindto, {event:event, param:paramId});
						}
						else
							instance.doEvent(fnName, bindto, {event:event});
					}
				});
			}
		});
	}
	
	doEvent(fnName, bindto=null, param=undefined) {
		try {
			if(bindto && typeof bindto[fnName] == "function")
				return bindto[fnName](param);
			else if(typeof window[fnName] == "function")
				return window[fnName](param);
		}
		catch(err) {
			console.log('Error: '+ fnName + ': ' + err);
		}
		return false;
	}
	
	enterKeyHandler(inpdiv, trigid) {
		var instance = this;
		$("#"+inpdiv).off('keydown');
		$("#"+inpdiv).keydown(function(event)  {
			if(!instance.enterKey(event, trigid))
				return false;
		});
	}
	
	enterKey(e, submitid) {
		var keycode = (e.keyCode ? e.keyCode : (e.which ? e.which : e.charCode));
		if (keycode == 13) {
			if(submitid != "")
				$("#" + submitid).click();
			return false;
		}
		return true;
	}
	
	escapeKey(e) {
		var hidden = 0;
		var keycode = (e.keyCode ? e.keyCode : (e.which ? e.which : e.charCode));
		if (keycode == 27) {
			if(this.options && this.options.handlers && this.options.handlers.escape)
				this.options.handlers.escape();
		}
		return true;
	}
	
	setEscapeHandler(handler) {
		this.options.handlers['escape'] = handler;
	}

	escapeHandler(handler) {
		return options.handlers.escape;
	}
	
	static a11yClick(event) {
		if(event.type === 'click')
			return 3;
		else if(event.type === 'keypress') {
			var code = event.charCode || event.keyCode;
			if((code === 32)|| (code === 13))
				return code === 32 ? 2 : 1;
		}
		else
			return 0;
	}
	
	static IsIntersecting(rect01, rect02) {
		var aLeftOfB = rect01[2] < rect02[0];
		var aRightOfB = rect01[0] > rect02[2];
		var aAboveB = rect01[1] > rect02[3];
		var aBelowB = rect01[3] < rect02[1];
		return !(aLeftOfB || aRightOfB || aAboveB || aBelowB)
	}
}

function saveLicenseCode()
{
	var code = $('#license-code').val();
	if(code && code.length) {
		SEDAPI.saveLicenseCode(code);
	}
	else
		console.log('empty license code');
}

function buttonClicked(options) {
	AppModules.openLink(options.param, BRWIN_HELP);
}



/////////////////////////////////////////////////////////////////////////////////////////

function is_an_admin_user() {
	if(typeof user_details != "undefined") {
		if(user_details['rights'] == 65535) 
			return true;
	}
	return false;
}

/////////////////////////////////////////////////////////////////////////////////////////

function allow_download() {
	if(typeof user_details != "undefined") {
		var rights = user_details['rights'];
		if(rights == 65535 || (bit_test(rights, ALLOW_DOWNLOAD_BITPOS)))
			return true;
	}
	return false;
}

/////////////////////////////////////////////////////////////////////////////////////////

function allow_category_edit() {
	if(typeof user_details != "undefined") {
		var rights = user_details['rights'];
		if(rights == 65535 || (bit_test(rights, ALLOW_CATEDIT_BITPOS) && bit_test(rights, ALLOW_ALLDOMAINS_BITPOS)))
			return true;
	}
	return false;
}

/////////////////////////////////////////////////////////////////////////////////////////

function allow_category_add() {
	if(typeof user_details != "undefined") {
		var rights = user_details['rights'];
		if(rights == 65535 || (bit_test(rights, ALLOW_CATEDIT_BITPOS) && bit_test(rights, ALLOW_ALLDOMAINS_BITPOS) && bit_test(rights, ALLOW_ADD_BITPOS)))
			return true;
	}
	return false;
}

/////////////////////////////////////////////////////////////////////////////////////////

function allow_category_delete() {
	if(typeof user_details != "undefined") {
		var rights = user_details['rights'];
		if(rights == 65535 || (bit_test(rights, ALLOW_CATEDIT_BITPOS) && bit_test(rights, ALLOW_ALLDOMAINS_BITPOS) && bit_test(rights, ALLOW_DELETE_BITPOS)))
			return true;
	}
	return false;
}

/////////////////////////////////////////////////////////////////////////////////////////

function allow_autoquery_edit() {
	if(typeof user_details != "undefined") {
		var rights = user_details['rights'];
		if(rights == 65535 || (bit_test(rights, ALLOW_AQUERY_BITPOS) && bit_test(rights, ALLOW_ALLDOMAINS_BITPOS)))
			return true;
	}
	return false;
}

/////////////////////////////////////////////////////////////////////////////////////////

function allow_autoquery_add() {
	if(typeof user_details != "undefined") {
		var rights = user_details['rights'];
		if(rights == 65535 || (bit_test(rights, ALLOW_AQUERY_BITPOS) && bit_test(rights, ALLOW_ALLDOMAINS_BITPOS) && bit_test(rights, ALLOW_ADD_BITPOS)))
			return true;
	}
	return false;
}

/////////////////////////////////////////////////////////////////////////////////////////

function allow_autoquery_delete() {
	if(typeof user_details != "undefined") {
		var rights = user_details['rights'];
		if(rights == 65535 || (bit_test(rights, ALLOW_AQUERY_BITPOS) && bit_test(rights, ALLOW_ALLDOMAINS_BITPOS) && bit_test(rights, ALLOW_DELETE_BITPOS)))
			return true;
	}
	return false;
}

/////////////////////////////////////////////////////////////////////////////////////////

function bit_test(num, bit){
    return ((num>>bit) % 2 != 0)
}



(function($) {
	"use strict";

	var DefaultTooltip = function(options) {
		if(options !== undefined && typeof(options) === 'object') {
			this.$element = options.$element || null;
			if(options.options) {
				if(options.options.showalways == undefined)
					options.options.showalways = true;
				this.$options = options.options;
			}
			else
				this.$options = {showalways:true};
			if(this.isValid(this.$element) && !this.$element.data().hasOwnProperty('_instance')) {
				this.title = this.$element.attr('title');
				if(this.title !== undefined && this.title.length) {
					if(!this.title.includes('.')) // don't make hostnames uppercase
						this.title = this.title.replace(/(?:^|\s)\w/g, function(match) {return match.toUpperCase();}); // To Title Case
					this.$element.attr('title', '');
					this.$tooltip = null;
					this.set();
					this.init();
					this.$element.data('_instance', '1');
					return this;
				}
			}
			else if(this.$element.data().hasOwnProperty('_instance')) {
				console.log(this.$element.data());
			}
		}
	};

	DefaultTooltip.prototype.isValid = function (theobj) {
		return(theobj !== null && theobj !== undefined && typeof(theobj) === 'object' && theobj.jquery !== undefined );
	};

	DefaultTooltip.prototype.set = function () {
		if(!this.isValid(this.$tooltip)) {
			this.$tooltip = $('<div class="tooltip"></div>');
			this.$tooltip.html(this.title);
		}
		return this.$tooltip;
	};

	DefaultTooltip.prototype.init = function() {
		this.$element.on('mouseenter', {that: this}, this.mouseOver);
		this.$element.on('mouseleave', {that: this}, this.mouseOut);
		this.$element.attr('title', '');
	};

	DefaultTooltip.prototype.mouseOver = function (event) {
		var that = event.data.that;
		if (that.$tooltip.parent().length) {
			return event;
		}
		if(that.$options.showalways || this.offsetWidth < this.scrollWidth) {
			$('body').append(that.$tooltip);
			that.$tooltip.hide();
			that.setPos();
			that.$tooltip.show();
		}
		return event;
	};

	DefaultTooltip.prototype.mouseOut = function (event) {
		var that = event.data.that;
		if(!that.$tooltip.parent().length) {
			return event;
		}
		that.$tooltip.remove();
		return event;
	};

	DefaultTooltip.prototype.setPos = function () {

		if (!this.isValid(this.$element) || !this.isValid(this.$tooltip) ) {
			return;
		}
		var pos = this.$element.offset();
		
		pos.top += parseInt( ((this.$element.outerHeight() - this.$tooltip.outerHeight())/2), 10) ;
		pos.left += parseInt(((this.$element.outerWidth()-this.$tooltip.outerWidth())/2), 10 );

		if(pos.top <= this.$element.outerHeight()) pos.top = this.$element.outerHeight() + 10;
		if((pos.top+this.$tooltip.outerHeight()) > $(window).height()) {
			pos.top = $(window).height() - this.$tooltip.outerHeight() - 10;
		}
		if(pos.left <= 0) 
			pos.left = this.$element.outerWidth() + 10;
		if((pos.left+this.$tooltip.outerWidth()) > $(window).width()) {
			pos.left = $(window).width() - this.$tooltip.outerWidth() - this.$element.outerWidth() - 20;
		}
		if(pos.top > $(window).height()/2) {
			pos.top -= this.$tooltip.outerHeight()+10;
			if(pos.left < $(window).width()/2)
				pos.left = this.$element.offset().left;
		}
		
		var el = this.$element.offset().left;
		var et = this.$element.offset().top;
		var rect01 = [pos.left, pos.top, pos.left+this.$tooltip.outerWidth(), pos.top+this.$tooltip.outerHeight()];
		var rect02 = [el, et, el+this.$element.outerWidth(), et+this.$element.outerHeight()];
		var f = UserInput.IsIntersecting(rect01, rect02);
		if(f) {
			pos.top -= (this.$element.outerHeight() + 10);
		}
		
		// Hacks to make the tooltips show up at specific spots
		if ($('#apptoolbar').has(this.$element).length) {
			//pos.left = this.$element.offset().left + this.$element.outerWidth() + 5;
			pos.top = this.$element.offset().top + this.$element.outerHeight() + 32;
		}
		if ($('#appsidebar').has(this.$element).length) {
			pos.left = this.$element.offset().left - this.$tooltip.outerWidth() - 5;
			pos.top = this.$element.offset().top;
		}
		if ($('#controltab').has(this.$element).length) {
			pos.left = this.$element.offset().left + this.$element.outerWidth() + 8;
			pos.top = this.$element.offset().top - 2;
		}
		if ($('.controlfooter').has(this.$element).length) {
			pos.left = this.$element.offset().left;
			pos.top = this.$element.offset().top - 30;
		}
		
		this.$tooltip.css($.extend({}, {
			top: pos.top,
			left: pos.left
		}));
	};

	
	$.fn.tooltip = function(settings) {
		return this.each(function() {
			var $this =  $(this);
			if (!$this.data().hasOwnProperty('_instance'))
				new DefaultTooltip({$element: $this, options:settings});
		});
	};
})(jQuery);