"use strict";
/*
 * NMS info-window controller
 *
 * Interface: nmsInfoBox.showWindow(windowType,optionalParameter), nmsInfoBox.hide()
 *
 * Uses a basic hierarchy of window > views > panels, where each panel can work
 * independently, but gets loaded/unloaded when needed by window or view.
 *
 */
/*
 *
 * Currently broken or needs reimplementing:
 * - Possibly: Comment CRUD, did not want to test writes on our "historic db copy"
 * - Comments popover
 * - Handler unloading is not working correctly, and many are never removed
 * - SSH-management link, this should propably be a custom "view" of sorts
 * - inventoryListing window is partially broken when first opened. Since it's
 *   both a window type and a panel with different modes it has some conflicts.
 *
 * General TODO:
 * - Fix broken stuff
 * - Test comments
 * - Add external windows (timetravel, etc)
 * - Take a critical look at what methods/variables should be marked as "_"
 * - Currently argument is assumed to be a switch, this should not be the case
 * - Add some basic styling to separate panels visually when in the same view
 * - Add some movement/placement/size options to info window
 *
 */
/*
 * Basic configuration
 */
var nmsInfoBox = nmsInfoBox || {
	stats: {},
	_container: false, //Container window
	_windowHandler: false, //Window handler
	_sw: false, //Name of last switch opened, used for toggle-click
	_windowTypes: [
	{
		'id': 'switchInfo',
		'title': 'Switch info',
		'views': {
			'initial': {
				'name': 'Switch summary',
				'panels': ['switchComments','switchSummary']
			},
			'details': {
				'name': 'Switch details',
				'panels': ['switchDetails']
			},
			'ports': {
				'name': 'SNMP - Ports',
				'panels': ['switchSNMP:ports']
			},
			'misc': {
				'name': 'SNMP - Misc',
				'panels': ['switchSNMP:misc']
			},
			'comments': {
				'name': 'Comments',
				'panels': ['switchComments']
			},
			'edit': {
				'name': 'Edit',
				'panels': ['switchEdit']
			}
		}
	},
	{
		'id': 'addSwitch',
		'title': 'Add new switch',
		'views': {
			'initial': {
				'name': 'Add switch',
				'panels': ['switchAdd']
			}
		}
	},
	{
		'id': 'inventoryListing',
		'title': 'Inventory listing',
		'views': {
			'initial': {
				'name': 'Distro names',
				'panels': ['inventoryListing:distro_name']
			},
			'sysDescr': {
				'name': 'System description',
				'panels': ['inventoryListing:sysDescr']
			},
			'jnxBoxSerialNo': {
				'name': 'Serial numbers',
				'panels': ['inventoryListing:jnxBoxSerialNo']
			}
		}
	}
	],
	_panelTypes: {} //Populate by using the nmsInfoBox.addPanelType method
};
/*
 * Shows a window, and triggers initial load if needed
 */
nmsInfoBox.showWindow = function (windowName,argument) {
	if(windowName == "switchInfo" && argument != '' && argument == this._sw) {
		nmsInfoBox.hide();
		return;
	}
	if(!this._container)
		this._load();
	if(!windowName)
		windowName = 'switchInfo';
	this._sw = argument;
	this._windowHandler.showWindow(windowName,argument)
	this._container.style.display = "block";
};
/*
 * Internal function to load and register the initial html objects
 */
nmsInfoBox._load = function() {
	var infoBox = document.createElement("div");
	infoBox.classList.add("panel", "panel-default");
	var title = document.createElement("div");
	title.id = "info-box-title";
	title.classList.add("panel-heading");
	var nav = document.createElement("div");
	nav.id = "info-box-nav";
	nav.classList.add("panel-body");
	var body = document.createElement("div");
	body.id = "info-box-body";
	body.classList.add("panel-body");
	infoBox.appendChild(title);
	infoBox.appendChild(nav);
	infoBox.appendChild(body);
	this._container = document.getElementById("info-box-container");
	this._container.appendChild(infoBox);
	this._windowHandler = new windowHandler();
	this._windowHandler.setContainerObj(document.getElementById("info-box-container"));
	this._windowHandler.setTitleObj(document.getElementById("info-box-title"));
	this._windowHandler.setBodyObj(document.getElementById("info-box-body"));
	this._windowHandler.setNavObj(document.getElementById("info-box-nav"));
	this._windowHandler.setPanelTypes(this._panelTypes);
	this._windowHandler.setWindowTypes(this._windowTypes);
};
/*
 * Adds a panel type to _panelTypes for usage in windows and views
 */
nmsInfoBox.addPanelType = function (id, obj) {
	this._panelTypes[id] = obj;
};
/*
 * Hide the active window and tell it to unload
 */
nmsInfoBox.hide = function() {
	this._sw = false;
	this._windowHandler.hide();
	this._windowHandler.unloadWindow();
};
/*
 * Click a switch and display it.
 */
nmsInfoBox.click = function(sw)
{
	this.showWindow("switchInfo",sw);
};
/*
 * Window handler
 *
 * Is based on a hierarchy of objects: Window (itself) > Views > Panels. Where
 * any object should not interact with any other directly. Panels are special
 * nmsInfoPanel-objects that handle their own rendering, refreshing, etc. The
 * window handler only makes shure these panels are loaded and unloaded when
 * needed in a window or view.
 *
 * Does primarily rely on an imported list of panel types and window types to
 * display stuff, but has methods for manual overrides if needed.
 *
 * Panels can use the doInPanel(panelId,functionName,arguments) method to pass
 * actions to themselves if needed.
 *
 */
var windowHandler = function () {
	this.containerObj = false;
	this.titleObj = false;
	this.navObj = false;
	this.bodyObj = false;
	this._panels = {};
	this._view = "";
	this._window = {};
	this.windowTypes = false;
	this.panelTypes = false;
	this.argument = false;
	this.show = function () {
		this.containerObj.classList.remove("hidden");
	};
	this.hide = function () {
		this.containerObj.classList.add("hidden");
	};
	this.setContainerObj = function (containerObj) {
		this.containerObj = containerObj;
	};
	this.setTitleObj = function (titleObj) {
		this.titleObj = titleObj;
	};
	this.setNavObj = function (navObj) {
		this.navObj = navObj;
	};
	this.setBodyObj = function (bodyObj) {
		this.bodyObj = bodyObj;
	};
	this.setPanelTypes = function (panelTypes) {
		this.panelTypes = panelTypes;
	};
	this.setWindowTypes = function (windowTypes) {
		this.windowTypes = {};
		for(var i in windowTypes) {
			this.windowTypes[windowTypes[i].id] = windowTypes[i];
		}
	};
	this.setArgument = function (argument) {
		if(this.argument != argument) {
			this.argument = argument;
			this.showView(this._view);
		}
	};
	this.showPanel = function (panelName) {
		var panelArray = panelName.split(":");
		var panelName = panelArray[0];
		var panelMode = panelArray[1];
		if(this.panelTypes[panelName]) {
			var id = (Math.random().toString(36)+'00000000000000000').slice(2, 10+2);
			var panel = new this.panelTypes[panelName];
			panel.setId(id);
			if(!!panelMode)
				panel.setMode(panelMode);
			panel.load(this.bodyObj,this.argument);
			this._panels[id] = panel;
		}
	};
	this.showTitle = function (title) {
		this.titleObj.innerHTML = '× 
' + title + ' ';
	};
	this.showNav = function () {
		if(!this._window.views)
			this.navObj.innerHTML = '';
		var output = '';
		var i = 0;
		for(var view in this._window.views) {
			var viewObj = this._window.views[view];
			var active = '';
			if(this._view == view)
				active = ' class="active" ';
			output += '' + viewObj.name + '  ';
		if(i < 2) {
			this.navObj.innerHTML = '';
		} else {
			this.navObj.innerHTML = output;
		}
	};
	this.addWindow = function (windowObj) {
		this.windowTypes[windowObj.id] = windowObj;
	};
	this.showWindow = function (windowName,argument) {
		if(!this.windowTypes[windowName])
			return;
		this.unloadWindow();
		this.argument = argument;
		this._window = this.windowTypes[windowName];
		this.showTitle(this._window.title);
		this.showView();
		this.show();
	};
	this.showView = function (viewId) {
		if(!viewId || viewId == '')
			viewId = "initial";
		if(!this._window.views || !this._window.views[viewId])
			return;
		this.unloadView();
		for(var panel in this._window.views[viewId].panels) {
			this.showPanel(this._window.views[viewId].panels[panel]);
		}
		this._view = viewId;
		this.showNav();
	};
	this.removePanel = function (panelId) {
		if(!!panelId)
			this.unloadPanel(panelId);
	};
	this.unloadView = function () {
		this.unloadPanel();
	};
	this.unloadWindow = function() {
		this.hide();
		this.unloadPanel();
	};
	this.unloadPanel = function (panelId) {
		if(!panelId) {
			for(var i in this._panels) {
				this._panels[i].unload();
			}
			this._panels = {};
		} else {
			try {
				this._panels[panelId].unload();
			} catch (e) {}
			delete this._panels[panelId];
		}
	};
	//Method for triggering a function in an active panel
	this.doInPanel = function (panelId, action, argument) {
		if(!this._panels[panelId])
			return;
		if(typeof this._panels[panelId][action] === "function") {
			if(!argument) {
				this._panels[panelId][action]();
			} else {
				this._panels[panelId][action](argument);
			}
		}
	};
};
/*
 * Basic info-panel object
 *
 * Has a basic model of a stand alone panel which is intended to be extended
 * upon to implement specific panels:
 *
 * var myNewPanel = function () {
 *	nmsInfoPanel.call(this,"myNewPanelId");
 *	this.refresh = function (reason) {
 *		//My custom window function
 *		this._render(htmlObj);
 *	};
 * };
 *
 */
var nmsInfoPanel = function nmsInfoPanel(name,id) {
	this.name = name;
	this.id = id;
	this.sw = false;
	this.container = false;
	this.classList = ['info-panel'];
	this.me = false;
	this.handlers = [];
	this.mode = "initial";
	if(!this.id)
		this.id = (Math.random().toString(36)+'00000000000000000').slice(2, 10+2);
	//Method for loading the general panel properties
	this.load = function (container,argument) {
		this.container = container;
		this.sw = argument;
		this.me = document.createElement("div");
		this.me.id = this.id;
		for(var i in this.classList)
			this.me.classList.add(this.classList[i]);
		this.container.appendChild(this.me);
		this.init(argument);
	};
	//Method for making this specific panel-instance ready for first refresh
	//Override in children when any custom init-functionality is needed
	this.init = function (argument) {
		this.refresh("init");
	};
	//Methods for getting and setting panel id
	this.setId = function (id) {
		this.id = id;
	};
	this.getId = function () {
		return this.id;
	};
	//Methods for setting and getting mode (default "initial")
	this.setMode = function (mode) {
		this.mode = mode;
	};
	this.getMode = function () {
		return this.mode;
	};
	//Internal method for rendering content
	this._render = function (newContent) {
		if(!newContent || !this.me)
			return;
		this.me.innerHTML = newContent.outerHTML;
	};
	//Helper method for rendering error messages in a unified way
	this._renderError = function (message) {
		var error = document.createElement("div");
		error.className = "alert alert-info";
		error.innerHTML = message;
		this._render(error);
	};
	//Method for unloading any local data
	this.unload = function () {
		if(!this.me)
			return;
		this.me.remove();
		this.sw = false;
		this.container = false;
		this.me = false;
		this.id = false;
		this.removeHandlers();
	};
	//Method for loading new data and triggering a _render if needed
	//Implemented in children only
	this.refresh = function (reason) {};
	//Methods for adding and removing classes
	this.addClass = function (className) {
		if(this.classList.indexOf(className) == -1) {
			this.classList.push(className);
			this.me.classList.add(className);
		}
	};
	this.removeClass = function (className) {
		var index = this.classList.indexOf(className);
		if(index != -1) {
			this.classList.splice(index,1);
			this.me.classList.remove(className);
		}
	};
	//Method for registering a data handler (lets us clean them up later)
	this.addHandler = function (dataType,targetFunction) {
		if(!targetFunction)
			targetFunction = "refresh";
		nmsData.addHandler(dataType,this.id,(this[targetFunction]).bind(this),"handler-"+dataType);
		this.handlers.push(dataType);
	};
	//Method for removing all handlers we have registered
	this.removeHandlers = function () {
		for(var i in this.handlers) {
			nmsData.unregisterHandler(this.handlers[i],this.id);
		}
	};
	//Method for checking if we have handlers registered
	this.hasHandler = function (dataType) {
		for(var i in this.handlers) {
			if(this.handlers[i] == dataType)
				return true;
		}
		return false;
	};
};
/*
 * Panel type: Switch SNMP information
 *
 * Displays a list of available SNMP data from a set SNMP-group (Ex. "Ports", "Misc")
 *
 * TODO: Clean up html-generator code.
 *
 */
var switchSNMPPanel = function () {
	nmsInfoPanel.call(this,"switchSNMP");
	this.init = function() {
		this.addHandler("snmp");
		this.refresh();
	};
	this.refresh = function(reason) {
		var domObj = document.createElement("div");
		domObj.classList.add("panel-group");
		try {
			var snmpJson = nmsData.snmp.snmp[this.sw][this.mode];
		} catch(e) {
			this._renderError("Waiting for data.");
			return;
		}
		for(var obj in snmpJson) {
			var cleanObj = obj.replace(/\W+/g, "");
			var groupObj = document.createElement("div");
			groupObj.classList.add("panel","panel-default");
			groupObj.innerHTML = '' + obj + ' ';
			var groupObjCollapse = document.createElement("div");
			groupObjCollapse.id = cleanObj + "-group";
			groupObjCollapse.classList.add("collapse");
			var panelBodyObj = document.createElement("div");
			panelBodyObj.classList.add("panel-body");
			var tableObj = document.createElement("table");
			tableObj.classList.add("table","table-condensed");
			var tbody = document.createElement("tbody");
			for(var prop in snmpJson[obj]) {
				var propObj = document.createElement("tr");
				propObj.innerHTML = '' + prop + ' ' + snmpJson[obj][prop] + ' ';
				tbody.appendChild(propObj);
			}
			tableObj.appendChild(tbody);
			panelBodyObj.appendChild(tableObj);
			groupObjCollapse.appendChild(panelBodyObj);
			groupObj.appendChild(groupObjCollapse);
			domObj.appendChild(groupObj);
		}
		this._render(domObj);
	};
};
nmsInfoBox.addPanelType("switchSNMP",switchSNMPPanel);
/*
 * Panel type: Switch details
 *
 * Displays a table of switch information
 *
 */
var switchDetailsPanel = function() {
	nmsInfoPanel.call(this,"switchDetails");
	this.refresh = function(reason) {
		var swi = [];
		var swm = [];
		try {
			swi = nmsData.switches["switches"][this.sw];
		} catch(e) {}
		try {
			swm = nmsData.smanagement.switches[this.sw];
		} catch(e) {}
		var content = [];
		for (var v in swi) {
			if (v == "placement") {
				var place = JSON.stringify(swi[v]);
				content.push([v,place]);
				continue;
			}
			content.push([v, swi[v]]);
		}
		for (var v in swm) {
			content.push([v, swm[v]]);
		}
		content.sort();
		var infotable = nmsInfoBox._makeTable(content);
		this._render(infotable);
	};
};
nmsInfoBox.addPanelType("switchDetails",switchDetailsPanel);
/*
 * Panel type: Add switch
 *
 * Lets you add a new switch using the switch-add api
 *
 */
var switchAddPanel = function() {
	nmsInfoPanel.call(this,"switchAdd");
	this.refresh = function(reason) {
		var domObj = document.createElement("div");
		domObj.innerHTML = 'Add switch '
		this._render(domObj);
	};
	this.save = function () {
		var sysname = document.getElementById('create-sysname').value;
		var myData = JSON.stringify([{'sysname':sysname}]);
		$.ajax({
			type: "POST",
			url: "/api/write/switch-add",
			dataType: "text",
			data:myData,
			success: function (data, textStatus, jqXHR) {
				var result = JSON.parse(data);
				if(result.switches_addded.length > 0) { // FIXME unresolved variable switches_addded
					nmsInfoBox.hide();
				}
				nmsData.invalidate("switches");
				nmsData.invalidate("smanagement");
			}
		});
	};
};
nmsInfoBox.addPanelType("switchAdd",switchAddPanel);
/*
 * Panel type: Inventory listing
 *
 * Displays a filterable table with switch data, based on a selected mode
 *
 * TODO:
 * - Add support for multiple columns with data
 * - Add sorting
 * - Add live filtering
 * - Add export options?
 *
 */
var inventoryListingPanel = function() {
	nmsInfoPanel.call(this,"inventoryListing");
	this.filter = "";
	this.init = function (mode) {
		if(!nmsData.snmp || !nmsData.snmp.snmp) {
			if(!this.hasHandler("snmp")) {
				this.addHandler("snmp","init");
				this._renderError("Waiting for SNMP data.");
			}
			return;
		} else {
			this.removeHandlers();
			if(!!mode && this.mode == "initial")
				this.setMode(mode);
			this.refresh("init");
		}
	};
	this.setFilter = function (filter) {
		this.filter = filter;
		this.refresh();
	};
	this.refresh = function (reason) {
		var targetArray = [];
		var listTitle = '';
		var contentObj = document.createElement("div");
		var inputObj = document.createElement("div");
		inputObj.innerHTML = 'Filtrer 
';
		contentObj.appendChild(inputObj);
		switch (this.mode) {
			case 'distro_name':
				listTitle = 'Distro names';
				break;
			case 'sysDescr':
				listTitle = 'System description';
				break;
			case 'jnxBoxSerialNo':
				listTitle = 'Serial Numbers';
				break;
			default:
				listTitle = 'Distro names';
		}
		var resultArray = [];
		for(var sw in nmsData.switches.switches) {
			var value = '';
			if(this.filter != '') {
				if(sw.toLowerCase().indexOf(this.filter) == -1 && !nmsInfoBox._searchSmart(this.filter,sw))
					continue;
			}
			try {
				switch (this.mode) {
					case 'distro_name':
						value = nmsData.switches.switches[sw]["distro_name"];
						break;
					case 'sysDescr':
						value = nmsData.snmp.snmp[sw]["misc"]["sysDescr"][0];
						break;
					case 'jnxBoxSerialNo':
						value = nmsData.snmp.snmp[sw]["misc"]["jnxBoxSerialNo"][0];
						break;
				}
			} catch (e) {}
			resultArray.push([sw, value]);
		}
		resultArray.sort();
		var infotable = nmsInfoBox._makeTable(resultArray,listTitle);
		infotable.id = "inventory-table";
		contentObj.appendChild(infotable);
		this._render(contentObj);
	};
};
nmsInfoBox.addPanelType("inventoryListing",inventoryListingPanel);
/*
 * Panel type: Edit switch
 *
 * Lets you edit basic switch and switch management data through the switch-update api
 *
 */
var switchEditPanel = function () {
	nmsInfoPanel.call(this,"switchEdit");
	this.refresh = function (reason) {
		var swi = [];
		var swm = [];
		try {
			swi = nmsData.switches["switches"][this.sw];
		} catch(e) {}
		try {
			swm = nmsData.smanagement.switches[this.sw];
		} catch(e) {}
		var domObj = document.createElement("div");
		var template = {};
		nmsInfoBox._editValues = {};
		var place;
		for (var v in swi) {
			if (v == "placement") {
				place = JSON.stringify(swi[v]);
				template[v] = place;
				continue;
			}
			template[v] = nmsInfoBox._nullBlank(swi[v]);
		}
		for (var v in swm) {
			template[v] = nmsInfoBox._nullBlank(swm[v]);
		}
		var content = [];
		for (v in template) {
			var tmpsw = '\'' + this.sw + '\'';
			var tmpv = '\'' + v + '\'';
			var tmphandler = '"nmsInfoBox._editChange(' + tmpsw + ',' + tmpv + ');"';
			var html = 'Add comment 
';
		// We have data
		if(!(!nmsData.comments || !nmsData.comments.comments)) {
			this.commentsHash = nmsData.comments.hash;
			// We have data for this switch
			if(nmsData.comments.comments[this.sw]) {
				this.commentsHash = nmsData.comments.hash;
				for (var c in nmsData.comments.comments[this.sw]["comments"]) {
					var comment = nmsData.comments.comments[this.sw]["comments"][c];
					if (comment["state"] == "active" || comment["state"] == "persist" || comment["state"] == "inactive") {
						comments.push(comment);
					}
				}
				if (comments.length > 0) {
					var commenttable = nmsInfoBox._makeCommentTable(comments);
					commenttable.id = "info-switch-comments-table";
					domObj.appendChild(commenttable);
				}
			}
		}
		domObj.appendChild(commentbox);
		this._render(domObj);
	};
};
nmsInfoBox.addPanelType("switchComments",switchCommentsPanel);
/*
 * Panel type: Switch summary
 *
 * Display a live summary of key metrics
 *
 */
var switchSummaryPanel = function() {
	nmsInfoPanel.call(this,"switchSummary");
	this.init = function() {
		this.addHandler("ticker");
		this.refresh();
	};
	this.refresh = function(reason) {
		var content = [];
		//Get DHCP info
		var lastDhcp = undefined;
		try {
			var tempDhcp = nmsData.dhcp.dhcp[this.sw];
			var now = Date.now();
			now = Math.floor(now / 1000);
			tempDhcp = now - parseInt(tempDhcp);
			tempDhcp = tempDhcp + " s";
		} catch(e) {}
		//Get SNMP status
		var snmpStatus = undefined;
		try {
			if (nmsData.snmp.snmp[this.sw].misc.sysName[0] != sw) {
				snmpStatus = "Sysname mismatch";
			} else {
				snmpStatus = "OK";
			}
		} catch(e) {}
		//Get CPU usage
		var cpuUsage = undefined;
		try {
			var cpu = 0;
			for (var u in nmsData.snmp.snmp[this.sw].misc.jnxOperatingCPU) {
				var local = nmsData.snmp.snmp[this.sw].misc['jnxOperatingCPU'][u];
				cpu = Math.max(nmsData.snmp.snmp[this.sw].misc.jnxOperatingCPU[u],cpu);
			}
			cpuUsage = cpu + " %";
		} catch (e) {}
		//Get traffic data
		var uplinkTraffic = undefined;
		try {
			var speed = 0;
			var t = parseInt(nmsData.switchstate.then[this.sw].uplinks.ifHCOutOctets);
			var n = parseInt(nmsData.switchstate.switches[this.sw].uplinks.ifHCOutOctets);
			var tt = parseInt(nmsData.switchstate.then[this.sw].time);
			var nt = parseInt(nmsData.switchstate.switches[this.sw].time);
			var tdiff = nt - tt;
			var diff = n - t;
			speed = diff / tdiff;
			if(!isNaN(speed)) {
				uplinkTraffic = byteCount(speed*8,0);
			}
		} catch (e) {};
		//Get uptime data
		var uptime = "";
		try {
			uptime = nmsData.snmp.snmp[this.sw]["misc"]["sysUpTimeInstance"][""] / 60 / 60 / 100;
			uptime = Math.floor(uptime) + " t";
		} catch(e) {}
		//Get temperature data
		var temp = "";
		try {
			temp = nmsData.switchstate.switches[this.sw].temp + " °C";
		} catch(e) {}
		//Get management data
		var mgmtV4 = "";
		var mgmtV6 = "";
		var subnetV4 = "";
		var subnetV6 = "";
		try {
			mgmtV4 = nmsData.smanagement.switches[this.sw].mgmt_v4_addr;
			mgmtV6 = nmsData.smanagement.switches[this.sw].mgmt_v6_addr;
			subnetV4 = nmsData.smanagement.switches[this.sw].subnet4;
			subnetV6 = nmsData.smanagement.switches[this.sw].subnet6;
		} catch(e) {}
		//Get ping data
		var ping = undefined;
		try {
			nmsData.ping.switches[this.sw].latency + " ms";
		} catch (e) {}
		content.push(["Ping latency:",ping]);
		content.push(["Last DHCP lease:",lastDhcp]);
		content.push(["SNMP status:",snmpStatus]);
		content.push(["CPU usage:",cpuUsage]);
		content.push(["Uplink traffic:",uplinkTraffic]);
		content.push(["System uptime:",uptime]);
		content.push(["Temperature",temp]);
		content.push(["Management (v4):",mgmtV4]);
		content.push(["Management (v6):",mgmtV6]);
		content.push(["Subnet (v4):",subnetV4]);
		content.push(["Subnet (v6):",subnetV6]);
		var contentCleaned = [];
		for(var i in content) {
			if(content[i][1] == '' || content[i][1] == null)
				continue;
			if(content[i][1] == undefined || content[i][1])
				content[i][1] == "No data";
			contentCleaned.push(content[i]);
		}
		var table = nmsInfoBox._makeTable(contentCleaned);
		this._render(table);
	};
};
nmsInfoBox.addPanelType("switchSummary",switchSummaryPanel);
/*
 * General-purpose table-maker?
 *
 * Takes an array of arrays as input, and an optional caption.
 *
 * E.g.: _makeTable([["name","Kjell"],["Age","five"]], "Age list");
 */
nmsInfoBox._makeTable = function(content, caption) {
	var table = document.createElement("table");
	var tr;
	var td1;
	var td2;
	table.className = "table";
	table.classList.add("table");
	table.classList.add("table-condensed");
	if (caption != undefined) {
		var cap = document.createElement("caption");
		cap.textContent = caption;
		table.appendChild(cap);
	}
	for (var v in content) {
		tr = table.insertRow(-1);
		tr.className = content[v][0].toLowerCase();
		td1 = tr.insertCell(0);
		td2 = tr.insertCell(1);
		td1.innerHTML = content[v][0];
		td2.innerHTML = content[v][1];
	}
	return table;
};
/*
 * Create and return a table for comments.
 *
 * Input is an array of comments.
 */
nmsInfoBox._makeCommentTable = function(content) {
	var table = document.createElement("table");
	table.className = "table";
	table.classList.add("table");
	table.classList.add("table-condensed");
	var cap = document.createElement("caption");
	cap.textContent = "Comments"
	table.appendChild(cap);
	for (var commentid in content) {
		var tr;
		var td1;
		var td2;
		var comment = content[commentid];
		var col;
		if (comment["state"] == "active")
			col = "danger";
		else if (comment["state"] == "inactive")
			col = false;
		else
			col = "info";
		tr = table.insertRow(-1);
		tr.id = "commentRow" + comment["id"];
		tr.className = col;
		td1 = tr.insertCell(0);
		td1.style.whiteSpace = "nowrap";
		td1.style.width = "8em";
		td2 = tr.insertCell(1);
		var txt =  '
';
		td1.innerHTML = txt;
		td2.innerHTML = comment["comment"];
	}
	return table;
};
nmsInfoBox._searchSmart = function(id, sw) {
	try {
		try {
			if (nmsData.switches.switches[sw].distro_name.toLowerCase() == id) {
				return true;
			}
		} catch (e) {}
		try {
		if (id.match("active")) {
			var limit = id;
			limit = limit.replace("active>","");
			limit = limit.replace("active<","");
			limit = limit.replace("active=","");
			var operator = id.replace("active","")[0];
			if (limit == parseInt(limit)) {
				var ports = parseInt(nmsData.switchstate.switches[sw].ifs.ge.live);
				limit = parseInt(limit);
				if (operator == ">" ) {
					if (ports > limit) {
						return true;
					}
				} else if (operator == "<") {
					if (ports < limit) {
						return true;
					}
				} else if (operator == "=") {
					if (ports == limit) {
						return true;
					}
				}
			}
		}
		} catch (e) {}
		try {
			if (nmsData.smanagement.switches[sw].mgmt_v4_addr.match(id)) {
				return true;
			}
			if (nmsData.smanagement.switches[sw].mgmt_v6_addr.match(id)) {
				return true;
			}
		} catch (e) {}
		try {
			if (nmsData.smanagement.switches[sw].subnet4.match(id)) {
				return true;
			}
			if (nmsData.smanagement.switches[sw].subnet6.match(id)) {
				return true;
			}
		} catch (e) {}
		if (nmsData.snmp.snmp[sw].misc.sysDescr[0].toLowerCase().match(id)) {
			return true;
		}
	} catch (e) {
		return false;
	}
	return false;
};
/*
 * FIXME: Not sure this belongs here, it's really part of the "Core" ui,
 * not just the infobox.
 */
nmsInfoBox._search = function() {
	var el = document.getElementById("searchbox");
	var id = false;
	var matches = [];
	if (el) {
		id = el.value.toLowerCase();
	}
	if(id) {
		nmsMap.enableHighlights();
		for(var sw in nmsData.switches.switches) {
			if(sw.toLowerCase().indexOf(id) > -1) {
				matches.push(sw);
				nmsMap.setSwitchHighlight(sw,true);
			} else if (nmsInfoBox._searchSmart(id,sw)) {
				matches.push(sw);
				nmsMap.setSwitchHighlight(sw,true);
			} else {
				nmsMap.setSwitchHighlight(sw,false);
			}
		}
	} else {
		nmsMap.disableHighlights();
	}
	if(matches.length == 1) {
		document.getElementById("searchbox-submit").classList.add("btn-primary");
		document.getElementById("searchbox").dataset.match = matches[0];
	} else {
		document.getElementById("searchbox-submit").classList.remove("btn-primary");
		document.getElementById("searchbox").dataset.match = '';
	}
};
nmsInfoBox._searchKeyListener = function(e) {
	switch (e.keyCode) {
		case 13:
			var sw = document.getElementById("searchbox").dataset.match;
			if(sw != '') {
				nmsInfoBox.showWindow("switchInfo",sw);
			}
			break;
		case 27:
			document.getElementById("searchbox").dataset.match = '';
			document.getElementById("searchbox").value = '';
			nmsInfoBox._search();
			nmsInfoBox.hide();
			break;
	}
};
nmsInfoBox._nullBlank = function(x) {
	if (x == null || x == false || x == undefined)
		return "";
	return x;
};
nmsInfoBox._editChange = function(sw, v) {
	var el = document.getElementById("edit-" + sw + "-" + v);
	var val = el.value;
	if (v == "placement") {
		try {
			val = JSON.parse(val);
			el.parentElement.classList.remove("has-error");
			el.parentElement.classList.add("has-success");
		} catch (e) {
			el.parentElement.classList.add("has-error");
			return;
		}
	}
	nmsInfoBox._editValues[v] = val;
	el.classList.add("has-warning");
	var myData = nmsInfoBox._editStringify(sw);
	var out = document.getElementById("edit-output");
	out.value = myData;
};
nmsInfoBox._editStringify = function(sw) {
	nmsInfoBox._editValues['sysname'] = sw;
	return JSON.stringify([nmsInfoBox._editValues]);
};