dojo.declare("com.mgh.GoogleSearch", null, {
	constructor : function (configParams){
		this.xmlDoc; 
		this.categories = ['All results','Physicians','Conditions and treatments','Centers and services','Research and clinical trials','News and events','Multimedia resources','Education and training','Career opportunities','About Mass General','Other'];
		this.categoriesResults = new Array();
		this.categoryList = '';
		this.recordCount = 0;
		this.currentPage = 0;
		
		/********************************** Default Variables *****************************************/
		//accept a json object with all necessary constructor values
		this.queryParams = configParams;
		this.query = '';
		
		//get data
		fadeOutNode('resultsColumn');
		fadeOutNode('categories1');	
		this.getXmlString();		
	},
	
	updateQuery : function()
	{
		var m = this.queryParams;
		//this.query = m.href + "?q=" + m.q + "&site=" + m.site + "&num=" + m.numPerPage + "&req=" + m.req + '&st=' + m.st;
		this.query = m.href + "?q=" + m.q + "&site=" + m.site + "&num=" + m.numPerPage + "&req=" + m.req + '&st=' + m.st + '&center=' + m.center;
	},    

	getXmlString : function()
	{
		this.updateQuery();
		dojo.xhrGet({
			url: this.query,
			handleAs: "text",
			load: function(response, ioArgs){
				//outside function listening for the data to be ready
				searchDataReady(response);
				return response;
			},
			error: function(response, ioArgs){
				alert("An error occurred, with response: " + response);
				return response;
			}
		});		
	},
    
	loadXmlString : function(txt) 
	{
		var Doc;
		var parser;
		try //Internet Explorer
		{
			Doc = new ActiveXObject("Microsoft.XMLDOM");
			Doc.async = "false";
			Doc.loadXML(txt);
			return(Doc); 
		}
		catch(e)
		{
			try //Firefox, Mozilla, Opera, etc.
			{
				parser = new DOMParser();
				Doc = parser.parseFromString(txt,"text/xml");
				return(Doc);
			}
			catch(e) {console.log(e.message)}
		}
		return(null);
	},
	
	reset : function (){
		this.queryParams.req = '';
		this.getXmlString();
	},
	
	getRecordCount : function (){
		try{
			
			var nextPage = parseInt(this.xmlDoc.getElementsByTagName("RES")[0].getAttribute("EN"));
			var numberPerPage = this.queryParams.numPerPage;
			this.recordCount = parseInt(this.xmlDoc.getElementsByTagName("M")[0].childNodes[0].nodeValue);
	        //first make them less than 1000
			this.recordCount > 1000 ? this.recordCount = 1000 : this.recordCount = this.recordCount;
			//and then
			if(nextPage < this.recordCount && nextPage > numberPerPage-1){
				this.recordCount = this.recordCount;
			} else {
				this.recordCount = nextPage;	
			}
			/* misspelling of categories will throw off the code above. Otherwise, results match available results. code below is safe.
			this.recordCount = parseInt(this.xmlDoc.getElementsByTagName("M")[0].childNodes[0].nodeValue);
	        this.recordCount > 1000 ? this.recordCount = 1000 : this.recordCount = this.recordCount;	*/		
		} catch (e) {
			this.recordCount = 0;
		}		
	},
	
	getCategories : function ()
	{		
		var MT = this.xmlDoc.getElementsByTagName("MT");
		var i=1;
		var x=0;
		var y=0;
		var categoryElementCount = 0;
		var categoryName = '';
		var multipleCategories;
		
		for (i; i < this.categories.length; i++)
		{
			var elementPositions = new Array();
			for (x; x < MT.length; x++){
				categoryName = MT[x].getAttribute("V");
				multipleCategories = categoryName.split(',');
				for (y=0; y < multipleCategories.length; y++){
					if (multipleCategories[y].toLowerCase() == this.categories[i].toLowerCase()){
						elementPositions[categoryElementCount] = x;
						categoryElementCount += 1;				
					}
				}
			}
			this.categoriesResults[this.categories[i]] = elementPositions;
			elementPositions = null;
			categoryElementCount = 0;
			x=0;	
		}
	},
	
	displayCategories : function()
	{
		this.getCategories();
		var recordCount = this.xmlDoc.getElementsByTagName("M")[0].childNodes[0].nodeValue;
		var percent = 0;
		var numberOfResults = 0;
		var output = '<h3>Refine by Category</h3>';
        output += '<ul>';
        output += '<li><a href="#" onclick="displayFilteredResults(\'\')">' + this.categories[0] + ' (' + recordCount + ')</a></li>';
		for (i=1; i<this.categories.length; i++){
			numberOfResults = this.categoriesResults[this.categories[i]].length;
			percent = numberOfResults/this.queryParams.numPerPage;
			
			if (numberOfResults > 0){
				//output += '<li><a href="#">' + this.categories[i] + ' (' + numberOfResults + ')</a></li>';
				output += '<li><a href="#" onclick="displayFilteredResults(\'' + this.categories[i] 
				+ '\')">' + this.categories[i] 
				+ ' (' + Math.ceil(recordCount*percent) + ')</a></li>';
			} else {
				output += '<li>' + this.categories[i] + '</li>';
			}
		}
		output += '</ul>';	
		return output;
	},
	
	displayCategoryColumns : function (){
		this.getCategories();
		var catName = '';
		var inactiveCat = '';
		var recordsPerCategory = 0;
		var percent = 0;
		var numberOfResults = 0;
		var counter = 0;		
		var rows=0;
		var linksToDisplay = 4;
		var i;
		var output = '<h3>View:</h3>';
		output += '<table width="100%" border="0" cellspacing="5" cellpadding="5" valign="top">';
        output += '<tr>';
        
        for (var x=0; x < 3; x++){
	    	output += '<td width="33%" valign="top">';
	    	output += '<ul>';
	    	if (counter == 0){
				output += '<li id="' + this.categories[0] + '"><a href="#" onclick="displayFilteredResults(\''+ this.categories[0] + '\',' +  this.recordCount + ')">' + this.categories[0] + ' (' + this.recordCount + ')</a></li>';	    		
	    	}   	
	        for (i=rows; i < linksToDisplay; i++){
	        	try{
	        		numberOfResults = this.categoriesResults[this.categories[counter]].length;
					percent = numberOfResults/this.queryParams.numPerPage;  
					catName = this.categories[counter];
					inactiveCat = '<span>' + catName + '</span>';
					
					if (numberOfResults > 0){
						if (this.recordCount <= this.queryParams.numPerPage){
							recordsPerCategory = numberOfResults;
						} else {
							recordsPerCategory = Math.ceil(this.recordCount*percent);
						}											
						/* with record count
						output += '<li id="' + catName + '"><a href="#" onclick="displayFilteredResults(\'' 
						+ catName + '\',' + recordsPerCategory +')">' + catName 
						+ ' (' + recordsPerCategory + ')</a></li>';						
						*/
						// widthout
						output += '<li id="' + catName + '"><a href="#" onclick="displayFilteredResults(\'' 
						+ catName + '\',' + recordsPerCategory +')">' + catName 
						+ '</a></li>';							
					} else {
						output += '<li id="' + catName + '">' + inactiveCat + '</li>';
					}

	        	} catch (e) {
	        		//console.log(counter + ' ' + e);
	        		//break;
	        	}
	        	counter += 1;
	        }
	    	output += '</ul>';
	    	output += '</td>';	        
        }
        output += '</tr>';
        output += '</table>';
        return output;	
	},
	
    displayResults : function ()
    {	
    	if (this.recordCount > 0){
			var highlighted = this.xmlDoc.getElementsByTagName("GM");
			var hContainer = '<div id="highlightedResults">%1</div>';
			var highlightedLink = '<div id="result"><a href="%1" class="bold">%2</a><br><a href="%3">%4</a></div>';
			var gmLink = '';
			var gmDesc = '';
			var recordList = this.xmlDoc.getElementsByTagName("R");  
			var mimeType = '';
	        var results = '';
	        var url = '';
	        var title = '';
	        var description = '';
			var recordNumber = '';
			var pageTitle = /^Massachusetts General Hospital:{1}/;
	        var count = recordList.length;
			var regEx = /<b>...<\/b>/g;
			var breaks = /<br>/g;
			var trimmed = '';		        
			var childNodeCount = 0;
			
			if(highlighted.length > 0){
				if(this.queryParams.st == '0'){
					for (var x=0; x < highlighted.length; x++){
						gmLink = highlighted[x].childNodes[0].childNodes[0].nodeValue;
						gmDesc = highlighted[x].childNodes[1].childNodes[0].nodeValue;
						results += this.format(highlightedLink, gmLink, gmDesc, gmLink,gmLink);
					}
					results = this.format(hContainer, results);
				}
			}
			
			if (count > 0){
				results += '<div id="googleResults">';
				
				for (var i = 0; i < count; i++)
				{
	                try
	                {
						title = this.getNodeText(recordList[i],'T');
						url = this.getNodeText(recordList[i],'U');
						description = this.getNodeText(recordList[i],'S');
						recordNumber = recordList[i].getAttribute('N');
						mimeType = recordList[i].getAttribute("MIME");							
						
						if (mimeType != 'null') {
							switch  (mimeType) {
								case 'application/pdf' :
									mimeType = '[pdf]';
									break;
								
								case 'application/msword' :
									mimeType = '[doc]';
									break;
									
								default :
									mimeType = '';
									break;
							}
							
						}					

						title = title.replace(pageTitle,'');						
						results += this.searchResult(url,title,description,recordNumber,mimeType);
			}
	               catch(e)
	               {
	                	console.log(i + ' ' + e);
	               }
					//console.log(i + ' ' + title);
				}
			}
			results += '</div>';
		    return results;
    	} else {
    		   		
   			var error = '<div id="googleResults"><ul><li>';
		    error += '<ul id="resultItems">';
		    error += '<li id="resultUrl">';
		    
		   try {
		    	var wrongTerm = this.xmlDoc.getElementsByTagName("Q")[0].childNodes[0].nodeValue;
		    	var suggest = this.xmlDoc.getElementsByTagName("Suggestion")[0];
		    	var suggestDisplay = suggest.childNodes[0].nodeValue;
		    	var suggestText = suggest.getAttribute("q");

			var suggestLink = '';

			if (this.queryParams.center==undefined)
				{
			    	suggestLink = '<a href="search.aspx?st=0&q='+ suggestText + '">' + suggestDisplay + '?</a>';
				}
			else
				{
			    	suggestLink = '<a href="search.aspx?st=0&q='+ suggestText + '&center=' + this.queryParams.center + '">' + suggestDisplay + '?</a>';
				}


		    	error += 'No Results Available for: <strong>' + wrongTerm + '</strong>. ' +
		    			 'Did you mean ' + suggestLink;
		   } catch(ex){
		   		error += 'No Results Available for: <strong>' + this.queryParams.q + '</strong>';		    	
		   }
		    
		    error += '</li>';
		    error += '</ul>';
		    error += '</div>';
    		return error;
    	}
	},

	getNodeText : function (node,name)
	{
		var text = '';
		try {
			for (var i=0; i<node.childNodes.length; i++){
				if (node.childNodes[i].nodeName == name){
					text = node.childNodes[i].childNodes[0].nodeValue;
					break;
				}
			}
		} catch (e) {
			
		}
		return text;
	},
	
	searchResult : function (url,title,description,recordNumber,mimeType){
		var regEx = /<b>...<\/b>/g;
		var breaks = /<br>/g;
		var trimmed = '';		
		var results = '';	
		if (title==''){

		} else {
			results = '<div id="result">';	
			results += '<ul id="resultItems">';
			results += '<li id="resultUrl">';
			mimeType != '' ? results += '<span class="mimeType">' + mimeType + '&nbsp</span>' : results += mimeType;
			results += '<a href="' + url + '">';
			results += title;
			results += '</a>';
			results += '</li>';
			if (description != '')
			{
				trimmed = description.replace(regEx,'');
				trimmed = trimmed.replace(breaks,'');
				results += '<li id="resultDescription">';
				results += trimmed;
				results += '</li>';
			}
			results += '<li id="resultFullUrl">';
			results += '<a href="' + url + '">';
			if (url.length >= 80)
			{
				results += url.substring(0, 80) + '...';
			}
			else
			{
				results += url;
			}
			results += '</a>';
			results += '</li>';
			results += '</ul>';         
			results += '</div>';			
		}
		return results;
		
	},
	
    displayFilteredResults : function (category)
    {
		var urlList = this.xmlDoc.getElementsByTagName("U");
		var titleList = this.xmlDoc.getElementsByTagName("T");
		var descriptionList = this.xmlDoc.getElementsByTagName("S");
		var recordNumberList = this.xmlDoc.getElementsByTagName("R");
		var mimeType  = '';
        var results = '';
        var url = '';
        var title = '';
        var description = '';
		var recordNumber = '';
		var pageTitle = /^Massachusetts General Hospital:{1}/;
				
        var resultsArray = this.categoriesResults[category];
        var count = resultsArray.length;

        var current = 0;
        
		results += '<div id="googleResults">';
		var regEx = /<b>...<\/b>/g;
		var breaks = /<br>/g;
		var trimmed = '';

		for (var i = 0; i < count; i++)
		{
			current = parseInt(resultsArray[i]);			
            try
            {
                url = urlList[current].childNodes[0].nodeValue;
                title = titleList[current].childNodes[0].nodeValue;
                description = descriptionList[current].childNodes[0].nodeValue;
				mimeType = recordNumberList[current].getAttribute("MIME");
                
                title = title.replace(pageTitle,'');	                

                results += '<div id="result">';

                results += '<ul id="resultItems">';
                results += '<li id="resultUrl">';
                results += '<b>' + (i+1).toString() + '.</b> ';
                results += '<a href="' + url + '">';
                results += title;
                results += '</a>';
                results += '</li>';
                if (description != '')
                {
                	trimmed = description.replace(regEx,'');
                	trimmed = trimmed.replace(breaks,'');
                    results += '<li id="resultDescription">';
                    results += trimmed;
                    results += '</li>';
                }
                results += '<li id="resultFullUrl">';
                results += '<a href="' + url + '">';
                //parse the url at a reasonable length.
                if (url.length >= 80)
                {
                    results += url.substring(0, 80) + '...';
                }
                else
                {
                    results += url;
                }
                results += '</a>';
                results += '</li>';
                results += '</ul>';         
                results += '</div>';
            }
            catch(e)
            {
            	console.log(i + ' ' + e);
            }
		}
		results += '</div>';
		urlList = null;
		titleList = null;
		descriptionList = null;
		recordNumberList = null; 		
	    return results;
	},
	
	createPaging : function ()
	{
		//console.log(arguments.callee.caller);
		if (this.recordCount > 0){
			var RES = this.xmlDoc.getElementsByTagName("RES");
	        var startPage = parseInt(RES[0].getAttribute("SN"));
	        var nextPage =  parseInt(RES[0].getAttribute("EN"));
	        var numberOfPages = 0;
			var rem = 0;	        
	        var previousPage = 0;
	        var numberPerPage = this.queryParams.numPerPage;
	        var numberOfResults = this.getNumberOfResults(startPage,nextPage,numberPerPage);
			
			if (startPage > numberPerPage){
				previousPage = (startPage - numberPerPage) - 1;
			} else {
				previousPage = 0;
			}
	       
	        var paging = '<div class="resultNumber" id="numberOfResults">';
	       	paging +=  numberOfResults + '</div>';                      
	        paging += "<ul id=\"googlePaging\">";
			
			if(startPage!=1){
	           paging += '<li id="prevpage"><a href="#" onclick="changePage(\'' + previousPage.toString() + '\')">< Previous</a></li>';
			}
			else{
				paging += '';
			}

	        if (nextPage < (startPage + numberPerPage)-1){
	        	numberOfPages = Math.ceil(nextPage/numberPerPage);
	        } else {
	        	numberOfPages = Math.ceil(this.recordCount/numberPerPage);
	        }
	        
	        rem = this.recordCount % numberPerPage;
	        
	        if(numberOfPages > 20){
	            numberOfPages = 20;
	        }        
	
	        for (var i = 1; i < (numberOfPages + 1); i++)

	        {
	            paging += '<li id="page' + i.toString() +'">';
	            if ((((i-1) * numberPerPage)+1) == startPage)
	            {
	                paging += "&nbsp;<b>" + i.toString() + "</b>";
	            }
	            else
	            {
	                paging += '<a href="#" onclick="changePage(\'' + ((i - 1) * numberPerPage).toString() + '\')">' + i.toString() + '</a>';
	               
	            }
	            paging += "</li>";
	        }
			//console.log(nextPage + ' ' + this.recordCount + ' ' + numberPerPage);
			if(nextPage < this.recordCount && nextPage > numberPerPage-1){
					paging += '<li class="nextPage"><a href="#" onclick="changePage(\'' + nextPage.toString() + '\')">Next ></a></li>';
			}
			else
			{
				paging += '';
			}
			paging += "</ul>"; 
			return paging;
		} else {
			return "";
		}
	},	
	
	getNumberOfResults : function(start,nextPage,numberPerPage){
		var total = this.recordCount;
		var end;
		var output = '';
		if (total > 0){
			if (total < this.queryParams.numPerPage){
				end = start + (total-1);
			} else if ((start + (this.queryParams.numPerPage - 1)) < this.recordCount) {
				end = start + (this.queryParams.numPerPage-1);	
			} else {
				end = this.recordCount;
			}
			output = '<strong>';
			output += start;
			if (start < total){
				output += ' to ';
				output += end;
			}
			output += '</strong>';
			if(nextPage < this.recordCount && nextPage > numberPerPage-1){
				output += ' of ';
				output += '<strong>' + total + '</strong>';
			}
			
			output += ' Results';
		} else {
			//output = '<strong>No Results Found</strong>';	
			output = '';
		}
		this.currentPage = start;
		return output;			
	},	

	nextPage : function () {
		var page = this.currentPage + this.queryParams.numPerPage;
		console.log(this.currentPage + ' ' + page);
		if (page < this.results){
			this.gotoPage(page);
		}	
		console.log('next page ' + this.currentPage + ' ' + page)
	},
	
	previousPage : function(){
		var page = this.currentPage - this.queryParams.numPerPage;
		if (page < 0){
			page = 0;
			//this.currentPage = 0;
		}
		this.gotoPage(page);
		//console.log('previous page ' + this.currentPage + ' ' + page);
	},
	
	gotoPage : function (start){
		var page = this.displayResults();
		this.currentPage = start;
		console.log('content ' + this.currentPage + ' ' + page)
		var paging = this.createPaging(start);
		dojo.byId('browseResults').innerHTML = page;	
		dojo.byId('pagingTop').innerHTML = paging;
		dojo.byId('pagingBottom').innerHTML = paging;			
	},	
	
	format : function(string) {   
		var args = arguments;   
		var pattern = new RegExp("%([1-" + arguments.length + "])", "g");   
		return String(string).replace(pattern, function(match, index) {   
			return args[index];   
		});   
	},    
    
	/********************************** filters *****************************************/
	updateFilter : function (category){
		var output = '<H3>View:</H3>';
		output +='<ul>'
		output += '<li id="' + category + '" class="active"><strong>' + category + '</strong></li>';
		output += '<li><a href="#" class="goBack" onclick="removeFilter()">Show All Categories</a></li>';
		output += '</ul>';
		return output;
	}	
});

