//https://github.com/LucidTechnics/som
//var culvert_features=["stc","sed_ratio_h","rusle_sum","rusle_majo","rusle_mean","upstrea_stru_m","immediate_curv","meander","up_local_sinuosity"];
//"sed_ratio_h"


$('head').append([		
			'<script src="assets-examples/js/som_package/som.js"></script>',			
	].join('\n'));


	var input_data_setting={
		"key":"culvert_sed-ratio-n-key","data_url":'data/new_culvert_analysis_sentivity_done.json',
		"features":	['culvert_sed-ratio-n-key','culvert_stc-n','up2500_100mb_ag-m','up2500_100mb_grass','up2500_100mb_forest','fl_ws_area-km','q100'],  
		// original "features":	['culvert_sed-ratio-n-key','culvert_stc-n','up2500_100mb_ag-m','up2500_100mb_grass','up2500_100mb_forest','up2500_100mb_area_km'], 
		//,"features":	['culvert_stc-n','fl_ws_area-km','up2500_100mb_ag','up2500_100mb_grass','up2500_100mb_forest','fl_100mb_urban','up2500_100mb_coniferous','up2500_100mb_channel-density'], 
		"log_ln_field":["fl_ws_area-km",'up2500_100mb_channel-density','fl_100mb_urban','up2500_100mb_coniferous',],  //'culvert_stc-n'
		"optimal_neuron":[9,9]
		};
	
	
	function survey_run_som(x,y,initialrate,iteration,distance,initialradius,input_data_setting){  
			
			var jsondata_url=input_data_setting['data_url'];	
			var json_properties=input_data_setting["features"];	
			var key=input_data_setting["key"]; 	
			var final_result;
			var log_ln_field=input_data_setting['log_ln_field'] || [];
			// log_ln_field:["fl_ws_area-km",'culvert_stc-n','up2500_100mb_channel-density',fl_100mb_urban]
			//var jsondata = require('data/culvert_sedmap_liz.json'); 
			if(typeof(jsondata_url)=="object"){
				//console.log('object call');
				final_result=handle_data_som_training(jsondata_url,json_properties,key);
				//console.log(final_result);
				return final_result;
			}
			if(typeof(jsondata_url)=="string" && jsondata_url.includes("json")){
				//console.log('ajax call');
				$.ajax({
					  url: jsondata_url,
					  dataType: 'json',
					  async: false,
					  //data: myData,
					  success: function(data) {
							//console.log(data);
							let nor_data=data_normalization(data,json_properties,log_ln_field);
							final_result=handle_data_som_training(data,json_properties,key);
							//console.log(final_result);
							
					  }//success
					});
				return final_result; 
			}
			
			
			//setInterval(function(){ console.log(sed_degree); }, 3000);		
			//console.log('start', +new Date());
			//console.log('end', +new Date());
			//Look at the internal structure of the SOM
			//console.log('SOM', util.inspect(som.traineeIndex, false, 4)); 
			//console.log(som.traineeIndex); 
			//util.inspect(som.traineeIndex, false, 8)
			
			function handle_data_som_training(data,json_properties,key){
				//console.log({'features': input_data_setting['features'], 'iterationCount': iteration, 'width': x, 'height': y, 'initialLearningRate':initialrate, 'initialRadius':initialradius})
				var som = new Som({features: input_data_setting['features'], iterationCount: iteration, width: x, height: y, initialLearningRate :initialrate, initialRadius:initialradius});
				var final_result;
				som.init({});
				var jsondata = data;
						var json_outputs={};
						var data_feature=data["features"] || data;
						for(var i in data_feature){						
							var each_item=data_feature[i]["properties"] || data_feature[i];
							var text_features_training="";
							//console.log(each_item["site_id"]);
							var each_site_id = each_item[key];
							
							for(var eachfeature in json_properties){
								text_features_training+="'"+json_properties[eachfeature]+"':Number("+(each_item[json_properties[eachfeature]])+"),"
								
							} 		
							text_features_training="som.train('"+each_site_id+"',{"+text_features_training+"})";
							
							eval(text_features_training);
							json_outputs[each_site_id]=each_item["sed_ratio_h"];
						
						
						} //end of for loop
						
					return result_logging(som,json_outputs,distance,data,key)			
			}
			
			function data_normalization(data,json_properties,log_ln_field){ 	
			
				let getMean = function (data) {
					return data.reduce(function (a, b) {
						return Number(a) + Number(b);
					}) / data.length;
				};
				let getSD = function (data) {
					let m = getMean(data);
					return Math.sqrt(data.reduce(function (sq, n) {
							return sq + Math.pow(n - m, 2);
						}, 0) / (data.length - 1));
				};
				
				var data_feature=data["features"] || data;
				var max_value_set={}, min_value_set={},dataset_for_stats={},normalized_results=[],stats_set={};
				
				for(var i in data_feature){						
							var each_item=data_feature[i]["properties"] || data_feature[i];					
							//console.log(each_item["site_id"]);
							
							
							var each_site_id = each_item[key];	
								for(var eachfeature in json_properties){
									
									each_item[json_properties[eachfeature]]
									
									if( log_ln_field.indexOf(json_properties[eachfeature])!=-1){
												//let value = 
												//-Infinity
											if(Math.log10(Number(each_item[json_properties[eachfeature]]))==-Infinity){
												each_item[json_properties[eachfeature]]=0; 
											}else{
												each_item[json_properties[eachfeature]]=Math.log10(Number(each_item[json_properties[eachfeature]])); 									
											}
																	
									}
								
									if(!max_value_set.hasOwnProperty(json_properties[eachfeature])){
										max_value_set[json_properties[eachfeature]]=-99999;
										min_value_set[json_properties[eachfeature]]=99999;
										dataset_for_stats[json_properties[eachfeature]]=[];
									}
									dataset_for_stats[json_properties[eachfeature]].push(Number(each_item[json_properties[eachfeature]]))
									if(Number(each_item[json_properties[eachfeature]])>=max_value_set[json_properties[eachfeature]]){
										max_value_set[json_properties[eachfeature]]=Number(each_item[json_properties[eachfeature]]);									
									}
									if(Number(each_item[json_properties[eachfeature]])<=min_value_set[json_properties[eachfeature]]){
										min_value_set[json_properties[eachfeature]]=Number(each_item[json_properties[eachfeature]]);									
									}								
									//text_features_training+="'"+json_properties[eachfeature]+"':Number("+(each_item[json_properties[eachfeature]])+"),"								
								}
						} //end of for loop
						for(var eachfeature in json_properties){
							let eachfield = json_properties[eachfeature];
							stats_set[eachfield]={  
								"mean": getMean(dataset_for_stats[eachfield]),
								"std": getSD(dataset_for_stats[eachfield]) };
						}
				
				//console.log("get_max_value");
				//console.log(max_value_set);	
				//console.log(min_value_set);
				//console.log(stats_set);
				/*var isAlpha = function(ch){
				  return typeof ch === "string" && ch.length === 1
						 && (ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z");
				}*/
				
				for(var i in data_feature){						
							var each_item=data_feature[i]["properties"] || data_feature[i];						
							let temp_for_each={};
							var each_site_id = each_item[key];						
								for(var eachfeature in json_properties){							
									
										//each_item[json_properties[eachfeature]]=(each_item[json_properties[eachfeature]]-stats_set[json_properties[eachfeature]]["mean"])/stats_set[json_properties[eachfeature]]["std"];
										if(json_properties[eachfeature]=="up2500_100mb_coniferous"){ 
											//console.log('('+Number(each_item[json_properties[eachfeature]])+'-'+min_value_set[json_properties[eachfeature]]+')/('+max_value_set[json_properties[eachfeature]]+'-'+min_value_set[json_properties[eachfeature]]+')');
										}
										console.log((each_item[json_properties[eachfeature]].toString()).charAt(0));
										//if(!isAlpha((each_item[json_properties[eachfeature]].toString()).charAt(0))){   									
										temp_for_each[json_properties[eachfeature]]=(Number(each_item[json_properties[eachfeature]])-min_value_set[json_properties[eachfeature]])/(max_value_set[json_properties[eachfeature]]-min_value_set[json_properties[eachfeature]]);
										each_item[json_properties[eachfeature]]=temp_for_each[json_properties[eachfeature]];									
										/*}else{
											console.log("let");
										}*/
									
									//text_features_training+="'"+json_properties[eachfeature]+"':Number("+(each_item[json_properties[eachfeature]])+"),"								
								}
							normalized_results.push(temp_for_each);
						} //end of for loop
				//console.log(normalized_results);
				
				return normalized_results;
				
				
				
			}
			
			
			function result_logging(som,sed_degree,distance,data,key){
				console.log('sed_degree');
				//console.log(distance); 
				//console.log(sed_degree);
				//console.log(som);
				var res=som.traineeIndex;
				var cout=0
				var indexing_result={},
				  neighbors_result={},
				  neighbors_best={};
				
				
				for (var each in res){
					//console.log(res[each]);
					var index="i"+res[each].x+"-"+res[each].y; 
					if(!indexing_result.hasOwnProperty(index)){
									indexing_result[index]=[];
						};
					indexing_result[index].push( {"id":each,"x":res[each].x,"i":res[each].i,"y":res[each].y,"sed":sed_degree[each],"weight":res[each]["weights"]});				
					neighbors_result[index]=som.neighbors(each,distance);
											
					}					 
					cout++;					
					console.log(indexing_result["neighbors_result"])
					return indexing_result={"index_list":indexing_result,"neighbour_group":neighbors_result,"features":input_data_setting['features'],"raw_data":data,"join_key":key}; 
					//return {"index_list":indexing_result,"neighbour_group":neighbors_result};  
				
				}
		
	};



