/* ui_module.js
 * A collection of javascript functions that can be run in the foreground by the User Interface.
 * This module calls meisosis, akin and synthesis modules. 
 * It is not called by other modules. 
 */

	function display_array(rebuild) {
		function depth_to_pixels (depth){
			// convert a cTag's depth to the diameter of its object in the scope
				return depth * 2 +10 ;
			};

		if (rebuild) {
			var slicearr = function (a,b) {return a.slice(0,b);};
			var axes 		= +document.getElementById('ScopeAxes').value;
			var focusdiam 	= +document.getElementById('ScopeFocusDiam').value;

			var max = displaycTags[displaycTags.length -1].distance;
			var min = displaycTags[0].distance;
							
			glamsetstr[glamsetstr.length]="<charts><values><max>"+ max +"</max></values></charts>";
			if (document.getElementById('Check_ScopeScale').checked === true) {
//alert("checked.  cTagArr " +cTagArr.length + " displaycTags " +displaycTags.length)
				focus_cTag.distance = min ;
				glamsetstr[glamsetstr.length]="<charts><values><min>"+ min +"</min></values></charts>";
//				glamsetstr[glamsetstr.length]="<settings><graphs><graph gid='0'><bullet_size>"+ depth_to_pixels(focus_cTag.depth)  +"</bullet_size></graph></graphs></settings>";
//				glamsetstr[glamsetstr.length]="<settings><graphs><graph gid='0'><bullet_size>"+ focusdiam  +"</bullet_size></graph></graphs></settings>";
				so.addVariable("chart_data", plot_all(axes, displaycTags, null));
			}
			else {
//alert("unchecked.  cTagArr " +cTagArr.length + " displaycTags " +displaycTags.length)
				focus_cTag.distance = 0;
				so.addVariable("chart_data", plot_all(axes, displaycTags, focus_cTag));
			}
				
		}
		so.write("flashcontent");
	}

	function plot_all (axes, cTags, focus_cTag){

		var axes_string 	= "";
		var focus_string 	= "";
		var values_string 	= "";
		var axis;
		var cTag;

		if (focus_cTag !== null) {
			focus_string =	"<value"+
							" xid='0'"+
							" bullet='"					+focus_cTag.shape+		"'"+
							" bullet_color='"			+focus_cTag.colour+		"'"+
							" description='"			+focus_cTag.id+';'+focus_cTag.description+"'"+
							" url='"					+focus_cTag.uri+		"'>"+
								focus_cTag.distance+"</value>";
		}

		for (axis=0; axis < axes && axis < cTags.length; axis++)
		{
			cTag = cTags[axis];
			cTag.axis = axis;
			axes_string 	= axes_string 	+ add_axis(axis);
			if (cTag.shape && cTag.shape.name !== 'shape') // && is guard for undefined array element
			{ 
				values_string = values_string + add_bullet(	cTag );
			}
		}
		
		data_xml_string = "<chart>"+
							"<axes>"+axes_string+
							"</axes>"+
							"<graphs>"+
								"<graph gid='0'>"+
								focus_string+
								"</graph>"+
								"<graph gid='1'>"
								+values_string+
								"</graph>"+
							"</graphs>"+
						"</chart>";				
//alert (data_xml_string)
		return data_xml_string;
}

  function drop(target, event){
  	/* Process a cTag object that has been dropped on the Scope area.
  	 * The object should conform to the expectations of the 
  	 */
 	try {		
		var DraggedData;
		var DataFormat;
		var DataSource;
		var doc;

		if ('returnValue' in event) event.returnValue = false;	// Internet Explorer
		
		function getData(DataTrx, event) {
			DraggedData = event.dataTransfer.getData(DataTrx);
			if (DraggedData === null ||DraggedData === "" ||DraggedData === false) return null;	
			else return DraggedData;
		};
	//	if ((DraggedData = getData('url', event)) === null) -- IE8 not working with 'url'. see example http://msdn.microsoft.com/en-us/library/ms536744(VS.85).aspx
		if ((DraggedData = getData('text', event)) === null) // perform synthesis
		{
			DataFormat = 'SYNTH'; 	DataSource = 'local';
		}
		else {
			
			// More robust parsing is needed here.
			if (DraggedData.substr(0, 8) === '{"cTag":') {
				DataFormat = 'JSON'; DataSource = 'local';
			}
			else 
				if (DraggedData.substr(DraggedData.length - 5, 5) === '.json') { // note: case sensitive file naming. 
					DataFormat = 'JSON';
					DataSource = 'local';
				}
				else 
					if (DraggedData.substr(0, 5) === '<cTag') {
						DataFormat = 'XML';
						DataSource = 'local';
					}
					else 
						if (DraggedData.substr(DraggedData.length - 4, 4) === '.xml') {
							DataFormat = 'XML';
							DataSource = 'local';
						}
						else {
							DataFormat = 'SYNTH'; 	DataSource = 'local';	// IE
						}

		return;	
		}
	}
	catch (e) {
		alert ("error : " +e);
	}
   }
	
   function hover(target, e){
   	alert("hover area dropped");
   }


function loadXMLDoc(dname) 
{
try //Internet Explorer
  {
  xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
  }
catch(e)
  {
    xmlDoc=document.implementation.createDocument("","",null);
  }
try 
  {
  xmlDoc.async=false;
  xmlDoc.load(dname);
  return(xmlDoc);
  }
catch(e) {alert('loadXMLDoc exception : '+e&&e.message)}
return(null);
}
   
	 	 
	function loadXMLString(txt) 
	{
		try //Internet Explorer
		  {
		  xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
		  xmlDoc.async="false";
		  xmlDoc.loadXML(txt);
		  return(xmlDoc); 
		  }
		catch(e)
		  {
		  try //Firefox, Mozilla, Opera, etc.
		    {
		    parser=new DOMParser();
		    xmlDoc=parser.parseFromString(txt,"text/xml");
		    return(xmlDoc);
		    }
		  catch(e) {alert('loadXMLString exception : '+e&&e.message)}
		  }
		return(null);
	}

// extract XML elements of cTag 
	function traverse(tree) {
		var treeobj;
	        if(tree.hasChildNodes()) {
				document.write('<ul><li>');
				document.write('<b>'+tree.nodeName+'</b>');
				var nodes=tree.childNodes.length;
				for (var i = 0; i < tree.childNodes.length; i++) {
					traverse(tree.childNodes[i]);
				}
				document.write('</li></ul>');
	        }
			else {
				if(tree.nodeValue) document.write('<b> :'+tree.nodeValue+'</b>');				
			}
			return treeobj;
  	}
	
	
	/**
 * Convert XML to JSON Object
 * @param {Object} XML DOM Document
 */
xml2Json = function(xml) {
 var obj = {};
 
 if (xml.nodeType == 1) { // element
  // do attributes
  if (xml.attributes.length > 0) {
   obj['@attributes'] = {};
   for (var j = 0; j < xml.attributes.length; j++) {
    obj['@attributes'][xml.attributes[j].nodeName] = xml.attributes[j].nodeValue;
   }
  }
  
 } else if (xml.nodeType == 3) { // text
  obj = xml.nodeValue;
 }
 
 // do children
 if (xml.hasChildNodes()) {
  for(var i = 0; i < xml.childNodes.length; i++) {
   if (typeof(obj[xml.childNodes[i].nodeName]) == 'undefined') {
    obj[xml.childNodes[i].nodeName] = xml2Json(xml.childNodes[i]);
   } else {
    if (typeof(obj[xml.childNodes[i].nodeName].length) == 'undefined') {
     var old = obj[xml.childNodes[i].nodeName];
     obj[xml.childNodes[i].nodeName] = [];
     obj[xml.childNodes[i].nodeName].push(old);
    }
    obj[xml.childNodes[i].nodeName].push(xml2Json(xml.childNodes[i]));
   }
   
  }
 }

 return obj;
};

	function add_bullet(cTag)
		{
//alert ('add_bullet ' +cTag.id)
			var bullet_size = normalise_bullet_size(cTag.depth) ;	

			// XML as input to AMcharts
			return	"<value"+
						" xid='"			+cTag.axis+			"'"+
						" bullet_color='"	+cTag.colour		+"'"+
						" bullet='"			+cTag.shape			+"'"+
						" bullet_size='"	+bullet_size		+"'"+
						" url=''"+
//						" url='"			+cTag.uri			+"'"+	//prevent automatic page change on click bullet
						" description='"	+cTag.id+';'+cTag.description	+"'>"+	cTag.distance+
					"</value>";
		};

	function normalise_bullet_size(depth){
		var MaxDiam = document.getElementById("ScopeMaxDiam").value;
		var MinDiam = document.getElementById("ScopeMinDiam").value;
		var MaxDepth = 15	// parameter specified by Akinity version 0.1 		
			return Math.round((MaxDiam - MinDiam) * (depth / MaxDepth) + +MinDiam ) ;	
		}

	function add_axis (axis){
			return "<axis xid='"+axis+"'>"+axis+"</axis>" ;
		};


	function show_cTag_details (focus_cTag){
		/* Display details of the in-focus cTag 
		 */
			document.getElementById("FocuscTagBindingID").value = focus_cTag.binding_id;
			document.getElementById("FocuscTagDesc").value 		= focus_cTag.description;
			document.getElementById("FocuscTagVersion").value 	= focus_cTag.version;
			document.getElementById("FocuscTagDepth").value 	= focus_cTag.depth;
			document.getElementById("FocuscTagBreadth").value 	= focus_cTag.breadth;
			document.getElementById("FocuscTagCreated").value 	= focus_cTag.create_dt;
								
			update_culture(operativeCulture, focus_cTag.binding_id);
		};

	function update_culture (operativeCulture, focus_cTag_id){

			var mv = init_mv(); // create module variable structue and default values
			mv.dest.module 		= 'db';
			mv.dest.action 		= 'update_culture';
			mv.dest.ID 			= dbworker.ID
			mv.cu.name 			= operativeCulture;
			mv.cu.focus_id		= focus_cTag_id;

			trx_caller (wp, mv, null, null, mv.dest.ID);
				
		};


function init_mv()
{
	/* Initialise the object structure of module variable in preparation for communication with a background worker (db, meiosis, synthesis or akin)
	 * Set values for those parameters which are not transaction specific.
	 */	
	var mv;
	var version 		= document.getElementById("ConcAkinityVers").value;
	var wkrthrottle		= +document.getElementById("GearsWorkers").value;	
	var def_breadth 	= +document.getElementById("ConcDefBreadth").value;
	var bv_type 		= 'text'
	var steps			= def_breadth - (mos_breadth ||8);
	
	try{
		var mv = {
			init: {
				parent: null,
				synthScript: synworker.script,
				wkrthrottle: wkrthrottle
			},
			api: {
				flickr: {	Key : null,
							URL : null
						}
			},
			ak: {	// akin module
				low : lib_set_binding (version, def_breadth, null, null, bv_type, organelle, mos_breadth, null, null, steps, synworker.ID),
				high : lib_set_binding (version, def_breadth, null, null, bv_type, organelle, mos_breadth, null, null, steps, synworker.ID),
				result : {
					bits			: null,
					length			: null,
					lot				: null,
					distance		: null,
					expire			: null		// stop seeking new akin after this time
				},
			},
			ba : set_batch (false, false, []),
			cu: {
				name				: null,	
				focus_id			: null	
			}, 
			se: {	// settings
				param				: null,	
				value				: null	
			},

			me: {	// meiosis module
					X: lib_set_binding (version, def_breadth, null, null, bv_type, organelle, mos_breadth, null, null, steps, synworker.ID),
					Y: lib_set_binding (version, def_breadth, null, null, bv_type, organelle, mos_breadth, null, null, steps, synworker.ID),
					Z: lib_set_binding (version, def_breadth, null, null, bv_type, organelle, mos_breadth, null, null, steps, synworker.ID)
				},
			sy: lib_set_binding (version, def_breadth, null, null, bv_type, organelle, mos_breadth, null, null, steps, synworker.ID),		// synthesis module
			from: {
					module: 'UI',
					action: null, // set at point of use
					status: null, // set at point of use
					message: null, // set at point of use
					ID: null // n/a for UI source
				},
			dest: { // set at point of use
					module: null,
					action: null,
					status: null,
					message: null,
					ID: null
				}
		}
		return mv;
	}
	catch(e){
	alert ("init_mv error: " +e)	;
	}
}

function validSource (inputArr)
{
	if (inputArr.length  === 128) return true ;
	else return false;
}

function gup( name )
/* Get URI Parameter
 * Return value of parameter in URI
 */
{
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results === null )
    return "";
  else
    return results[1];
}

var by = function (name) { // thanks Crockford
	return function (o,p) {
		var a, b;
		if (typeof o === 'object' && typeof p === 'object' && o && p) {
			a = o[name];
			b = p[name];
			return a - b;
		}
		else {
			throw {
				name : 'Error',
				message : 'Expected an object when sorting by ' + name
			};
		}
	};
};

function trx_caller(wp, mv, synthScript, wkrthrottle, call_ID){
/* Messaging function. Replicated in each module.
 */
	try {
		mv.from.module = 'UI';
		wp.sendMessage([mv, synthScript, wkrthrottle], call_ID);
	}
	catch (e) {
		alert("error in trx_caller (UI) " +e);
	}
};




