// Public Sector Directory Widget
// Author: Greg Rogan
// Organisation: State Services Commission
// --- psdwidget.js ---
// Version: 1.0
// Description: This javascript file is to be included on any webpage that wishes to allow uses to interact with Public Sector Directory data

// specify dojo libraries to load
dojo.require("dojo.style");
dojo.require("dojo.io.XhrIframeProxy");
dojo.require("dojo.event.*");
dojo.require("dojo.io.*");
dojo.require("dojo.widget.*");
dojo.require("dojo.widget.*");
dojo.require("dojo.widget.FloatingPane");
dojo.require("dojo.widget.ContentPane");
dojo.require("dojo.widget.TabContainer");
dojo.require("dojo.widget.ComboBox");
dojo.require("dojo.widget.Button");
dojo.require("dojo.widget.TreeBasicControllerV3");
dojo.require("dojo.widget.TreeSelectorV3");
dojo.require("dojo.widget.TreeEmphasizeOnSelect");
dojo.require("dojo.widget.TreeV3");
dojo.require("dojo.widget.TreeNodeV3");


// Gobal static variables
//var webServiceServer = 'psdsldev.dev.portal.govt.nz';
//var webServiceServer = 'psdsltst.dev.portal.govt.nz';
var webServiceServer = 'psd.govt.nz';
var psdWebServiceProxy='http://'+webServiceServer+'/webservice/xip_server.html';
var psdWebServiceQuery='http://'+webServiceServer+'/webservice/feed.php';
var psdWebServiceStatus='http://'+webServiceServer+'/webservice/statuscheck.php';

var psdSearchShowOrg='http://'+webServiceServer+'/search/org.php';

//var commentServer='public.dev.portal.govt.nz';
//var commentWebServiceProxy='http://'+commentServer+'/commentService/xip_server.html';
//var commentWebService='http://'+commentServer+'/commentService/collect.cgi';

var orgPopup;
var browsePopup;
//var feedbackPopup;
var viewOrg_loaded = 'false';

var findComboMsg = 'Type or select a PSD organisation...';

// TODO: widget parameter to specify url that produces HTML about the org - passes in orgid and org name
// TODO: widget parameter to specify url that produces JSON to fill search combobox
// TODO: widget parameter to specify url that produces JSON to fill browse tree
// TODO: widget parameter to block certian agencies from being displayed

// TODO: with search box make it list maori names and search names, also make it macron insensitive - hack dojo libraries - seems to work now - need to test
function psdw_viewOrg(psdw_orgid, psdw_orgname) {

	// TODO: be able to print from this popup window
	// TODO: save state to cater for back button
	// set browse tab to show a link to the browse window

	var browseTab = (dojo.widget.byId('browseTab'));
	browseTab.setContent("<a href=\"javascript:void(0)\" onclick=\"psdw_treeView();\">Show browse tree</a>");

	//if (dojo.widget.byId('feedbackPopup')) dojo.style.setDisplay('feedbackPopup', false);
	if (dojo.widget.byId('aboutPopup')) dojo.style.setDisplay('aboutPopup', false);
	if (dojo.widget.byId('browsePopup')) dojo.style.setDisplay('browsePopup', false);
	if (dojo.widget.byId('orgPopup')) dojo.style.setDisplay('orgPopup', false);

	var tabContainer;
	var statusBar;

	if (dojo.widget.byId('orgPopup')) {
		tabContainer = dojo.widget.byId('orgPopupTabCont');
		statusBar = dojo.widget.byId('orgPopupStatusBar');
		if (tabContainer.children.length) {
			if (dojo.widget.byId('orgPopup')) dojo.style.setDisplay('orgPopup', true);
		}
	}
	else {
		var orgPopup = dojo.widget.createWidget("FloatingPane",{hasShadow:true, toggle:"explode", toggleDuration:"300", resizable:false, titleBarDisplay:false, id:'orgPopup'}, orgPopup);
		tabContainer = dojo.widget.createWidget('TabContainer',{id:'orgPopupTabCont'});
		statusBar = dojo.widget.createWidget('ContentPane',{id:'orgPopupStatusBar'});
		orgPopup.addChild(tabContainer);
		orgPopup.addChild(statusBar);
		document.getElementById("psdwidget").appendChild(orgPopup.domNode);
	}

	if (psdw_orgid && psdw_orgname) {
		
		if (dojo.widget.byId('orgPopup')) dojo.style.setDisplay('orgPopup', true);
			
		statusBar.setContent("<a href=\"" + psdSearchShowOrg + "?id=" + psdw_orgid + "\" target=\"_blank\">Show full details</a>");

		if (dojo.widget.byId('psdorg'+psdw_orgid)) { tabContainer.selectChild('psdorg'+psdw_orgid); }
		else {

			var maxlength = 30;
			// Truncate orgname to fit into tab label
			if (psdw_orgname.length >= maxlength) psdw_orgname = psdw_orgname.substring(0, maxlength-3) + "...";
	
			// TODO: put the close button on the left side, then the close button never disappears if browser font size set to larger
			var orgInfo = dojo.widget.createWidget('ContentPane', {label: psdw_orgname, closable:"true", id: 'psdorg'+psdw_orgid});
			tabContainer.addChild(orgInfo);
	
			// select this newly created tab
			// TODO: bold/italics and make bigger the text in this tab, and normalize the text in all other tabs
			tabContainer.selectTab(orgInfo, true);
	
			orgInfo.setContent('Loading...');
	
	        	dojo.io.bind({
	                	iframeProxyUrl: psdWebServiceProxy,
				url: psdWebServiceQuery,
				content: {
					type: "widgetOrgMini",
					orgid: psdw_orgid,
					ws: webServiceServer
				},
				mimetype: "text/html",
	                	load: function(type, data, evt){
					if (data != null) {
						orgInfo.setContent(data);
					}
					else {
						orgInfo.setContent('Error loading data');
					}
				},
				error: function(type, error){
					// TODO: specify type and error message in the below text
					orgInfo.setContent('Error loading data');
				}
			});
			
			dojo.event.connect(tabContainer, 'closeChild', function() {
				if (!(tabContainer.children.length)) {
					if (dojo.widget.byId('orgPopup')) dojo.style.setDisplay('orgPopup', false);
					browseTab.setContent('');
					if (dojo.widget.byId('globalTabContainer').selectedChild == 'browseTab') {
						if (dojo.widget.byId('browsePopup')) dojo.style.setDisplay('browsePopup', true);
					}
				}
			});
		}
			
		// change 'Show full details link' on change of tab
		dojo.event.connect(tabContainer, 'selectChild', function() {
			statusBar.setContent("<a href=\"" + psdSearchShowOrg + "?id=" + tabContainer.selectedChild.substring(6) + "\" target=\"_blank\">Show full details</a>");
		});

		

	}
}


function psdw_treeView() {

	// TODO: save state to cater for back button
	
	// set browse tab to show a link to the org window if there is one
	if (dojo.widget.byId('orgPopup')) {
		var browseTab = (dojo.widget.byId('browseTab'))

		if (dojo.widget.byId('orgPopupTabCont').children.length) {;
			browseTab.setContent("<a href=\"javascript:void(0)\" onclick=\"psdw_viewOrg();\">Show organisations window</a>");
		}
	}

	//if (dojo.widget.byId('feedbackPopup')) dojo.style.setDisplay('feedbackPopup', false);
	if (dojo.widget.byId('aboutPopup')) dojo.style.setDisplay('aboutPopup', false);
	if (dojo.widget.byId('orgPopup')) dojo.style.setDisplay('orgPopup', false);
	if (dojo.widget.byId('browsePopup')) { dojo.style.setDisplay('browsePopup', true); }
	else {
		var browsePopup = dojo.widget.createWidget("FloatingPane",{hasShadow:true, toggle:"explode", toggleDuration:"300", resizable:false, titleBarDisplay:false, id:'browsePopup'}, browsePopup);
	
		contentPane = dojo.widget.createWidget('ContentPane',{id:'broswePopupContentPane'});
		browsePopup.addChild(contentPane);
	
		var treeController = dojo.widget.createWidget('TreeBasicControllerV3', {widgetId:'treeController'});
		var treeSelector = dojo.widget.createWidget('TreeSelectorV3', {widgetId:'treeSelector',eventNames:{'select':'nodeSelected'}});
		var treeEmphasize = dojo.widget.createWidget('TreeEmphasizeOnSelect', {selector:'treeSelector'});
		var viewsTree = dojo.widget.createWidget('TreeV3', {toggle:'wipe',toggleDuration:500,selector:'treeSelector',listeners:['treeSelector','treeController']});
		contentPane.addChild(treeController);
		contentPane.addChild(treeSelector);
		contentPane.addChild(treeEmphasize);
		contentPane.addChild(viewsTree);
	
		document.getElementById("psdwidget").appendChild(browsePopup.domNode);
	
		// when user clicks on the Browse tab the tree will show Loading... until the data is loaded below
		viewsTree.setChildren([{title:'Loading...'}]);
	        dojo.io.bind({
	                iframeProxyUrl: psdWebServiceProxy,
			url: psdWebServiceQuery,
			content: {
				type: "widgetTreeMog"
			},
			mimetype: "text/json",
	                load: function(type, data, evt){
				if (data != null) {
					viewsTree.setChildren(data);
				}
				else {
					viewsTree.setChildren([{title:'Error loading data'}]);
				}
	                },
			error: function(type, error){
				// TODO: specify type and error message in the below text
				viewsTree.setChildren([{title:'Error loading data'}]);
			}
		});
	}
	
}


//function psdw_feedbackView() {
//
//	if (dojo.widget.byId('orgPopup')) dojo.style.setDisplay('orgPopup', false);
//	if (dojo.widget.byId('browsePopup')) dojo.style.setDisplay('browsePopup', false);
//	if (dojo.widget.byId('aboutPopup')) dojo.style.setDisplay('aboutPopup', false);
//
//	var feedbackPopup;
//	if (dojo.widget.byId('feedbackPopup')) {
//		dojo.style.setDisplay('feedbackPopup', true); 
//		feedbackPopup = dojo.widget.byId('feedbackPopup');
//	} else {
//		feedbackPopup = dojo.widget.createWidget("FloatingPane",{hasShadow:true, toggle:"explode", toggleDuration:"300", resizable:false, titleBarDisplay:false, id:'feedbackPopup'}, feedbackPopup);
//
//	}
//
//	var contentPane;
//	if (dojo.widget.byId('feedbackPopupContentPane')) {
//		contentPane = dojo.widget.byId('feedbackPopupContentPane');
//	} else {
//		contentPane = dojo.widget.createWidget('ContentPane',{id:'feedbackPopupContentPane'});
//	}
//
//	var submitButton;
//	if (dojo.widget.byId('submitButton')) {
//		submitButton = dojo.widget.byId('submitButton');
//	} else {
//		submitButton = dojo.widget.createWidget('Button', {caption: 'Submit', layoutAlign: 'left', id:'submitButton'});
//		contentPane.setContent('<p>Please enter feedback about your experience/impression or data/usablility issues regarding this widget.<br/><textarea name="comments" id="submitText" rows=8 cols=28></textarea><br/>Please include an email address or phone number if you wish to be contacted.</p>');
//		contentPane.addChild(submitButton);
//		feedbackPopup.addChild(contentPane);
//		document.getElementById("psdwidget").appendChild(feedbackPopup.domNode);
//	}
//
//        dojo.event.connect(submitButton, 'onClick', function() {
//	        dojo.io.bind({
//	                iframeProxyUrl: commentWebServiceProxy,
//			url: commentWebService,
//			content: {
//				comment: document.getElementById('submitText').value,
//				app: "psdwidget",
//				OS: BrowserDetect.OS,
//				Browser: BrowserDetect.browser + ' ' + BrowserDetect.version,
//				URL: location.href
//			},
//			mimetype: "text/html",
//	                load: function(type, data, evt){
//				if (data != null) {
//					//contentPane.setContent(data);
//					dojo.widget.byId('feedbackTab').setContent('Thankyou for your feedback');
//					contentPane.setContent('<p>'+data+'</p><p>To send more feedback at any time, please click the Feedback tab.</p>');
//				}
//				else {
//					contentPane.setContent('Error processing submisison, please try again latter. Thankyou');
//				}
//	                },
//			error: function(type, error){
//				// TODO: specify type and error message in the below text
//				contentPane.setContent('Error processing submisison, please try again latter. Thankyou');
//			}
//		});
//	});
//}


function psdw_aboutView() {

	if (dojo.widget.byId('orgPopup')) dojo.style.setDisplay('orgPopup', false);
	if (dojo.widget.byId('browsePopup')) dojo.style.setDisplay('browsePopup', false);
//	if (dojo.widget.byId('feedbackPopup')) dojo.style.setDisplay('feedbackPopup', false);

	if (dojo.widget.byId('aboutPopup')) {
		dojo.style.setDisplay('aboutPopup', true); 
	} else {
		var aboutPopup = dojo.widget.createWidget("FloatingPane",{hasShadow:true, toggle:"explode", toggleDuration:"300", resizable:false, titleBarDisplay:false, id:'aboutPopup'}, aboutPopup);
		var contentPane = dojo.widget.createWidget('ContentPane',{id:'aboutPopupContentPane'});
		var aboutContent = '<b>Please use these links to find out more about the Public Sector Directory (PSD)</b>' +
		'<p><ul>' +
		'<li><a href="http://toolkit.psd.govt.nz" target="_blank">http://toolkit.psd.govt.nz</a> explains how it works and its various uses.</li>' +
		'<li><a href="http://psd.govt.nz" target="_blank">http://psd.govt.nz</a> is a traditional web search interface.</li>' +
		'<li><a href="http://psd.govt.nz/mailmerge" target="_blank">http://psd.govt.nz/mailmerge</a> is a mail-merge facility.</li>' +
		'<li><a href="http://toolkit.psd.govt.nz/contact.php" target="_blank">http://toolkit.psd.govt.nz/contact.php</a> to contact the PSD team.</li>' +
		'</ul></p>';
//		'</ul></p>' +
//		'Please be sure to provide feedback by going to the Feedback tab';
		contentPane.setContent(aboutContent);
		aboutPopup.addChild(contentPane);
		document.getElementById("psdwidget").appendChild(aboutPopup.domNode);
	}
}

function psdw_init(){

	BrowserDetect.init();

	// disallow browser that are known to have problems displaying the widget to load it
	if ( (BrowserDetect.browser == "Safari")  && (BrowserDetect.version < "500") ) {
		return 0;
	}

	// TODO: test dojo can load properly - especially important when dojo libraries
	//  	 are loaded remotely

	// Use psd health/status check page to test if LDAP server / webservice is up - if not don't then load the widget
	// TODO: decide - should this instead display error on widget with a link to the HTML based psdsearch?
	// TODO: IE 7 has a problem somewhere in here
	dojo.io.bind({
                iframeProxyUrl: psdWebServiceProxy,
                url: psdWebServiceStatus,
		mimetype: "text/plain",
		handle: function(type, data, evt) {
			if (type == 'load') {
				if (data.match("PASS")) {
					webServicePass();
				}
			} else if (type == 'error') {
				alert('PSD webservice error: ' + data);
			} else {
				alert('PSD webservice error');
			}
		}
	});
}


function webServicePass() {

	// modify the DOM to remove all plain HTML under psdwidget and repace with widget stuff
	var psdwidget = document.getElementById("psdwidget");
	while (psdwidget.childNodes[0]) {
		psdwidget.removeChild(psdwidget.childNodes[0]);
	}

	// create the tab container
	var tabContainer = dojo.widget.createWidget('TabContainer', {id: 'globalTabContainer'});
	psdwidget.appendChild(tabContainer.domNode);

	// create the tabs
	var findLayoutCont = dojo.widget.createWidget('LayoutContainer', {label: 'Find', layoutChildPriority: 'left-right', id: 'findTab'});
	var browseTab = dojo.widget.createWidget('ContentPane', {label: 'Browse', id: 'browseTab'});
//	var feedbackTab = dojo.widget.createWidget('ContentPane', {label: 'Feedback', id: 'feedbackTab'});
	var aboutTab = dojo.widget.createWidget('ContentPane', {label: '?', id: 'aboutTab'});
	tabContainer.addChild(findLayoutCont);
	tabContainer.addChild(browseTab);
//	tabContainer.addChild(feedbackTab);
	tabContainer.addChild(aboutTab);

	// create find tab widgets
	var findComboBox = dojo.widget.createWidget('ComboBox', {autoComplete:false, layoutAlign: 'left', id: 'findComboBox'});
	findLayoutCont.addChild(findComboBox);
	
	findComboBox.setValue('Loading...');
	findComboBox.disable();
        dojo.io.bind({
                iframeProxyUrl: psdWebServiceProxy,
                url: psdWebServiceQuery,
		content: {
			type: "widgetComboOrgs"
		},
		mimetype: "text/json",
                load: function(type, data, evt){
			if (data != null) {
                        	findComboBox.dataProvider.setData(data);
				// ensure can see all the list and substring searching
				findComboBox.dataProvider.searchLimit = 2000;
			       	findComboBox.dataProvider.searchType = 'SUBSTRING';
				findComboBox.setValue(findComboMsg);
				findComboBox.enable();
			}
			else {
				// TODO: provide link to psd.govt.nz search
				findComboBox.setValue('Error loading data');
			}
                },
		error: function(type, error){
			// TODO: provide link to psd.govt.nz search
			// TODO: specify type and error message in the below text
			findComboBox.setValue('Error loading data');
		}
	});

	// set focus to tab container
	tabContainer.selectChild('findTab');

	// TODO: if user types a non-existant entry, ensure focus is still on text entry - IE (only) bug means it slips away
	// so when backspace is hit the broswer get that keystroke, not the textbox - bad!


	// if focus is set to combobox and instruction message is there, remove instruction message
	dojo.event.connect(findComboBox, '_onFocusInput', function() {
		if (findComboBox.getValue() == findComboMsg) {
			findComboBox.setValue('');
			findComboBox._startSearch("");
		}
	});

	// open org on combobox selection
	dojo.event.connect(findComboBox, '_selectOption', function() {
		findComboBox._hideResultList();
		psdw_viewOrg(findComboBox.comboBoxSelectionValue.value, findComboBox.getValue());
		tabContainer.selectChild('findTab');
	});


	// TODO: loading bar to show browse tree loading - more elegant than using the 'Loading...' node used above
	// when user clicks the browse tab load tree data if not already loaded
	dojo.event.connect(tabContainer, 'selectChild', function() {
		// check which tab has been clicked
		if (tabContainer.selectedChild == 'findTab') { // find tab
			psdw_viewOrg();
		}
		if (tabContainer.selectedChild == 'browseTab') { // browse tab
			psdw_treeView();
		}
//		if (tabContainer.selectedChild == 'feedbackTab') { // feedback tab
//			psdw_feedbackView();
//		}
		if (tabContainer.selectedChild == 'aboutTab') { // about tab
			psdw_aboutView();
		}
	});

	
	dojo.event.topic.subscribe("nodeSelected", function(message) {
		if (message.node.id && message.node.title) psdw_viewOrg(message.node.id, message.node.title);
	});

}

var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};


dojo.addOnLoad(psdw_init);
