/** 
 * scanning result schema (JSON format)
 * {category, issue, item[{name, type, status, version, secureVersion, secuniaID, msKB, files, vendor, fieDateTime, solution, icon}]}
 */

function Result(properties) {
	this.properties = properties;
	this.windows = null;
	this.security = null;
	this.browse = null;
	this.email = null;
	this.chat = null;
	this.multimedia = null;
	this.generalDocument = null;
	this.other = null;
	this.html = "";
	this.expandedCard = "";
	this.expandedItem = "";
	this.totalRedIssue = new Number(0);
	this.totalOrangeIssue = new Number(0);
	this.expandedCardOnMouseOver = null;
	this.expandedCardOnMouseOut = null;
	this.expandedSafeItemBar = null;
	this.isAllFirewallOff = true;
	this.problemFirewallCount = 0;
	this.vulnerability = null;
}

Result.prototype = {

  feed: function(categories) {
    var category = categories.split(";");
    for (var i = 0; i < category.length; i++) {
      if (category[i].length > 2) {
        this.register('('  +  category[i] + ')');
      }
    }
    
    this.vulnerability = new Vulnerability();
  }
  ,
	/** 
	 * Register each categories into the class
	 * 
	 * @param {string} result scanning result category in the format of the
	 * <code>result schema</code>
	 */
	register: function(result) {
	  result = eval(result);
		switch (parseInt(result.category)) {
      case CATEGORY_WINDOWS:
				this.windows = result;
				break;
			case CATEGORY_SECURITY:
				this.security = result;
				break;
			case CATEGORY_BROWSE:
				this.browse = result;
				break;
			case CATEGORY_EMAIL:
				this.email = result;
				break;
			case CATEGORY_CHAT:
				this.chat = result;
				break;
			case CATEGORY_DOCUMENT:
				this.generalDocument = result;
				break;
			case CATEGORY_OTHER:
				this.other = result;
				break;
		}
	}
	,
	
	/** 
	 * Write out the generated HTML result
	 * 
	 */
	write: function() {
    if (this.security != null)
		  this._constructTitle(this.security);
	  if (this.windows != null)
	   this._constructTitle(this.windows);
		if (this.browse != null)
		  this._constructTitle(this.browse);
		if (this.email != null)
		  this._constructTitle(this.email);
		if (this.chat != null)
		  this._constructTitle(this.chat);
		if (this.generalDocument != null)
	   this._constructTitle(this.generalDocument);
	  if (this.other != null)
		  this._constructTitle(this.other);
		  
		return this.html;
	}
	,
	
	_getSecurityTitle: function(category) {
		if (CATEGORY_SECURITY != category.category)
			return 1;
		
		var firewallCount = 0;
		var isWindowFirewallAvailable = 0;
		var isWindowFirewallOn = 0;
		var windowFirewallLocation = 0;
		var isAtLeastOneOtherFirewallOn = 0;
		var otherFirewallHasProblemCount = 0;
		var re = new RegExp("[Mm]icrosoft(.*?)[Ff]irewall");
		for (var i = 0; i<category.item.length; i++) {
			securityItem = category.item[i];

			if (OPSWAT_FW == securityItem.type) {
				firewallCount++;
				
				if (securityItem.name.match(re)) {
					isWindowFirewallAvailable = 1;
					windowFirewallLocation = i;
					if (securityItem.status & Opswat_Info_IsEnabled) {
						isWindowFirewallOn = 1;
						this.isAllFirewallOff = false;
					}
				}
				else {
					if (securityItem.status & Opswat_Info_IsEnabled) {
						this.isAllFirewallOff = false;
						isAtLeastOneOtherFirewallOn = 1;
						if ((securityItem.status & Opswat_Info_IsExpired) || (securityItem.status &  Opswat_Info_UnpdVerf_UpdateIsNotLatest)) {
							otherFirewallHasProblemCount++;
						}
					}
					else {
						otherFirewallHasProblemCount++;
					}
				}
			}
		}

		//assume windows firewall always there, so firewallCount will be at least 1.
		//case 1: no 3rd party, only windows or without, can go through normal route
		if (firewallCount <= 1) {
			return 1;
		}
		
		//whenever at least ONE 3rd party firewall is on, we will not show windows
		if (isAtLeastOneOtherFirewallOn) {
			category.item.splice(windowFirewallLocation, 1);
			if (!isWindowFirewallOn) {
				category.issue = parseInt(category.issue) - 1;
				this.totalRedIssue = parseInt(this.totalRedIssue) - 1;
			}
		}
		
		this.problemFirewallCount = otherFirewallHasProblemCount + (!isWindowFirewallOn ? 1 : 0);

		if (otherFirewallHasProblemCount != 0 && category.issue == otherFirewallHasProblemCount) {
			return this.properties.your_security + ": <label id='cardTitle" + category.category + "' class='cardTitleDesc'>" + this.properties.safe_but_has_other_problem.replace("$COUNT$", "<label id='unsafeCount" + category.category + "'>" + otherFirewallHasProblemCount + "</label>").replace("$APP$", this.properties.firewall) + "</label>";
		}
		else {
			return 1;
		}
	}
	,
	
	/**
	 * Construct the title bar card of a category
	 * 
	 * @param {object} category the JSON formatted category object that needs to be 
	 * processed
	 */
	_constructTitle: function(category) {
		//this.totalIssue += parseInt(category.issue);
		var alias = category.category;
		var title = "";
		
		var goNormalRoute = this._getSecurityTitle(category);
		
		if (goNormalRoute == 1) {
			title = this._getTitle(category, 0);
		}
		else {
			title = goNormalRoute;
		}
		
		this.html += "<table border='0' width='642px' cellspacing='0' cellpadding='0' style='padding-left:3px'>";
		this.html += "<tr>";
		this.html += "<td>";
		this.html += "<table border='0' width='100%' cellspacing='0' cellpadding='0'>";
		this.html += "<tr>";
		this.html += "<td>";
		this.html += "<table style='position:relative' border='0' width='100%' cellspacing='0' cellpadding='0'>";
		this.html += "<tr id='card" + alias + "' style='cursor: pointer;' onclick='javascript:expandDetails(" + alias + ", 1)' onmouseover='onCardMouseOver(this)' onmouseout='onCardMouseOut(this)' onselectstart='return false;'>";
		this.html += "<td style='width:5px'><div class='cardLeft'></div><div class='cardLeftOver'></div><div class='cardLeftOpened'></div></td>";
    this.html += "<td style='width:632px' class='cardTitle'><div class='cardMid'>";
    this._getStatusIcon(category.category, (goNormalRoute == 1 ? category.issue : 0)); 
    this.html += "<div style='position:absolute; line-height:36px; margin-left:45px;'>" + title + "</div>";
    this.html += "<div style='position:absolute; line-height:36px; margin-left:542px; width:50px; text-align:right;'><label class='smallLabel'>" + this.properties.open_string + "</label></div><div class='cardBtnClosed'></div><div class='cardBtnOver'></div><div class='cardBtnOpened'></div>";
    this.html += "</div></td>";
    this.html += "<td style='width:5px;'><div class='cardRight'></div><div class='cardRightOver'></div><div class='cardRightOpened'></div></td>";
		this.html +=	"</tr>";
		this.html +=	"</table>";
		this.html +=	"</td>";
		this.html +=	"</tr>";
		this.html += "<tr>";
		this.html +=	"<td>";
		this.html +=	"<div id='" + alias + "' style='margin-top:-1px; visibility: hidden; display: none; border-left:1px solid #DDDDDD; border-right:1px solid #DDDDDD; border-bottom:1px solid #DDDDDD;'>";
		this.html +=	"<table border='0' width='100%' cellspacing='0' cellpadding='0'>";
		this.html +=	"<tr>";
		this.html +=	"<td>";
		this.html += "<table border='0' width='100%' cellspacing='0' cellpadding='0'>";	
		
		var safeItems = this._constructResultItems(alias, category);
		
		this.html += "</table>";
		this.html +=	"</td>";
		this.html +=	"</tr>";
		
		this._constructSafeAppsBar(alias, category, safeItems);
		
		this.html +=	"</table>";
		this.html += "</div>";
		this.html +=	"</td>";
		this.html +=	"</tr>";
		this.html +=	"</table>";
		this.html +=	"</td>";
		this.html += "</tr>";
		this.html += "<tr><td><font size='1'>&nbsp;</font></td></tr></table>";
		
		this.vulnerability.addCount(category.category, category.issue);
	}
	,
	
	_getStatusIcon: function(category, issue) {
			this.html += "<div id='cardIconRed" + category + "' class='cardIconRed' style='visibility:" + (((CATEGORY_WINDOWS == parseInt(category) || CATEGORY_SECURITY == parseInt(category)) && parseInt(issue) > 0) ? "visible" : "hidden") + "'></div>";
			this.html += "<div id='cardIconOrange" + category + "' class='cardIconOrange' style='visibility:" + ((CATEGORY_WINDOWS != parseInt(category) && CATEGORY_SECURITY != parseInt(category) && parseInt(issue) > 0) ? "visible" : "hidden") + "'></div>";
			this.html += "<div id='cardIconGreen" + category + "' class='cardIconGreen' style='visibility:" + (parseInt(issue) > 0 ? "hidden" : "visible") + "'></div>"; 
			
			//We add up the total red and orange issue count here
			if (CATEGORY_WINDOWS == parseInt(category) || CATEGORY_SECURITY == parseInt(category)) {
				this.totalRedIssue += parseInt(issue);
			}
			else {
				this.totalOrangeIssue += parseInt(issue);
			}
	}
	,
	
	_constructSafeAppsBar: function(alias, category, safeItems) {
		var safeBarDivAlias = "9" + alias;
		var safeAppCount = parseInt(category.item.length) - parseInt(category.issue);
		if (safeAppCount > 0) {
			this.html += "<tr>";
			this.html += "<td><div style='height:26px; border-top:1px solid #DDDDDD;'>";
			this.html += "<table border='0' width='100%' cellspacing='0' cellpadding='0'>";
			this.html += "<tr class='smallLabel'>";
			this.html += "<td><div style='height:26px; width:17px'></div></td>"
			this.html += "<td><div style='height:17px; width:17px; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/item_is_safe.png\")'></div></td>";
			this.html += "<td><div style='height:26px; width:15px'></div></td>";
			this.html += "<td width='300px'>" + this._getTitle(category, 1) + "</td>";
			this.html += "<td width='200px' align='right'><div>";
			this.html += "<div class='smallLabel' style='cursor: pointer' onclick='javascript:expandDetails(" + safeBarDivAlias + ", 3);'><label id='safeBarShowAll" + safeBarDivAlias + "'>" + this.properties.more_string + " </label>&nbsp;&nbsp;&nbsp;&nbsp;<div id='safeBarShowAllIcon" + safeBarDivAlias + "' style='cursor: pointer; position:absolute; height:13px; width:13px; margin-left:-10px; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/item_closed.png\");'></div></div>";
			this.html += "</div></td>";
			this.html += "<td style='width:123px'><div style='height:26px;'></div></td>";
			this.html += "</tr>";
			this.html += "</table>";
			this.html += "</div></td>";
			this.html += "</tr>";
			this.html += "<tr>";
			this.html += "<td>";
			this.html += "<div id='" + safeBarDivAlias + "' style='visibility:hidden; display:none'>";
			this.html += "<table id='safeItems" + alias + "' border='0' width='100%' cellspacing='0' cellpadding='0'>";
			this.html += safeItems;
			this.html += "</table>";
			this.html += "</div>";
			this.html += "</td>";
			this.html += "</tr>";
		}
	}
	,
	
	/*
	 * Get the category title description from our localization properties file
	 * 
	 * @param {object} category the JSON formatted category object
	 */
	_getTitle: function(category, isSafeAppTitle) {
		switch (parseInt(category.category)) {
      case CATEGORY_WINDOWS:
				return this._isSafe(category.category, this.properties.your_windows, category.issue, category.item.length, 1, isSafeAppTitle);
			case CATEGORY_SECURITY:
				return this._isSafe(category.category, this.properties.your_security, category.issue, category.item.length, 1, isSafeAppTitle);
			case CATEGORY_BROWSE:
				return this._isSafe(category.category, this.properties.browse_string, category.issue, category.item.length, 0, isSafeAppTitle);
			case CATEGORY_EMAIL:
				return this._isSafe(category.category, this.properties.email_string, category.issue, category.item.length, 0, isSafeAppTitle);
			case CATEGORY_CHAT:
				return this._isSafe(category.category, this.properties.chat_string, category.issue, category.item.length, 0, isSafeAppTitle);
			case CATEGORY_DOCUMENT:
				return this._isSafe(category.category, this.properties.document_multimedia_string, category.issue, category.item.length, 0, isSafeAppTitle);
			case CATEGORY_OTHER:
				return this._isSafe(category.category, this.properties.other_string, category.issue, category.item.length, 0, isSafeAppTitle);
		}
	}
	,
	
	/**
	 * Determine whether this category has vulnerability based on <code>insecureCount</code>,
	 * and return the proper title for the card.
	 * We also use this method retrieve title for safe application group.
	 * 
	 * @param {string} categoryDesc The category description as restrieved from properties file.
	 * @param {integer} insecureCount the insecure software number return from activeX backend.
	 * @param {integer} appCount total software number in this category.
	 * @param {boolean} isSystem <code>false</code>=web, email, chat, multimedia, document, others, 
	 * <code>true</code>=windows and security
	 * @param {boolean} isSafeAppTitle <code>true</code>=use to get the title for
	 * safe applications grouping.
	 */
	_isSafe: function(category, categoryDesc, insecureCount, appCount, isSecurity, isSafeAppTitle) {
		if (isSafeAppTitle) {
			if (parseInt(appCount) - parseInt(insecureCount) == 1) {
				return "<label id='safe" + category + "'>" + this.properties.program_up_to_date_singular.replace("$COUNT$", "<label id='safeCount" + category + "'>" + (parseInt(appCount) - parseInt(insecureCount)) + "</label>") + "</label>";
			}
			else {
				return "<label id='safe" + category + "'>" + this.properties.program_up_to_date.replace("$COUNT$", "<label id='safeCount" + category + "'>" + (parseInt(appCount) - parseInt(insecureCount)) + "</label>") + "</label>";
			}
		}
		else {
			if (parseInt(insecureCount) == 0) {
	      if (isSecurity)
	        return categoryDesc + ": <label class='cardTitleDesc'>" + this.properties.up_to_date + "</label>";
	      else 
	        return categoryDesc + ": <label class='cardTitleDesc'>" + this.properties.all_programs_up_to_date + "</label>";
			}
			else {
	      if (isSecurity) {
	      	if (parseInt(insecureCount) == 1) {
	      		return categoryDesc + ": <label id='cardTitle" + category + "' class='cardTitleDesc'>" + this.properties.item_need_attention_singular.replace("$COUNT$", "<label id='unsafeCount" + category + "'>" + insecureCount + "</label>") + "</label>";
	      	}
	      	else {
	        	return categoryDesc + ": <label id='cardTitle" + category + "' class='cardTitleDesc'>" + this.properties.item_need_attention.replace("$COUNT$", "<label id='unsafeCount" + category + "'>" + insecureCount + "</label>") + "</label>";
	      	}
	      }
	      else {
	      	if (parseInt(insecureCount) == 1) {
	      		return categoryDesc + ": <label id='cardTitle" + category + "' class='cardTitleDesc'>" + this.properties.program_need_updating_singular.replace("$COUNT$", "<label id='unsafeCount" + category + "'>" + insecureCount + "</label>") + "</label>";
	      	}
	      	else {
	        	return categoryDesc + ": <label id='cardTitle" + category + "' class='cardTitleDesc'>" + this.properties.program_need_updating.replace("$COUNT$", "<label id='unsafeCount" + category + "'>" + insecureCount + "</label>") + "</label>";
	      	}
	      }
			}			
		}
	}
	,
	
	/**
	 * Return the constructed insecure software count string.
	 * 
	 * @param {integer} count total insecure software.
	 */
	_insecureCount: function(count) {
    return count + " " + this.properties.issue_found;
  }
	,
	
	/**
	 * Construct the vulnerability item
	 * 
	 * @param {integer} alias alias name of this category, in this case, the category number.
	 * @param {object} category the JSON formatted category object that needs to be processed
	 */
	_constructResultItems: function(alias, category) {
		var safeItems = "";
		for (var i = 0; i<category.item.length; i++) {
			appItem = category.item[i];
			this._getItemStatus(appItem);
			itemAlias = alias + "" + i;

			if (!appItem.isSafe) {
				this.html += "<tr id='" + itemAlias + "title' style='height:36px; line-height:18px'>";
				this.html += "<td><div style='width:1px'></div></td>";
				this.html += "<td style='background: url(img/item_mid.png);'><div style='height:36px; width:10px'></div></td>";
				this.html += "<td style='background: url(img/item_mid.png); height:36px'><div style='width:30px'>" + this._getAppIcon(itemAlias, appItem, category.category) + "</div></td>";
				this.html += "<td style='background: url(img/item_mid.png);'><div style='height:36px; width:6px'></div></td>";
				this.html += "<td style='background: url(img/item_mid.png); height:36px;'><div style='width:360px;'><label id='appTitle" + itemAlias + "' class='description'>" + this._getItemTitle(appItem, category.category) + "</label></div></td>";
				this.html += "<td style='background: url(img/item_mid.png);'><div style='height:36px; width:0px'></div></td>";
				this.html += "<td align='right' style='background: url(img/item_mid.png); height:36px'>";
				this.html += "<div id='more" + itemAlias + "' style='width:110px'>";
				
				this._addMoreButton(itemAlias, appItem.isSafe);
				
				this.html += "</div>";
				this.html += "</td>";
				this.html += "<td style='background: url(img/item_mid.png);'><div style='height:36px; width:15px'></div></td>";
				this.html += "<td style='background: url(img/item_mid.png); height:36px;'>";
				this.html += "<div style='width:90px'>";
				this.html += "<div id='solve" + itemAlias + "' style='width:90px'>";
				
				this._addSolutionButton(category.category, itemAlias, appItem);
				this.html += "</div>";
				this.html += "</div>";
				this.html += "</td>";
				this.html += "<td style='background: url(img/item_mid.png);'><div style='height:36px; width:7px'></div></td>";
				this.html += "<td><div style='width:1px'></div></td>";
				this.html += "</tr>";
				this.html += "<tr id='" + itemAlias + "desc'>";
				this.html += "<td colspan='11'>";
				this.html += "<div id='" + itemAlias + "' style='visibility: hidden; display: none;'>";
				this.html += "<table border='0' cellspacing='0' cellpadding='0' width='100%'>";
				this.html += "<tr>";
				this.html += "<td style='width:650px; padding-left:10px; padding-right:10px;' class='description'><div><div style='margin-top:6px'>" + this._getItemDesc(appItem, category.category) + "</div></div></td>";
				this.html += "</tr>";
				this.html += "</table>";
				this.html += "</div>";
				this.html += "</td>";
				this.html += "</tr>";
			}
			else {
				safeItems += this._constructSafeItem(appItem, alias);
			}
		}
		
		return safeItems;
	}
	,
	_constructSafeItem: function(appItem, alias) {
		var safeItem = "";
		safeItem += "<tr style='height:36px; line-height:18px'>";
		safeItem += "<td><div style='width:1px'></div></td>";
		safeItem += "<td style='background: url(img/item_mid.png);'><div style='height:36px; width:7px'></div></td>";
		safeItem += "<td width='4%' style='background: url(img/item_mid.png); height:36px'>";
		var tempIcon = unescape(appItem.icon);
		safeItem += (appItem.icon != "null" ?
						("<div style='margin-top:4px;'><img src='" + tempIcon + "' border='0' width='27px' height='27px'/>" +
						"<div class='smallStatusIconGreenWithAppIcon' style='visibility:" + (appItem.isSafe ? "visible" : "hidden") + "'></div>" )
						:
						("<div style='width:27px; height:24px; margin-top:0px; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/windows_icon.png\");'>" +
						"<div class='smallStatusIconGreen' style='visibility:" + (appItem.isSafe ? "visible" : "hidden") + "'></div>") + 
						"</div>");		
		safeItem += "</td>";
		safeItem += "<td style='background: url(img/item_mid.png);'><div style='height:36px; width:8px'></div></td>";
		safeItem += "<td width='59%' style='background: url(img/item_mid.png); height:36px'><label class='description'>" + this._getItemTitle(appItem, alias) + "</label></td>";
		safeItem += "<td style='background: url(img/item_mid.png);'><div style='height:36px; width:8px'></div></td>";
		safeItem += "<td align='right' width='15%' style='background: url(img/item_mid.png); height:36px'>";
		safeItem += "<div></div>";
		safeItem += "</td>";
		safeItem += "<td style='background: url(img/item_mid.png);'><div style='height:36px; width:11px'></div></td>";
		safeItem += "<td width='12%' style='background: url(img/item_mid.png); height:36px;'>";
		safeItem += "<div></div>";
		safeItem += "</td>";
		safeItem += "<td style='background: url(img/item_mid.png);'><div style='height:36px; width:7px'></div></td>";
		safeItem += "<td><div style='width:1px'></div></td>";
		safeItem += "</tr>";
		
		return safeItem;
	}
	,
	
	_getItemStatus: function(appItem) {
		if ("secure" == appItem.status) {
			appItem.isSafe = 1;
		}
		else if ("insecure" == appItem.status || "endoflife" == appItem.status) {
			appItem.isSafe = 0;
		}
		else {
			if (appItem.status & Opswat_Info_ProductNotInstalled) {
				appItem.isSafe = 0;
			}
			else {
				appItem.isSafe = 1;
				if (appItem.status & Opswat_Info_IsEnabled) {
					//do nothing
				}
				else {
					appItem.isSafe = 0;
				}
				
				if (appItem.status & Opswat_Info_UnpdVerf_UpdateIsNotLatest) {
					appItem.isSafe = 0;
				}
				
				if (appItem.status & Opswat_Info_IsExpired) {
					appItem.isSafe = 0;
				}

				if (appItem.status & Opswat_Info_ProductOutdated) {
				  appItem.isSafe = 0;
        }
			}
		}
	}
	,
	
	/**
	 * Retrieve the proper icon for different softwares (<code>appItem</code>), 
	 * as well as adding an additional icon to determine is ii vunerable.
	 *
	 * @param {integer} alias the alias for this item, which is in the format of 
	 * category number + software count.
	 * @param {object} appItem the JSON formatted software object return by the activeX backend.
	 * @param {integer} categoryId the category number.
	 */
	_getAppIcon: function(alias, appItem, categoryId) {
		if ((CATEGORY_SECURITY == categoryId) && (appItem.status & Opswat_Info_ProductNotInstalled)) {
			return "<div style='width:25px; height:25px; margin-top:2px; margin-left:2px; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/missing_alert.png\");'>";
		}
		var tempIcon = unescape(appItem.icon);
		return(appItem.icon != "null" ?
    ("<div style='margin-top:4px;'><img src='" + tempIcon + "' border='0' width='27px' height='27px'/>" +
 		this._getSmallStatusIcon(alias, appItem, categoryId, 1)) :
    ("<div style='width:27px; height:24px; margin-top:2px; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/windows_icon.png\");'>" +
    this._getSmallStatusIcon(alias, appItem, categoryId, 0)) + 
		"</div>");
		encodeURI(tempIcon);
	}
	,
	
	/**
	 * Determine whether this <code>appItem</code> is vulnerable.
	 * Vulnerable <code>appItem</code> will have the red icon, otherwise a green
	 * icon will be returned.
	 * 
	 * @param {object} appItem the JSON formatted software object return by the activeX backend.
	 * @param categoryId the category number.
	 */
	_getSmallStatusIcon: function(alias, appItem, categoryId, isWithAppIcon) {
		return "<div id='smallStatusRed" + alias + "' class='smallStatusIconRed" + (isWithAppIcon ? "WithAppIcon" : "")+ "' style='visibility: " + (!appItem.isSafe && (CATEGORY_WINDOWS == parseInt(categoryId) || CATEGORY_SECURITY == parseInt(categoryId)) ? "visible" : "hidden") + "'></div>" +
			"<div id='smallStatusOrange" + alias + "' class='smallStatusIconOrange" + (isWithAppIcon ? "WithAppIcon" : "")+ "' style='visibility: " + (!appItem.isSafe && CATEGORY_WINDOWS != parseInt(categoryId) && CATEGORY_SECURITY != parseInt(categoryId) ? "visible" : "hidden") + "'></div>" +
			"<div id='smallStatusGreen" + alias + "' class='smallStatusIconGreen" + (isWithAppIcon ? "WithAppIcon" : "")+ "' style='visibility:" + (appItem.isSafe ? "visible" : "hidden") + "'></div>" +
			"<div id='smallStatusGray" + alias + "' class='smallStatusIconGray" + (isWithAppIcon ? "WithAppIcon" : "")+ "' style='visibility:" + (appItem.isSafe ? "visible" : "hidden") + "'></div>";
	}
	,
	
	/**
	 * Construct the description of the item based on the software status.
	 * 
	 * @param {object} appItem the JSON formatted software object return by the activeX backend.
	 * @param {integer} categoryId the category number.
	 */
	_getItemTitle: function(appItem, categoryId) {
		if (CATEGORY_SECURITY == categoryId) {
			return this._getSecurityItemTitle(appItem);
		}

		if (!appItem.isSafe) {
			if ("endoflife" == appItem.status)
				return appItem.name + " " + this.properties.is_no_longer_supported;
			else
				return appItem.name + " " + this.properties.is_not_updated;
		}
		else {
			return appItem.name + " " + this.properties.is_updated;
		}
	}
	,
	
	/**
	 * Security item, aka system item, aka OPSWAT item, has 3 types, antivirus, 
	 * antispyware and firewall. The description of these items are a bit different
	 * and require special handling.
	 * 
	 * @param {object} appItem the JSON formatted software object return by the activeX backend
	 * @param {boolean} isDetails <code>true</code> if we are requesting detailed description
	 * of this security item, otherwise we just need the item title for it.
	 */
	_getSecurityItemTitle: function(appItem) {
		var status = parseInt(appItem.status);
		var desc = "";
		var product = "";
		
		if (OPSWAT_AV == appItem.type) {
			product = this.properties.antivirus;
		}
		else if (OPSWAT_SW == appItem.type) {
			product = this.properties.antispyware;
		}
		else if (OPSWAT_FW == appItem.type) {
			product = this.properties.firewall;
		}
		
		if (status & Opswat_Info_ProductNotInstalled) {
	    return this.properties.missing.replace("$APP$", product.substring(0, 1).toUpperCase().concat(product.substring(1)));
	  }
    
    if (status & Opswat_Info_ProductOutdated) {
      return product.substring(0, 1).toUpperCase().concat(product.substring(1)) + ": " +  appItem.name + " " + this.properties.is_out_of_date;
    } 
	  
	  if (status & Opswat_Info_IsEnabled) {
      if ((status & Opswat_Info_UnpdVerf_UpdateIsNotLatest) && (status & Opswat_Info_IsExpired)) {
     		desc = product.substring(0, 1).toUpperCase().concat(product.substring(1)) + ": " + appItem.name + " " + this.properties.is_not_updated + " " + this.properties.and_connector + " " + this.properties.expired;
      }
      else if (status & Opswat_Info_UnpdVerf_UpdateIsNotLatest) {
     		desc = product.substring(0, 1).toUpperCase().concat(product.substring(1)) + ": " +  appItem.name + " " + this.properties.is_not_updated;
      }
      else if (status & Opswat_Info_IsExpired) {
     		desc = product.substring(0, 1).toUpperCase().concat(product.substring(1)) + ": " +  appItem.name + " " + this.properties.expired;
      }
      else {
      	desc = product.substring(0, 1).toUpperCase().concat(product.substring(1)) + ": " +  appItem.name + " " + this.properties.is_on;
      }
	  }
	  else {
	  	if ((status & Opswat_Info_UnpdVerf_UpdateIsNotLatest) && (status & Opswat_Info_IsExpired)) {
		 		desc = product.substring(0, 1).toUpperCase().concat(product.substring(1)) + ": " + appItem.name + " " + this.properties.is_not_on + ", " + this.properties.expired + " " + this.properties.and_connector + " " + this.properties.is_not_updated;
	  	}
	  	else if (status & Opswat_Info_UnpdVerf_UpdateIsNotLatest) {
	  		desc = product.substring(0, 1).toUpperCase().concat(product.substring(1)) + ": " + appItem.name + " " + this.properties.is_not_on + " " + this.properties.and_connector + " " + this.properties.is_not_updated;
	  	}
	  	else if (status & Opswat_Info_IsExpired) {
				desc = product.substring(0, 1).toUpperCase().concat(product.substring(1)) + ": " + appItem.name + " " + this.properties.is_not_on + " " + this.properties.and_connector + " " + this.properties.expired;
	  	}
	  	else {
				desc = product.substring(0, 1).toUpperCase().concat(product.substring(1)) + ": " + appItem.name + " " + this.properties.is_not_on;
	  	}	  	
	  }
	  
	  return desc;
	}
	,

	/**
	 * Construct the string each item.
	 * If software item is Windows or Security category, will be handled differently.
	 * 
	 * @param {object} appItem the JSON formatted software object return by the activeX backend.
	 * @param {integer} category the category number.
	 */
	_getItemDesc: function(appItem, category) {
		var desc = "";

		if (CATEGORY_SECURITY == category) {
      desc = this._getSecurityItemDesc(appItem);
    }
    else {
    	if (appItem.type == 'microsoft') {
    		desc += this.properties.ms_missing_patch + "<p>" + this.properties.ms_missing_update + ":<br>";
    		var kbs = appItem.msKB.split(',');
    		for (var i=0; i<kbs.length; i++) {
	    		desc +=	"<a href='http://support.microsoft.com/kb/"+ kbs[i] + "/' target='_blank'>KB" + kbs[i] + "</a>  <img style='height:9px; width:9px; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/new_window_blue.png\");'>";	    		
	    		
    			if (i < kbs.length -1) {
    				desc += ', ';
    			}
    		}
    	}
    	else if (appItem.type == 'sp') {
    		desc = this.properties.missing_sp;
    	}
    	else {
    		if ("endoflife" == appItem.status) {
    			desc += this.properties.discontinued_product.replace("$CVER$", appItem.version);
    		}
    		else {
		  		desc += this.properties.insecure_app.replace("$APP$", appItem.name).replace("$CVER$", appItem.version).replace("$LVER$", appItem.secureVersion);
		  		if (appItem.secuniaID != null && this.properties.advisory_detail != null) {
		  			desc += " " + this.properties.advisory_detail.replace("$SA$", "SA" + appItem.secuniaID).replace("$SA$", "SA" + appItem.secuniaID).replace("$NEW$", "<img style='height:9px; width:9px; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/new_window_blue.png\");'>");
		  		}
	  		}
    	}
    }
		desc += "<div style='height:10px; font-size:1px'></div>";
		return desc;
	}
	,
	
	/**
	 * Construct the description based on the security item <code>status</code>.
	 * We combine several status together, so we need to do bitwise comparison
	 * to retrieve these status.
	 * 
	 * @param {object} appItem the JSON formatted software object return by the activeX backend.
	 * @param {string} product the 3 security types, antivirus, antispyware, firewall.
	 * @param {integer} type <code>1</code> indicates we are getting the details description,
	 * <code>2</code> indicates we just need the brief item title, <code>3</code> is just
	 * to determine whether this item is <code>safe</code> or <code>not safe</code>
	 * 
	 */
	_getSecurityItemDesc: function(appItem) {
		var status = parseInt(appItem.status);
		var desc = "";
		var product = "";
		
		if (OPSWAT_AV == appItem.type) {
			product = this.properties.antivirus_program;
		}
		else if (OPSWAT_SW == appItem.type) {
			product = this.properties.antispyware_program;
		}
		else if (OPSWAT_FW == appItem.type) {
			product = this.properties.firewall;
		}
		
		if (status & Opswat_Info_ProductNotInstalled) {
        return this._getDetail(appItem, product, 1);
	  }
	  
		if (status & Opswat_Info_ProductOutdated) {
        return this.properties.virus_def_is_out_of_date.replace("$D$", appItem.outdatedDay);
	  }
	  
	  if (status & Opswat_Info_IsEnabled) {      
      if ((status & Opswat_Info_UnpdVerf_UpdateIsNotLatest) && (status & Opswat_Info_IsExpired)) {
      		if (appItem.fileDateTime != null && appItem.fileDateTime.length > 0) {
      			desc += this.properties.program_not_updated_expired.replace("$APP$", product).replace('$D$', appItem.fileDateTime.substring(0, appItem.fileDateTime.indexOf(' '))) + " " + this._getDetail(appItem, product, 0);
      		}
      		else {
      			desc += this.properties.program_not_updated_nodate_expired.replace("$APP$", product) + " " + this._getDetail(appItem, product, 0);
      		}
      }
      else if (status & Opswat_Info_UnpdVerf_UpdateIsNotLatest) {
      		if (appItem.fileDateTime != null && appItem.fileDateTime.length > 0) {
      			desc += this.properties.program_not_updated.replace("$APP$", product).replace('$D$', appItem.fileDateTime.substring(0, appItem.fileDateTime.indexOf(' '))) + " " + this._getDetail(appItem, product, 0);
      		}
      		else {
      			desc += this.properties.program_not_updated_nodate.replace("$APP$", product) + " " + this._getDetail(appItem, product, 0);
      		}
      }
      else if (status & Opswat_Info_IsExpired) {
      		desc += this.properties.program_has_expired.replace("$APP$", product) + " " + this._getDetail(appItem, product, 0);
      }
	  }
	  else {
	  	if ((status & Opswat_Info_UnpdVerf_UpdateIsNotLatest) && (status & Opswat_Info_IsExpired)) {
	  			if (appItem.fileDateTime != null && appItem.fileDateTime.length > 0) {
		  			desc = this.properties.program_is_off_not_updated_expired.replace("$APP$", product).replace('$D$', appItem.fileDateTime.substring(0, appItem.fileDateTime.indexOf(' '))) + " " + this._getDetail(appItem, product, 0);
	  			}
	  			else {
		  			desc = this.properties.program_is_off_not_updated_nodate_expired.replace("$APP$", product) + " " + this._getDetail(appItem, product, 0);
	  			}
	  	}
	  	else if (status & Opswat_Info_UnpdVerf_UpdateIsNotLatest) {
	  		if (appItem.fileDateTime != null && appItem.fileDateTime.length > 0) {
	  			desc = this.properties.program_is_off_not_updated.replace("$APP$", product).replace('$D$', appItem.fileDateTime.substring(0, appItem.fileDateTime.indexOf(' '))) + " " + this._getDetail(appItem, product, 0);
	  		}
	  		else {
	  			desc = this.properties.program_is_off_not_updated_nodate.replace("$APP$", product) + " " + this._getDetail(appItem, product, 0);
	  		}
	  	}
	  	else if (status & Opswat_Info_IsExpired) {
	  			desc = this.properties.program_is_off_expired.replace("$APP$", product) + " " + this._getDetail(appItem, product, 0);
	  	}
	  	else {
	  			desc = this.properties.program_is_off.replace("$APP$", product) + " " + this._getDetail(appItem, product, 0);
	  	}
	  }
	  
	  return desc;
	}
	,
	
	/**
	 * Construct the detail description if user doesn't have certain security software
	 * installed/updated/license renewed.
	 * 
	 * @param {object} appItem the JSON formatted software object return by the activeX backend.
	 * @param {string} product the 3 security types, antivirus, antispyware, firewall.
	 */
	_getDetail: function (appItem, product, isMissing){
    if (this.properties.antivirus_program == product) {
    	if (isMissing)
      	return this.properties.without_antivirus;
      else
      	return this.properties.require_antivirus;
    }
    else if (this.properties.antispyware_program == product) {
    	if (isMissing)
      	return this.properties.without_antispyware;
      else 
      	return this.properties.require_antispyware;
    }
    else {
    	if (isMissing)
	      return this.properties.without_firewall;
			else
				return this.properties.require_firewall;
    }
  }
  ,	
	
	/**
	 * Only <code>secure</code> item will have the <code>more</code> link (button)
	 * hidden. That means any other status (insecure, and including OPSWAT integer 
	 * type status) will have some information on this item)
	 * 
	 */
	_addMoreButton: function(alias, isSafe) {
		if (isSafe) {
			this.html +="&nbsp;";
		}
		else {
			this.html += "<div class='smallLabel' style='cursor: pointer' onclick='javascript:expandDetails(" + alias + ", 2);'><label id='labelMore" + alias + "'>" + this.properties.more_string + " </label>&nbsp;&nbsp;&nbsp;&nbsp;<div id='btnMore" + alias + "' style='cursor: pointer; position:absolute; height:13px; width:13px; margin-left:-10px; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/item_closed.png\");'></div></div>";
		}
	}
	,

	/**
	 * Construct the solution. Only <code>secure</code> item and security(OPSWAT) 
	 * item with a checking return of <code>safe</code> will have the <code>Solve</code> 
	 * (solution) button <code>hidden</code>.
	 * 
	 * @param {integer} alias the alias for this item, which is in the format of 
	 * category number + software count.
	 * @param {string} status <code>insecure</code> or <code>secure</code>
	 * @param {appItem} the JSON formatted software object return by the activeX backend.
	 */
	_addSolutionButton: function(category, alias, appItem) {
		if(appItem.isSafe) {
			this.html +="&nbsp;";
		}
		else {
			this.html +=
								"<table border='0' width='100%' cellspacing='0' cellpadding='0'>" + 
								"<tr style='cursor:pointer' onclick='javascript:" + (top.progress ? "top.progress." : "") + "showSolution(\"" + category + "\", \"" + alias + "\", \"" + appItem.name + "\", \"" + appItem.type + "\", \"" + appItem.version + "\", \"" + appItem.secureVersion + "\", \"" + appItem.fileDateTime + "\", \"" + appItem.status + "\", \"" + this._getSolution(appItem) + "\");' onMouseOver='onBtnMouseOver(this, 18);' onMouseOut='onBtnMouseOut(this);' onselectstart='return false;'>" + 
								"<td style='width:3px;'><div class='smallButtonLeft'></div><div class='smallButtonLeftOver'></div></td>" +
								"<td class='smallLabel' style='width:84px; text-align:center'><div class='smallButtonMid'>" +
								this.properties.solve_string + "..." +
								"</div></td>" + 
								"<td style='width:3px;'><div class='smallButtonRight'></div><div class='smallButtonRightOver'></div></td>" +
								"</tr>" + 
								"</table>";
		}
	}
	,
	
	_getSolution: function (appItem) {
		if ("sp" == appItem.type) {
			return appItem.directDownloadUrl;
		}
		else if ("microsoft" == appItem.type) {
			return appItem.msKB;
		}
		else if ("secunia" == appItem.type) {
			return appItem.directDownloadUrl;
		}
		else {
			return appItem.solution;
		}
	}
}

/**
 * An object to store the current count of different vulnerabiliy colors
 */
function Vulnerability() {
	this.red = 0;
	this.orange = 0;
	this.gray = 0;
}

Vulnerability.prototype = {
	addCount: function(category, count) {
		if (category == CATEGORY_WINDOWS || category == CATEGORY_SECURITY) {
			this.red += parseInt(count);
		}
		else {
			this.orange += parseInt(count);
		}
	}
}

/**
 * Expand or close a hidden DIV details. This operation is used in both card and item.
 * 
 * @param {integer} the DIV's alias, this is the category number.
 * @param {integer} <code>1</code> is card, <code>2</code> is item, <code>3</code> is safe item bar.
 */
function expandDetails(resultDivId, labelType) {
	var doc = document;
	resultDiv = doc.getElementById(resultDivId);
	
	//calling by dynamically constructed safe app bar
	if (!resultDiv) {
		resultDiv = top.progress.subFrame.card.document.getElementById(resultDivId);
	}
	
	//The DIV is hidden, so this is a EXPAND/OPEN operation, meaning show the DIV!
	if (resultDiv.style.visibility == 'hidden') {
		resultDiv.style.visibility='visible';
		resultDiv.style.display = 'block';
		
		if (labelType == 1) {
			closeExpandedCardOrItem(0, doc);
			updateCardLayout(1, 0, resultDivId);
			result.expandedCard = resultDivId;
			result.expandedItem = "";
			result.expandedSafeItemBar = "";
		}
		else if (labelType == 2) {
			closeExpandedCardOrItem(1, doc);
			theLabel = doc.getElementById('labelMore' + resultDivId);
			theLabel.innerText = properties.less_string + " ";
			theBtn = doc.getElementById('btnMore' + resultDivId);
			theBtn.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/item_opened.png\")";
			result.expandedItem = resultDivId;
		}
		else {
			//calling by dynamically constructed safe app bar
			if (!doc.getElementById('safeBarShowAll' + resultDivId))
				doc = top.progress.subFrame.card.document;

			theLabel = doc.getElementById('safeBarShowAll' + resultDivId);
			theLabel.innerText = properties.less_string + " ";
			theBtn = doc.getElementById('safeBarShowAllIcon' + resultDivId);
			theBtn.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/item_opened.png\")";
			result = top.progress ? top.progress.subFrame.card.result : result;
			result.expandedSafeItemBar = resultDivId;
		}
	}
	//The DIV is visible, so this is a CLOSE operation, hide the DIV.
	else {
		resultDiv.style.visibility='hidden';
		resultDiv.style.display = 'none';
		
		if (labelType == 1) {
			closeExpandedCardOrItem(1, doc);
			updateCardLayout(0, 0, resultDivId);
			result.expandedCard = "";
			result.expandedItem = "";
			result.expandedSafeItemBar = "";
		}
		else if (labelType == 2) {
			theLabel = doc.getElementById('labelMore' + resultDivId);
			theLabel.innerText = properties.more_string + " ";
			theBtn = doc.getElementById('btnMore' + resultDivId);
			theBtn.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/item_closed.png\")";
			result.expandedItem = "";
		}
		else {
			//calling by dynamically constructed safe app bar
			if (!doc.getElementById('safeBarShowAll' + resultDivId))
				doc = top.progress.subFrame.card.document;
			
			theLabel = doc.getElementById('safeBarShowAll' + resultDivId);
			theLabel.innerText = properties.more_string + " ";
			theBtn = doc.getElementById('safeBarShowAllIcon' + resultDivId);
			theBtn.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/item_closed.png\")";
			result = top.progress ? top.progress.subFrame.card.result : result;
			result.expandedSafeItemBar = "";
		}
	}
}

/**
 * Only 1 card and 1 item is allowed to be expanded in any given time. So when
 * user chooses to open a card or item, the previous opened card or item has to
 * be closed. Closing the card will also automatically close its items.
 * 
 * We use the local variable <code>expandedCard</card> and <code>expandedItem</code>
 * to store expanded card and item alias.
 * 
 * @param {boolean} isCloseItemOnly <code>true</code> if we are only closing expanded
 * item, otherwise, both card and item need to be closed.
 */
function closeExpandedCardOrItem(isCloseItemOnly, doc) {
	expandedCard = doc.getElementById(result.expandedCard);
	expandedItem = doc.getElementById(result.expandedItem);
	expandedSafeBar = doc.getElementById(result.expandedSafeItemBar);
	
	if (eval(expandedItem)) {
		expandedItem.style.visibility='hidden';
		expandedItem.style.display = 'none';
		
		theLabel = doc.getElementById('labelMore' + result.expandedItem);
		theLabel.innerText = properties.more_string + " ";
		theBtn = doc.getElementById('btnMore' + result.expandedItem);
		theBtn.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/item_closed.png\")";
	}
	
	if (eval(expandedSafeBar)) {
		expandedSafeBar.style.visibility='hidden';
		expandedSafeBar.style.display = 'none';
		
		theLabel = doc.getElementById('safeBarShowAll' + result.expandedSafeItemBar);
		theLabel.innerText = properties.more_string + " ";
		theBtn = doc.getElementById('safeBarShowAllIcon' + result.expandedSafeItemBar);
		theBtn.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src=\"img/item_closed.png\")";
	}
	
	if (!isCloseItemOnly) {
		if (eval(expandedCard)) {
			expandedCard.style.visibility='hidden';
			expandedCard.style.display = 'none';
			updateCardLayout(0, 1, result.expandedCard, doc);
		}
	}
}

function updateCardLayout(isOpenCard, isReturnOriState, alias, doc) {
	var card = document.getElementById('card' + alias);
	
	if (isOpenCard) {
		this.expandedCardOnMouseOver = card.onmouseover;
		this.expandedCardOnMouseOut = card.onmouseout;
		
		card.onmouseover = function() {};
		card.onmouseout = function() {};
		
		card.childNodes[0].childNodes[1].style.visibility = 'hidden';
		card.childNodes[0].childNodes[1].style.display = 'inline';
		card.childNodes[0].childNodes[2].style.visibility = 'visible';
		card.childNodes[0].childNodes[2].style.display = "block";
		
		card.childNodes[1].childNodes[0].style.backgroundPosition = '0px -72px';

		card.childNodes[1].childNodes[0].childNodes[4].firstChild.innerText = this.properties.close_string;
		card.childNodes[1].childNodes[0].childNodes[6].style.visibility = 'hidden';
		card.childNodes[1].childNodes[0].childNodes[6].style.display = 'inline';
		card.childNodes[1].childNodes[0].childNodes[7].style.visibility = 'visible';
		card.childNodes[1].childNodes[0].childNodes[7].style.display = 'block';		
		
		card.childNodes[2].childNodes[1].style.visibility = 'hidden';
		card.childNodes[2].childNodes[1].style.display = 'inline';
		card.childNodes[2].childNodes[2].style.visibility = 'visible';
		card.childNodes[2].childNodes[2].style.display = "block";
	}
	else {
		var state = 0;
		if (isReturnOriState)
			state = -1;
			
		card.onmouseover = this.expandedCardOnMouseOver;
		card.onmouseout = this.expandedCardOnMouseOut;
		
		card.childNodes[0].childNodes[2].style.visibility = 'hidden';
		card.childNodes[0].childNodes[2].style.display = 'inline';
		card.childNodes[0].childNodes[1 + state].style.visibility = 'visible';
		card.childNodes[0].childNodes[1 + state].style.display = "block";
		
		card.childNodes[1].childNodes[0].style.backgroundPosition = '0px ' + (isReturnOriState ? 0: -36) + 'px';
		
		card.childNodes[1].childNodes[0].childNodes[4].firstChild.innerText = this.properties.open_string;
		card.childNodes[1].childNodes[0].childNodes[7].style.visibility = 'hidden';
		card.childNodes[1].childNodes[0].childNodes[7].style.display = 'inline';
		card.childNodes[1].childNodes[0].childNodes[6 + state].style.visibility = 'visible';
		card.childNodes[1].childNodes[0].childNodes[6 + state].style.display = 'block';		
		
		card.childNodes[2].childNodes[2].style.visibility = 'hidden';
		card.childNodes[2].childNodes[2].style.display = 'inline';
		card.childNodes[2].childNodes[1 + state].style.visibility = 'visible';
		card.childNodes[2].childNodes[1 + state].style.display = "block";
	}	
}

function refreshResultHeader(totalRedIssue, totalOrangeIssue) {
  var issueCountText;
  var issueDescText; 
	document.getElementById("checkSuccess").innerText = properties.check_success;
	if (parseInt(totalRedIssue) == 0 && parseInt(totalOrangeIssue) == 0) {
		issueCountText = properties.report_all_safe;
		issueDescText = properties.no_issue_found;
	}
	else if (parseInt(totalRedIssue) > 0 && parseInt(totalOrangeIssue) == 0){
    issueCountText = parseInt(totalRedIssue) == 1 ? properties.red_issue_singular : properties.red_issue_plurar.replace("$ISSUE$", totalRedIssue);
    issueDescText = properties.windows_issue_found;
	}
	else if (parseInt(totalRedIssue) == 0 && parseInt(totalOrangeIssue) > 0) {
    issueCountText = properties.security_windows_uptodate + " ";
    issueCountText += parseInt(totalOrangeIssue) == 1 ? properties.orange_issue_singular : properties.orange_issue_plurar.replace("$ISSUE$", totalOrangeIssue);
    issueDescText = properties.other_issue_found;
  }
  else {
    issueCountText = parseInt(totalRedIssue) == 1 ? properties.red_issue_singular : properties.red_issue_plurar.replace("$ISSUE$", totalRedIssue) + " ";
    issueCountText += parseInt(totalOrangeIssue) == 1 ? properties.orange_issue_singular : properties.orange_issue_plurar.replace("$ISSUE$", totalOrangeIssue);    
    issueDescText = properties.issue_found_desc;
  }
	document.getElementById("issueCount").innerText = issueCountText;
	document.getElementById("issueDesc").innerText = issueDescText;
}

function onBtnMouseOver(elem, height) {
	elem.childNodes[0].childNodes[0].style.visibility = 'hidden';
	elem.childNodes[0].childNodes[0].style.display = 'inline';
	elem.childNodes[0].childNodes[1].style.visibility = 'visible';
	elem.childNodes[0].childNodes[1].style.display = "block";
	
	elem.childNodes[1].childNodes[0].style.backgroundPosition = '0px -' + height + 'px';
	
	elem.childNodes[2].childNodes[0].style.visibility = 'hidden';
	elem.childNodes[2].childNodes[0].style.display = 'inline';
	elem.childNodes[2].childNodes[1].style.visibility = 'visible';
	elem.childNodes[2].childNodes[1].style.display = "block";
}

function onBtnMouseOut(elem) {
	elem.childNodes[0].childNodes[0].style.visibility = 'visible';
	elem.childNodes[0].childNodes[0].style.display = 'block';
	elem.childNodes[0].childNodes[1].style.visibility = 'hidden';
	elem.childNodes[0].childNodes[1].style.display = "inline";
	
	elem.childNodes[1].childNodes[0].style.backgroundPosition = '0px 0px';
	
	elem.childNodes[2].childNodes[0].style.visibility = 'visible';
	elem.childNodes[2].childNodes[0].style.display = 'block';
	elem.childNodes[2].childNodes[1].style.visibility = 'hidden';
	elem.childNodes[2].childNodes[1].style.display = "inline";
}

function onCardMouseOver(elem) {
	elem.childNodes[0].childNodes[0].style.visibility = 'hidden';
	elem.childNodes[0].childNodes[0].style.display = 'inline';
	elem.childNodes[0].childNodes[1].style.visibility = 'visible';
	elem.childNodes[0].childNodes[1].style.display = "block";
	
	elem.childNodes[1].childNodes[0].style.backgroundPosition = '0px -36px';
	
	elem.childNodes[1].childNodes[0].childNodes[5].style.visibility = 'hidden';
	elem.childNodes[1].childNodes[0].childNodes[5].style.display = 'inline';
	elem.childNodes[1].childNodes[0].childNodes[6].style.visibility = 'visible';
	elem.childNodes[1].childNodes[0].childNodes[6].style.display = 'block';
	
	elem.childNodes[2].childNodes[0].style.visibility = 'hidden';
	elem.childNodes[2].childNodes[0].style.display = 'inline';
	elem.childNodes[2].childNodes[1].style.visibility = 'visible';
	elem.childNodes[2].childNodes[1].style.display = "block";
}

function onCardMouseOut(elem) {
	elem.childNodes[0].childNodes[0].style.visibility = 'visible';
	elem.childNodes[0].childNodes[0].style.display = 'block';
	elem.childNodes[0].childNodes[1].style.visibility = 'hidden';
	elem.childNodes[0].childNodes[1].style.display = "inline";
	
	elem.childNodes[1].childNodes[0].style.backgroundPosition = '0px 0px';
	
	elem.childNodes[1].childNodes[0].childNodes[5].style.visibility = 'visible';
	elem.childNodes[1].childNodes[0].childNodes[5].style.display = 'block';
	elem.childNodes[1].childNodes[0].childNodes[6].style.visibility = 'hidden';
	elem.childNodes[1].childNodes[0].childNodes[6].style.display = 'inline';
	
	elem.childNodes[2].childNodes[0].style.visibility = 'visible';
	elem.childNodes[2].childNodes[0].style.display = 'block';
	elem.childNodes[2].childNodes[1].style.visibility = 'hidden';
	elem.childNodes[2].childNodes[1].style.display = "inline";
}
