// Copyright
// written by Arnaud Zufferey ,  2009-2011, verified with JSLint.com JS parser

var open_window_old = function (url) {
	open_window(url, 650, 500);
};

var open_window = function (url, width, height) {
	var newwindow = window.open(url, 'name', 'height='+height+',width='+width+',resizable=yes,scrollbars=yes');
	if (window.focus) {
		newwindow.focus();
	}
};

var toggle_visibility = function (id) {
	$("#"+id).toggle('blind');
};

var toggle_u_power = function (target){
	$(target).closest('table').find('tr.power').toggle();
}

var show_and_hide = function (id1, id2) {
	$("#"+id1).show('blind');
	$("#"+id2).hide('blind');
};

var isNumber = function (value){
	return typeof value === 'number' && isFinite(value);
};

var isEmpty = function (param) {
	if ((param === null) || (param === "")){
		return true;
	} else {
		return false;
	}
};

var setString = function (id, new_value) {
	$("#"+id).val(new_value);
};

var getString = function (id) {
	return $("#"+id).val() + "";
};

var setFloat2 = function (id, new_value, precision) {
	$("#"+id).val(new_value.toFixed(precision));
	//var factor = Math.pow(10, precision);
	//document.getElementById(id).value = Math.round(factor*new_value)/factor;
};

var setFloat = function (id, new_value) {
	setFloat2(id, new_value, 2);
};

var setInt = function (id, new_value) {
	$("#"+id).val(parseInt(new_value, 10));
};

var getFloat = function (id) {
	var result = getString(id);
	result = result.replace(",","."); // if separator entered is a comma instead of a dot
	result = parseFloat(result, 10); // base 10 
	return result;
};

var getInt = function (id) {
	var result = getString(id);
	return parseInt(result, 10); // base 10
};

var get_today_formatted = function () {
	var today = new Date();
	var today_formatted = today.getDate() + "." + (today.getMonth()+1) +"."+today.getFullYear(); 
	return today_formatted; // string like : "30.01.2010"
};

var set_date_today = function (fieldId) {
	if (isEmpty(getString(fieldId))){
		setString(fieldId, get_today_formatted());
	}
};


var copy_address = function() {	
	var building_location = window.opener.$('#building_address_street').val() + ' , ' 
							+ window.opener.$('#building_address_postal_code').val() 
							+ ' ' + window.opener.$('#building_address_city').val();

	$('#address').val(building_location);
};

var enable_ventilation_options = function () {
	var ventilation_type = getInt("parameter_ventilation");

	if (ventilation_type === 1 ){ 
		//natural ventilation
		$("#parameter_heat_recovery").attr("disabled", "disabled");
		$("#parameter_air_flow").attr("disabled", "disabled");		
	} else {
		// mechanical ventilation 
		$("#parameter_heat_recovery").removeAttr("disabled");
		$("#parameter_air_flow").removeAttr("disabled");
	}		
};

var estimate_occupants = function (fieldId) {
	var sia_category = getInt("parameter_building_category");
	var number_of_occupants = Math.round(getFloat("parameter_heated_area") /  standard_use_sia_380["cat_"+sia_category].ap);
	setInt("parameter_number_of_occupants", number_of_occupants); 
};

var set_default_temperature = function (fieldId) {
	var sia_category = getInt("parameter_building_category");
	var temperature = standard_use_sia_380["cat_"+sia_category].ti;
	setInt(fieldId, temperature); 
};

var set_default_heat_recovery = function (fieldId) {
	var ventilation_type = getInt("parameter_ventilation");
	var default_heat_recovery = 0;
	
	if (ventilation_type === 3){ // double flow with heat recovery
		default_heat_recovery = 70;	
	}

	setInt(fieldId, default_heat_recovery); 
};

var set_default_air_flow = function (fieldId) {
	var air_flow = getInt("parameter_number_of_occupants") * 30; // 30 m3/h SIA 2023
	setInt(fieldId, air_flow); 
};



var calculate_enery_use = function (fieldId) {
	var energy_use_year_1 = 0;
	var energy_use_year_2 = 0;
	var energy_use_year_3 = 0;
	var energy_use_avg = 0;
	var energy_use_sum = 0;
	var energy_use_row_sum = 0;
	var number_of_years  = 0;
	var conversion_factors = [0, 1, 1, 10.5, 10, 5, 2150, 1550, 1];
	var conversion_factor = 0;
	
	for (i=1; i<=5; i++){ // for each row in the energy use table do
		number_of_years  = 0; // reset counter
		energy_use_row_sum = 0; // reset sum
		energy_use_avg = 0; // reset average
		// get selected energy vector :
		conversion_factor = conversion_factors[getInt("energy_use_a"+i)];
		energy_use_year_1 = getFloat("energy_use_b"+i);
		energy_use_year_2 = getFloat("energy_use_c"+i);
		energy_use_year_3 = getFloat("energy_use_d"+i);
		
		if (!isNaN(energy_use_year_1)){
			number_of_years++;
			energy_use_row_sum += energy_use_year_1;
		}
		if (!isNaN(energy_use_year_2)){
			number_of_years++;
			energy_use_row_sum += energy_use_year_2;
		}
		if (!isNaN(energy_use_year_3)){
			number_of_years++;
			energy_use_row_sum += energy_use_year_3;
		}
		if (number_of_years !== 0) {
			energy_use_avg = Math.round(100*energy_use_row_sum / number_of_years)/100;
		} 
		setFloat("energy_use_e"+i, energy_use_avg);
		energy_use_avg = energy_use_avg * conversion_factor; // convert to kWH 
		setFloat("energy_use_f"+i, energy_use_avg);
		energy_use_sum += energy_use_avg;
	} 
	document.getElementById("energy_use_f6").value = energy_use_sum;
	setFloat("energy_use_f8", energy_use_sum * (getFloat("energy_use_f7") / 100)); // kwh weighted with percentage
};

var calculate_area = function (fieldId) {
	var sign   = 0;
	var number = 0;
	var width  = 0;
	var length = 0;
	var area   = 0;
	var total  = 0;
	
	for (i=1; i<=8; i++){
		sign   =  getFloat("area_a"+i);
		number =  getFloat("area_b"+i);
		width  =  getFloat("area_c"+i);
		length =  getFloat("area_d"+i);
		area   = sign*number*width*length;
		if (isNaN(area)){ area = 0; }
		setFloat("area_e"+i, area);
		total  = total + area;
	}
	setFloat("area_total", total);
};

var estimate_u_value_for_year = function (construction_year) {
	var u_value = 0;
	if (isNaN(construction_year)){construction_year = 1960;}
	if (construction_year < 1969){
		u_value = 1.2;
	} else {
		u_value = -0.01 * construction_year + 20.28;
	}
	u_value = Math.round(u_value*100)/100;
	return u_value;
};

var get_u_value_index_for_year = function (construction_year) {
	var index = 1;
	if (isNaN(construction_year)){construction_year = 1980;}
	if (construction_year > 2010){
		index = 6;
	} else if (construction_year > 2005){
		index = 5;
	} else if (construction_year > 2000){
		index = 4;
	} else if (construction_year > 1990){
		index = 3;
	} else {
		index = 2;
	}
	return index;
		/*
		  <option value="1">5.9 | 0.85 | Simple vitrage</option>
		  <option value="2">2.8 | 0.75 | Double vitrage (1960-1990)</option>
		  <option value="3">1.9 | 0.65 | Double vitrage (1990-2000)</option>
		  <option value="4">1.4 | 0.60 | Double vitrage (2000-2005)</option>
		  <option value="5">1.1 | 0.55 | Double vitrage + couche sélective</option>
		  <option value="6">0.7 | 0.45 | Triple vitrage + couche sélective</option>
		  <option value="7">0.5 | 0.45 | Triple vitrage + couche sélective</option>
		*/

}

var calculate_envelope = function () {
	
	var startTime = new Date(); 
	
	var construction_year = getInt("wiz_building_construction_year");
	setInt('building_construction_year', construction_year);
	var u_value = estimate_u_value_for_year(construction_year);
	var u_value_window_index = get_u_value_index_for_year(construction_year);
	var a = getFloat("envelope_a1"); // L
	var b = getFloat("envelope_a2"); // P
	var c = getFloat("envelope_a3");  // H1
	var d = getFloat("envelope_a4"); // H2
	var e = getFloat("envelope_a5"); // annexe L
	var f = getFloat("envelope_a6"); // annexe P
	var g = getFloat("envelope_a7"); // annexe H
	var windows_fraction = getFloat("envelope_a8");
	var number_of_floors_abc = getFloat("envelope_a9");
	var number_of_floors_efg = getFloat("envelope_a10");
	// outputs
	var Ae = 0;
	var roof_area = 0;
	var ground_floor_abc = 0;
	var ground_floor_efg = 0;
	var ground_floor = 0;
	var walls = 0;
	var roof_tilt = 0;
	
	// reset building envelope
	$('#opaqueelementstable').find('tr.data').remove();
	$('#windowconstructiontable').find('tr.data').remove();
	$('#windowshadowtable').find('tr.data').remove();
	$('#windowlisttable').find('tr.data').remove();
	$('#thermalbridgestable').find('tr.data').remove();
	
	// copy canton and climate station values :
	$('#building_canton').val($('#wiz_building_canton').val());
	filter_climate_station_list('building_canton', 'building_climate_station');
	$('#building_climate_station').val($('#wiz_building_climate_station').val());


	// conversion to percentage
	if (windows_fraction > 1 ){ windows_fraction = windows_fraction / 100;}
	if (isEmpty(d)){ d = c; } // flat roof
	
	ground_floor_abc = Math.round(a*b);
	ground_floor_efg = Math.round(e*f);
	ground_floor = ground_floor_abc + ground_floor_efg;
	Ae = Math.round(ground_floor_abc * number_of_floors_abc + ground_floor_efg * number_of_floors_efg);
	setFloat("parameter_heated_area", Ae);	
	
	// set default altitude and internal temperature :
	set_default_altitude('building_altitude');
	estimate_occupants('parameter_number_of_occupants');
	set_default_temperature('parameter_inside_temperature');		
	
	var area_north_south = a*((c+d)/2) + (e*g);
	var area_east_west = b*d;
	walls = 2*(area_east_west+area_north_south);
	
	roof_area = Math.round(b*Math.sqrt(Math.pow(a/2,2) + Math.pow(c-d,2)));
	roof_tilt = Math.round((180/Math.PI)*Math.atan((Math.abs(c-d))/(a/2)));

	// Opaque :      (Type : 1=toit, 2=mur, 3=sol)  (adjacent:  1=ext, ...)
	var opaque_elements = {
		'op_1' : {
			'name' : 'AW1', // mur nord
			'uniqueid' : 'uid-001-aw1',
			'type' : 2,
			'tilt' : 90,
			'azimut' : 0,
			'adjacent' : 1,
			'u_value' : u_value,
			'area' : area_north_south
		},
		'op_2' : {
			'name' : 'AW2', // mur est
			'uniqueid' : 'uid-002-aw2',
			'type' : 2,
			'tilt' : 90,
			'azimut' : 90,
			'adjacent' : 1,
			'u_value' : u_value,
			'area' : area_east_west
		},
		'op_3' : {
			'name' : 'AW3', // mur sud
			'uniqueid' : 'uid-003-aw3',
			'type' : 2,
			'tilt' : 90,
			'azimut' : 180,
			'adjacent' : 1,
			'u_value' : u_value,
			'area' : area_north_south
		},
		'op_4' : {
			'name' : 'AW4', // mur ouest
			'uniqueid' : 'uid-004-aw4',
			'type' : 2,
			'tilt' : 90,
			'azimut' : 270,
			'adjacent' : 1,
			'u_value' : u_value,
			'area' : area_east_west
		},
		'op_5' : {
			'name' : 'BO1', // sol abc
			'uniqueid' : 'uid-005',
			'type' : 3,
			'tilt' : 0,
			'azimut' : 0,
			'adjacent' : 5,
			'u_value' : u_value,
			'area' : ground_floor_abc
		},
		'op_6' : {
			'name' : 'BO2', // sol efg
			'uniqueid' : 'uid-006',
			'type' : 3,
			'tilt' : 0,
			'azimut' : 0,
			'adjacent' : 5,
			'u_value' : u_value,
			'area' : ground_floor_efg
		},
		'op_7' : {
			'name' : 'DA1', // toit ab1
			'uniqueid' : 'uid-007',
			'type' : 1,
			'tilt' : roof_tilt,
			'azimut' : 90,
			'adjacent' : 1,
			'u_value' : u_value,
			'area' : roof_area
		},
		'op_8' : {
			'name' : 'DA2', // toit ab2
			'uniqueid' : 'uid-008',
			'type' : 1,
			'tilt' : roof_tilt,
			'azimut' : 270,
			'adjacent' : 1,
			'u_value' : u_value,
			'area' : roof_area
		},
		'op_9' : {
			'name' : 'DA3', // toit ab2
			'uniqueid' : 'uid-009',
			'type' : 1,
			'tilt' : 0,
			'azimut' : 0,
			'adjacent' : 1,
			'u_value' : u_value,
			'area' : ground_floor_efg
		}
	};
	fill_table($('#opaqueelementstable .tableheader'), opaque_elements);

	
	var thermal_bridges = {
		'tb_1' : {
			'name' : 'socle', 
			'length' : 2*(a+b)+2*e,
			'psi' : 0.15
		},
		'tb_2' : {
			'name' : 'fenetres', 
			'length' : Math.round(walls*windows_fraction*2.5),
			'psi' : 0.15
		}
	};
	
	fill_table($('#thermalbridgestable .tableheader'), thermal_bridges);
	
	var windowconstruction = {
		'wt1' : {
			'frametype' : 3,
			'glasstype' : u_value_window_index,
			'glassspacer' : 1,
			'name' : 'default-window' ,
			'uniqueid' : 'uid-100'
		}
	}
	fill_table($('#windowconstructiontable .tableheader'), windowconstruction);
	  
	var shading = {
		'sh1' : {
			'name' : 'embrasure 25cm', 
			'uniqueid' : 'uid-201',
			'a' : 0,
			'b' : 0.25,
			'c' : 0,
			'd' : 0.25,
			'e' : 0,
			'f' : 0.25,
			'g' : 0
		},
		'sh2' : {
			'name' : 'balcon 1.2m', 
			'uniqueid' : 'uid-202',
			'a' : 0.3,
			'b' : 1.2,
			'c' : 0,
			'd' : 0.25,
			'e' : 0,
			'f' : 0.25,
			'g' : 0
		},
		'sh3' : {
			'name' : 'balcon 2m', 
			'uniqueid' : 'uid-203',
			'a' : 0.3,
			'b' : 2,
			'c' : 0,
			'd' : 0.25,
			'e' : 0,
			'f' : 0.25,
			'g' : 0
		}
	}
	fill_table($('#windowshadowtable .tableheader'), shading);
	
	updateElementsLists(); // update drop down lists before inserting windows

	var windows = {
		'w_1' : {
			'opaqueelementsselect' : 'uid-001-aw1',
			'name' : 'f1',
			'width' : 1,
			'height' : 1,
			'wings' : 2,
			'number' : Math.round(area_north_south*windows_fraction),
			'windowtypeselect' : '',
			'framepart' : 30,
			'windowshadowselect' : '',
			'shading' : ''
		},
		'w_2' : {
			'opaqueelementsselect' : 'uid-002-aw2',
			'name' : 'f2',
			'width' : 1,
			'height' : 1,
			'wings' : 2,
			'number' : Math.round(area_east_west*windows_fraction),
			'windowtypeselect' : '',
			'framepart' : 30,
			'windowshadowselect' : '',
			'shading' : ''
		},
		'w_3' : {
			'opaqueelementsselect' : 'uid-003-aw3',
			'name' : 'f3',
			'width' : 1,
			'height' : 1,
			'wings' : 2,
			'number' : Math.round(area_north_south*windows_fraction),
			'windowtypeselect' : '',
			'framepart' : 30,
			'windowshadowselect' : '',
			'shading' : ''
		},
		'w_4' : {
			'opaqueelementsselect' : 'uid-004-aw4',
			'name' : 'f4',
			'width' : 1,
			'height' : 1,
			'wings' : 2,
			'number' : Math.round(area_east_west*windows_fraction),
			'windowtypeselect' : '',
			'framepart' : 30,
			'windowshadowselect' : '',
			'shading' : ''
		}

	}
	fill_table($('#windowlisttable .tableheader'), windows);
	
	// heating
	$('#hvac_heating_a2').val($('#wiz_hvac_heating').val());
	$('#hvac_heating_a3').val(construction_year);
	estimate_cop('hvac_heating_a2');
	
	calculate_minergie();
	$('#hvac_heating_a6').val($('#sia_380_384_201').val());
	
	var endTime = new Date(); 
	var timeElapsed = endTime - startTime;
	alert(timeElapsed + " ms pour generer et simuler le batiment.");
	
	
	$('#confirm_envelope_wizard').show().delay('4000').fadeOut('slow');
	
}


var fill_table = function (table_selector, json_data) {
	for (var i in json_data) {
		addRow(table_selector, json_data[i]); 
	}
};


var calculate_u_value = function (target) {
	
	var rvalue = 0; 
	var thicknesstotal = 0;
	var thickness = 0;
	var uvalue = 0;
	var rtotal = 0.17; // Ra + Ri

	$(target).closest('table').find('tr.data').each(function(){
		thickness = $(this).find(".thickness").val()*1; // integer
		rvalue = (thickness / 100) / $(this).find(".lambdavalue").val(); // R = e / lambda
		rtotal = rtotal + rvalue ; 
		thicknesstotal = thicknesstotal + thickness;
	});
	uvalue = 1 / rtotal;
	$(target).closest('table').find('tr.tablefooter .thicknesstotal').val(thicknesstotal);
	$(target).closest('table').find('tr.tablefooter .uvalue').val(uvalue.toFixed(2));

	calculate_power(target);
}

var calculate_power = function (target) {
	var table = $(target).closest('table');
	var tint = table.find('.insidetemperature').val();
	var text = table.find('.outsidetemperature').val();
	var area = table.find('.elementarea').val();
	var uvalue = table.find('.uvalue').val(); 
	var heatingpower = uvalue * area * (tint-text);
	
	table.find('.heatingpower').val(heatingpower.toFixed());
}

var get_energy_label = function (qh_mj_m2) {
	// standard Qh for each SIA category :  
	var energy_label = "Z";
	var qh_li = getFloat("sia_380_qhli");
	//var qh_sia_2031 = [160, 220, 170, 180, 130, 240, 210, 170, 150, 130, 150, 180];
	var ratio = Math.round(qh_mj_m2 *100 / qh_li); 

	if (ratio <= 50) {
		energy_label = "A";
	} else if (ratio <= 100) {
		energy_label = "B";		
	} else if (ratio <= 150) {
		energy_label = "C";
	} else if (ratio <= 200) {
		energy_label = "D";
	} else if (ratio <= 250) {
		energy_label = "E";
	} else if (ratio <= 300) {
		energy_label = "F";
	} else {
		energy_label = "G";
	}
	return energy_label;
}

var calculate_thermal_balance = function (fieldId) {
	estimate_sia_380(); // refresh sia 380/1 calculation
	
	var energy_use = getFloat("energy_use_f8");
	var energy_reference_area = getFloat("parameter_heated_area");
	var energy_ratio = energy_use / energy_reference_area;
	// TODO : replace with real efficiency factor
	var energy_ratio_sia = (getFloat("sia_380_qww") + getFloat("sia_380_qh")) / 0.85; 
	var deviation = 0;
	
	setString("thermal_balance_c1", "-");
	setString("thermal_balance_c2", get_energy_label(getFloat("sia_380_qh")));
	
	setFloat("thermal_balance_a1", energy_ratio);
	setFloat("thermal_balance_b1", energy_ratio * 3.6); // conversion kWh -> MJ
	setFloat("thermal_balance_a2", energy_ratio_sia / 3.6); // conversion MJ -> kWh
	setFloat("thermal_balance_b2", energy_ratio_sia); 

	deviation = Math.round((energy_ratio - (energy_ratio_sia / 3.6)) / (energy_ratio_sia / 3.6) * 100);
	setFloat("thermal_balance_a3", deviation); 
		
}

var calculate_cost_surfaces = function (target) {
	var tr = $(target).closest('tr');
	var name = tr.find('.name').val();
	var area = tr.find('.area').val();
	var uvalue = tr.find('.uvalue').val();
	var measure = tr.find('.measure').val();
	var targetuvalue = tr.find('.targetuvalue').val();
	var lambdavalue = tr.find('.lambdavalue').val();
	var thickness = 0;
	var thickness_displayed = 0;
	var cost = 0;
	var grants = [15, 40, 70]; // grants : 15.- /unheated, 40.- walls & roofs, 70.- windows
	var grant_surface_min = 0;
	var grant_surface_max = 1;
	var grant_type = 0; 
	var grant_factor = 0;
	var grant = 0;
	var totalcost = 0;	
	var negawatt = 0;
	var years = 30; // amortisation on 30 years, for payback calculation
	var delta_t = 30; // TODO : replace with real delta T
	// TODO : replace with real altitude 
	var power_conversion_factor = get_power_conversion_factor(500, false); // altitude,  heating_only
	

	if (!(isEmpty(area) || isEmpty(uvalue) || isEmpty(measure) || isEmpty(targetuvalue) || isEmpty(lambdavalue))) {
		// thickness for cost calculations, use a lambda of 0.035
		thickness = Math.ceil(( (1/targetuvalue) - (1/uvalue) ) * 0.035 * 100);
		// thickness displayed, use the selected lambda value
		thickness_displayed = Math.ceil(( (1/targetuvalue) - (1/uvalue) ) * lambdavalue * 100);
		// calculate cost for the chosen measure :
		measure = measure * 1;
		// # here
		
		switch(measure)	{
		case 1:
		  cost = 1.07 * Math.pow(thickness,2)  - 24.85 * thickness + 286.36 ;
		  grant_type = grant_surface_max;
		  //debug ("case 1"); 
		  break;
		case 2:
		  cost = 2.4 * thickness  + 147 ;		
		  grant_type = grant_surface_max;
		  //debug("case 2"); 
		  break;
		case 3:
		  cost = 1.87 * Math.pow(thickness,2)  - 13.25 * thickness + 490.5 ;	
		  grant_type = grant_surface_max;
		  //debug("case 3"); 
		  break;
		case 4:
		  cost = 300 ;	
		  grant_type = grant_surface_max;
		  //debug("case 4"); 
		  break;
		case 5:
		  cost = 150 ;	
		  grant_type = grant_surface_max;
		  //debug("case 5"); 
		  break;
		case 6:
		  cost = -0.01 * Math.pow(thickness,2)  + 1.66 * thickness + 10.38 ;	
		  grant_type = grant_surface_min;
		  //debug("case 6"); 
		  break;
		case 7: 
		  cost = -0.13 * Math.pow(thickness,2)  + 7.5 * thickness + 45.3 ;	
		  grant_type = grant_surface_min;
		  //debug("case 7"); 
		  break;
		case 8: 
		  cost = 0.6198 * Math.pow(thickness,2)  - 4.124 * thickness + 225.5 ;	
		  grant_type = grant_surface_max;
		  //debug("case 8"); 
		  break;
		case 9: 
		  cost = -0.3571 * Math.pow(thickness,2)  + 26 * thickness + 65.857 ;	
		  grant_type = grant_surface_max;
		 // debug("case 9"); 
		  break;
		case 10: 
		  cost = - 0.36  * Math.pow(thickness,2)  + 11.7 * thickness + 80 ;	
		  grant_type = grant_surface_max;
		 // debug("case 10"); 
		  break;
		case 11: 
		  cost = - 0.36  * Math.pow(thickness,2)  + 11.7 * thickness + 80 ;	
		  grant_type = grant_surface_min;
		  //debug("case 11"); 
		  break;
		case 12: 
		  cost = - 0.2  * Math.pow(thickness,2)  + 7.81 * thickness + 50.97 ;	
		  grant_type = grant_surface_min;
		 // debug("case 12"); 
		  break;
		case 13: 
		  cost = - 0.01  * Math.pow(thickness,2)  + 1.67 * thickness + 30.8  ;	
		  grant_type = grant_surface_min;
		  //debug("case 13"); 
		  break;
		case 14: 
		  cost = 180  ;	
		  grant_type = grant_surface_max;
		  //debug("case 14"); 
		  break;
		default:
		  //debug("default case"); 
		} 
		
		cost = Math.round(cost);
		// calculate grants
		if (((grant_type == grant_surface_min) && (targetuvalue <= 0.25)) 
		   || ((grant_type == grant_surface_max) && (targetuvalue <= 0.2))) {
				grant_factor = 1;	// grants 		
		} else {
			grant_factor = 0; // no grants
		}
		grant  = grant_factor * grants[grant_type] * area;

		// negawatt = cost / (years * delta U * delta T * power_to_kwh_conversion_factor)
		//console.log(cost, years, uvalue, targetuvalue, delta_t, power_conversion_factor);
		negawatt = cost / (years * (uvalue-targetuvalue) * delta_t * (power_conversion_factor/1000)); 
		
		tr.find('.thickness').val(thickness_displayed);
		tr.find('.cost').val(cost);
		tr.find('.totalcost').val(cost*area);
		tr.find('.grant').val(grant);
		tr.find('.negawatt').val(negawatt.toFixed(2));

	}

}


var calculate_cost_windows = function (field_id) {
	var frame = 0;
	var glass = 0;
	var number = 0;
	var width = 0;
	var height = 0;
	var window_area = 0;
	var area = 0;
	var cost = 0;
	var grant = 0;
	var number_tl = 0;
	var area_tl = 0;
	var cost_tl = 0;
	var grant_tl = 0;
	frame = document.getElementById("fz1").value;
	glass = document.getElementById("fz2").value;	
	
  for (i=1; i<=6; i++){	
		number =  document.getElementById("fb"+i).value;
		width = document.getElementById("fc"+i).value;
		height = document.getElementById("fd"+i).value;	
	
	number_tl = number_tl + number *1;
	window_area = Math.round(width * height *100) / 100;
	area = Math.round(number * window_area*100)/100;
	area_tl = area_tl + area;
	// windows cost = base price + correction factors (frame, glass)
	if (window_area<=1){
		cost = 1000 * number * frame * glass;
	} else {
		cost = 725 * area * frame * glass;
	}	
	if (glass > 1){
		grant = 40 * area;
	}
	grant_tl = grant_tl + grant;
	cost_tl = cost_tl + cost;
	document.getElementById("fe"+i).value = area;
	document.getElementById("ff"+i).value = cost;
	document.getElementById("fg"+i).value = grant;
  }
	document.getElementById("fb7").value = number_tl;
	document.getElementById("fe7").value = area_tl;
	document.getElementById("ff7").value = cost_tl;
	document.getElementById("fg7").value = grant_tl;
}

var calculate_cost_doors = function (field_id) {
	var type = 0;
	var number = 0; 
	var width = 0;
	var height = 0;
	var area = 0;
	var cost = 0;
	var grant = 0; // no grants for doors
	var number_tl = 0;
	var area_tl = 0;
	var cost_tl = 0;
	var grant_tl = 0;
	
	for (i=1; i<=3; i++){	
		type = document.getElementById("ta"+i).value;
		number = document.getElementById("tc"+i).value; 
		width = document.getElementById("td"+i).value;
		height = document.getElementById("te"+i).value;
		area = Math.round(number * width * height *100)/100;
		area_tl = area_tl + area;
		if (type == "1") { // door -> unheated
			cost = 400 * area; // 400.- / m2
		} else { // entrance door
			cost = 1500 * area; // 1500.- / m2		
		}
		number_tl = number_tl + number *1;
		cost_tl = cost_tl + cost;
		document.getElementById("tf"+i).value = area;
		document.getElementById("tg"+i).value = cost;
		document.getElementById("th"+i).value = grant;		
	}
	document.getElementById("tc4").value = number_tl;
	document.getElementById("tf4").value = area_tl;
	document.getElementById("tg4").value = cost_tl;
	document.getElementById("th4").value = grant_tl;
}

var get_solar_production = function (collector_area) { // hot water
	return 400 * collector_area; // 400 kWh / m2 collector
	//production = Math.round(700/((1/collector_area) + (380/Qww)));
}

var calculate_cost_hot_water = function (field_id) {
	var building_category 			= 0;
	var heated_area 				= 0;
	var number_people_calculated 	= 0;
	var number_people_chosen  		= 0;
	var area_per_person 			= 0;
	var collector_area				= 0;
	var collector_area_per_person 	= 0;
	var boiler_capactiy				= 0;
	var boiler_capactiy_per_m2		= 0;
	var cost						= 0;
	var production 					= 0;
	var Qww							= 0;
	building_category =  $("#hot_water_a1").val() ;
	heated_area = $("#hot_water_b1").val();
	if (building_category === 1) { // category = MFH
		area_per_person = 40;
		collector_area_per_person = 0.9;
		boiler_capactiy_per_m2 = 70;
		Qww = 75 / 3.6;
	} else { // category = EFH 
		area_per_person = 60;
		collector_area_per_person = 1.25;
		boiler_capactiy_per_m2 = 100;
		Qww = 50 / 3.6;
	}
	number_people_calculated = Math.round(heated_area / area_per_person); 
	document.getElementById("hot_water_c1").value = number_people_calculated;
	number_people_chosen = document.getElementById("hot_water_d1").value ;
	collector_area  	 = Math.round(collector_area_per_person * number_people_chosen); 
	boiler_capactiy 	 = boiler_capactiy_per_m2 * collector_area; 
	production 			 = get_solar_production(collector_area);  
	cost				 = 1708 * collector_area + 8110;
	cost 				 = Math.round(cost/100)*100;
	document.getElementById("hot_water_e1").value = collector_area;
	document.getElementById("hot_water_f1").value = boiler_capactiy;
	document.getElementById("hot_water_g1").value = production;
	document.getElementById("hot_water_h1").value = cost;
	
}; 

var get_photovoltaics_power = function (solar_panel_area) {
	return solar_panel_area / 8;  // 8 m2 = 1 kWp
};

var get_photovoltaics_production = function (pv_power) {
	return pv_power * 1000; // 900 to 1100 kWh / kWp, (up to 1100 in Valais)
};

var calculate_cost_photovoltaics = function (field_id) {
	var solar_panel_area 	= document.getElementById("photovoltaics_a1").value;
	var power 				= get_photovoltaics_power(solar_panel_area);
	var production 			= get_photovoltaics_production(power);
	var cost 				= power * 6000; 	// 6'000.- / kWp, previously 10'000.-
	document.getElementById("photovoltaics_b1").value = power;
	document.getElementById("photovoltaics_c1").value = production;	
	document.getElementById("photovoltaics_d1").value = cost;
};

var calculate_cost_blinds = function (field_id) {
	var type = 0;
	var cost = 0;
	var surface = 0;
	
	surface = $('#blinds_a1').val();
	type = $('#blinds_b1').val();
	if (type==1){
		cost = 150; // store interieur
	} else if (type==2){
		cost = 150; // store lamelles
	} else if (type==3){
		cost = 200; // store toile
	} else if (type==4){
		cost = 230; // store toile soltis
	} else if (type==5){
		cost = 400; // store banne a caisson 
	}
	
	setFloat("blinds_c1", cost*surface);	
};

var calculate_cost_solar_film = function (field_id) {
	var surface = 0;
	var cost = 0;
	surface = $('#solar_film_a1').val();
	if (surface <= 30){
		// degressive cost
		cost =  (0.062 * surface * surface) - (4.15 * surface) + 178.9;
	} else {
		cost = 110;
	}

	setFloat("solar_film_b1", cost*surface);	

};

var calculate_power_swimming_pool = function (field_id) {
	var surface = 0;
	var power = 0;
	var type = 0;
	surface = $('#swimming_pool_a1').val();
	type = $('#swimming_pool_b1').val();

	if (type==1){ 					// 20 degres
		power = 0.2; 				//  0.2 kW / m2
	} else if (type==2){			// 24 degres
		power = 0.4; 				//  0.4 kW / m2
	} else if (type==3){			// 28 degres
		power = 0.6; 				//  0.6 kW / m2
	}

	setFloat("swimming_pool_c1", power*surface);
};

var calculate_cost_ventilation = function (field_id) {
	var heated_area = 0;	// SRE
	var cost = 0;
	var type = 0;  // simple flux ou double flux
	heated_area = getFloat("ventilation_p1"); 
	type = getInt("ventilation_a1");
	
	if (type==1){ 					// ventilation simple flux
		cost = 20 * heated_area; 	// 20.- / m2
	} else if (type==2){			// ventilation double flux
		cost = 120 * heated_area; 	// 120.- / m2
	}

	setFloat("ventilation_b1", cost);	
} // end calculate_cost_ventilation

var estimate_specific_power = function (sia_category, construction_year){
	var specific_power = 0;

	if (sia_category == 2){ // Wohnen EFH
		if (construction_year < 1969){
			specific_power = 115;
		} else if (construction_year < 1979){
			specific_power = 80;			
		} else if (construction_year < 1989){
			specific_power = 75;			
		} else if (construction_year < 1999){
			specific_power = 70;			
		} else if (construction_year < 1999){
			specific_power = 70;			
		} else if (construction_year < 2009){
			specific_power = 45;			
		} else {
			specific_power = 30;						
		}
	} else { // Wohnen MFH, admin...
		if (construction_year < 1969){
			specific_power = 75;
		} else if (construction_year < 1979){
			specific_power = 67;			
		} else if (construction_year < 1989){
			specific_power = 59;			
		} else if (construction_year < 1999){
			specific_power = 51;			
		} else if (construction_year < 1999){
			specific_power = 43;			
		} else if (construction_year < 2009){
			specific_power = 35;			
		} else {
			specific_power = 30;						
		}				
	}
	return specific_power;
}



var get_power_conversion_factor = function (altitude, heating_only){
	var power_conversion_factor = 0;
	if (heating_only){
		if (altitude < 800){
			power_conversion_factor = 2400;
		} else {
			power_conversion_factor = 2650;
		}
	} else { // heating and hot water
		if (altitude < 800){
			power_conversion_factor = 2700;
		} else {
			power_conversion_factor = 2950;
		}
	}
	return power_conversion_factor;
}

var estimate_power = function (energy_use, altitude, heating_only){
	// energy_use = kWh
	var power_conversion_factor = get_power_conversion_factor(altitude, heating_only);
	var power = 0;
	power = energy_use / power_conversion_factor;
	return power;
}

var estimate_energy_use = function (power, altitude, heating_only){
	var power_conversion_factor = get_power_conversion_factor(altitude, heating_only);
	var energy_use = Math.round(power * power_conversion_factor);
	return energy_use;
}

var estimate_energy_use_old = function (heated_area, specific_power, altitude, heating_only){

	var power = (specific_power/1000) * heated_area ;
	var energy_use = 0;
	var power_conversion_factor = get_power_conversion_factor(altitude, heating_only);
	energy_use = Math.round(power * power_conversion_factor);
	return energy_use;
}


var calculate_b_factor = function (type, adjacent, u_value){
	var b_factor = 0;
	if (adjacent == 1){
		b_factor = 1;
	} else if (adjacent == 2){
		b_factor = 0.9;
	} else if (adjacent == 3){
		b_factor = 0.9;
	} else if (adjacent == 4){
		b_factor = 0.8;
	} else if (adjacent == 5){
		b_factor = 0.7;
	} else if (adjacent == 6){
		b_factor = 0.7;
	} else if (adjacent == 12){
		b_factor = 0;
	} else {
		b_factor = 0.7; // TODO : g�rer les autres cas : adjacent = 7 � 11 : �l�ment contre terrain ! selon SIA 380/1..
		// valeur b en fonction du type et de la valeur U
	}
	return b_factor;
}


var estimate_sia_380 = function () {
	var chart_width_factor = 200; // 200 px wide
	var loss  = [0,0,0,0,0,0]; // roof, wall, floor, window, thermal bridge, ventilation
	var opaque_area = [0,0,0]; // roof, wall, floor
	var window_area = [0,0,0]; // roof, wall, floor
	var index = 0;
	var w_k = 0;
	var w_k_total = 0;
	var ventilation_type = getInt("parameter_ventilation");
	var sia_category = getInt("parameter_building_category");
	var construction_year = getInt("building_construction_year");
	var altitude = getInt("building_altitude");
	var v_sre0 = standard_use_sia_380["cat_"+sia_category].v_sre0;
	var heated_area = getFloat("parameter_heated_area");
	var type = 0;
	var adjacent = 0;
	var area = 0;
	var u_value = 0;
	var b_factor = 0;
	var length = 0;
	var psi = 0;
	var w_k_tb = 0;
	var Ath_Ae = 0;
	var Ath = 0;	
	var specific_power = 0; 
	var Qh = 0;
	var Qh_total = 0;
	var Qww = 0;
	var Qhli = 0;
	var Qt = 0;
	var Qt_total = 0;
	var Qv = 0;
	var Qv_total = 0;
	var internal_gain_people = 0;
	var internal_gain_electricity = 0;
	var Qi = 0;
	var Qi_total = 0;
	var nb_days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	var qs_distribution = [0.05, 0.06,	0.09, 0.1, 0.1, 0.11, 0.11, 0.11, 0.1, 0.08, 0.05, 0.04]; // deprecated
	var Qs = 0;
	var Qs_total = 0;
	var glazing_area = 0;
	var total_window_area = [];
	var w_k_windows = 0;
	var u_value_windows = 0;
	var number_of_windows = 0;
	var a = 0; 
	var ng = 0;
	var gamma = 0;
	var total_power = 0;
	var thermal_capacity = 0 ; 
	var thermal_capacity_index = 0;
	var delta_t = 0;
	var station = $("#building_climate_station").val();
	var avg_outside_temperature = weatherSIA2028[station]['temperature']['month'];
   	var inside_temperature = getFloat("parameter_inside_temperature");
	var regulation_index = getInt("parameter_regulation");
	var frame_width = 0.12; // 12 cm
	var w_height = 0;
	var w_width = 0;
	var glassvalues = [];
	
	// create a table with opaque elements values
	var opaqueelementslist = []; 
	$('#opaqueelementstable tr.data').each(function(){	
		type = $(this).find(".type").val();
		adjacent = $(this).find(".adjacent").val();
		area = parseFloat($(this).find(".area").val());
		u_value = parseFloat($(this).find(".u_value").val());
		b_factor = calculate_b_factor(type, adjacent, u_value);
		
		opaqueelementslist[$(this).find('.uniqueid').val()]	= {
			'name' : $(this).find(".name").val(),
			'type' : type,
			'tilt' : $(this).find(".tilt").val(),
			'azimut' : $(this).find(".azimut").val(),
			'adjacent' : adjacent,
			'u_value' : u_value,
			'b_factor' : b_factor,
			'raw_area' : area,
			'window_area' : 0			
		};
		Ath = Ath + (area * b_factor);
	});
	
	// create a table with window construction values
	var windowconstruction = [];
	$('#windowconstructiontable tr.data').each(function(){
		glassvalues = $(this).find('.glasstype :selected').text().split('|');
		windowconstruction[$(this).find('.uniqueid').val()] = {
			'Uf' : parseFloat($(this).find('.frametype :selected').text()),
			'Ug' : parseFloat(glassvalues[0]),
			'gg' : parseFloat(glassvalues[1]),
			'psig' : parseFloat($(this).find('.glassspacer :selected').text())
		};
	});
	
	// create a table with shadows
	var shadows = [];
	$('#windowshadowtable tr.data').each(function(){
		shadows[$(this).find('.uniqueid').val()] = {
			'name' : $(this).find('.name').val(),
			'a' : $(this).find('.a').val(),
			'b' : $(this).find('.b').val(),
			'c' : $(this).find('.c').val(),
			'd' : $(this).find('.d').val(),
			'e' : $(this).find('.e').val(),
			'f' : $(this).find('.f').val(),
			'g' : $(this).find('.g').val()
		};
	});
	
	var windows = [];
	$('#windowlisttable tr.data').each(function(){
		var windowTypeId = $(this).find('.windowtypeselect').val();
		var opaqueId = $(this).find('.opaqueelementsselect').val();
		w_width = parseFloat($(this).find('.width').val());
		w_height = parseFloat($(this).find('.height').val());
		windows.push({
			'name' : $(this).find('.name').val(),
			'opaqueId' :  opaqueId,
			'opaqueName' : opaqueelementslist[opaqueId]['name'],
			'shadowId' : $(this).find('.windowshadowselect').val(),
			'windowTypeId' : windowTypeId,
			'shadingId' : $(this).find('.shading').val(),
			'wings' : parseInt($(this).find('.wings').val()),
			'number' : parseInt($(this).find('.number').val()),
			'height' : w_height,
			'width' :  w_width,
			'framepart' : parseFloat($(this).find('.framepart').val()) / 100,
			'Uf' : parseFloat(windowconstruction[windowTypeId]['Uf']),
			'Ug' : parseFloat(windowconstruction[windowTypeId]['Ug']),
			'gg' : parseFloat(windowconstruction[windowTypeId]['gg']),
			'psig' : parseFloat(windowconstruction[windowTypeId]['psig']),
			'tilt' : parseFloat(opaqueelementslist[opaqueId]['tilt']),
			'azimut' : parseFloat(opaqueelementslist[opaqueId]['azimut']),
			'area' : w_width * w_height,
			'lg' : 0,
			'Uw' : 0,
			'fs1' : 0,
			'fs2' : 0,
			'fs3' : 0,
			'fs' : 0
			});
	});
	
	// calculate U value for windows (Uw) and shading factor (FS)
	$('#windows_report').html('');
	for(index in windows){
		windows[index]['lg'] = 2*windows[index]['wings']*(windows[index]['height']-2*frame_width) 
								+ 2*(windows[index]['width']-frame_width*(windows[index]['wings']+1));
		
		var Uw = ((windows[index]['Uf']*(windows[index]['area'] * windows[index]['framepart'])) 
								+ (windows[index]['Ug']*(windows[index]['area']	* (1-windows[index]['framepart']))) 
							+ (windows[index]['psig'] * windows[index]['lg'])) / windows[index]['area']	;		

		windows[index]['Uw'] = Uw.toFixed(2);

		var opaqueId = windows[index]['opaqueId'];
		var shadowId = windows[index]['shadowId'];
		// total_window_area[0,1,2] = roof, wall, floor		
		total_window_area[opaqueelementslist[opaqueId]['type']-1] += windows[index]['area']	 * windows[index]['number'];
		opaqueelementslist[opaqueId]['window_area'] += (windows[index]['area']	 * windows[index]['number']);
		
		glazing_area +=  windows[index]['area']	 * (1-windows[index]['framepart']) * windows[index]['number'];
		
		// shading calculation
		var fsdata = shadows[shadowId]
		fsdata['azimut'] = opaqueelementslist[opaqueId]['azimut'];
		fsdata['h'] = windows[index]['height'];
		fsdata['l'] = windows[index]['width'];
		var fs23 = get_fs23_factor(fsdata); // where fsdata = {'a': 2, 'b': 4... G ... 'azimut'} 
		var azimut_index = Math.round(opaqueelementslist[opaqueId]['azimut'] / 45); // 0, 1, 2, .. 7
		if (azimut_index === 8) {
                    azimut_index = 0;
        }
		var fs1Id = '#fs1_factor_' + azimut_index;
		var fs1 = $(fs1Id).val();
		var fs = fs1 * fs23['fs2'] * fs23['fs3']; 
		windows[index]['fs1'] = fs1;
		windows[index]['fs2'] = fs23['fs2'];
		windows[index]['fs3'] = fs23['fs3']
		windows[index]['fs'] = fs.toFixed(2);

		// TODO : calculer le FS pour les fenetres horizontales : multiplier les 4 FS1

		w_k_windows += windows[index]['Uw'] * windows[index]['area'] * windows[index]['number'];
		window_area[opaqueelementslist[opaqueId]['type']-1] += (windows[index]['area'] * windows[index]['number']);
		
		$('#windows_report').append('<pre>'+ 'name : ' + windows[index]['name'] 
					+ ' (' + windows[index]['number'] + 'x on element ' + windows[index]['opaqueName'] + ')\n'
					+ 'wings  : ' + windows[index]['wings']
					+ ', height : ' + windows[index]['height']
					+ ' m, width : ' + windows[index]['width'] 
					+ ' m => area : ' + windows[index]['area'] + ' m2 \n'
					+ 'Uf : ' + windows[index]['Uf'] + ', Ug : ' + windows[index]['Ug']
					+ ', gg : ' + windows[index]['gg'] + ', psig : ' + windows[index]['psig']
					+ ', lg : ' + windows[index]['lg'] + ', Ff : ' + windows[index]['framepart'] + ' => Uw : ' + windows[index]['Uw'] + ' W/(m2 K)\n'
					+ 'tilt : ' + windows[index]['tilt'] + ', azimut : ' + windows[index]['azimut'] 
					+ ', fs1 : ' + windows[index]['fs1'] 
					+ ', fs2 : ' + windows[index]['fs2'] 
					+ ', fs3 : ' + windows[index]['fs3'] 
					+ ' => fs : ' + windows[index]['fs'] 
					+ '</pre>');
	}
	
	// now we can compute net area => transmission losses
	for(index in opaqueelementslist){
		w_k = opaqueelementslist[index]['u_value'] * opaqueelementslist[index]['b_factor'] 
				* (opaqueelementslist[index]['raw_area'] - opaqueelementslist[index]['window_area']);	  	
		if (isNaN(w_k)){w_k = 0; }
		loss[opaqueelementslist[index]['type']-1] += w_k;
		opaque_area[opaqueelementslist[index]['type']-1] += opaqueelementslist[index]['raw_area']-opaqueelementslist[index]['window_area'];
	}
	
	if (ventilation_type==3){
		// mechanical ventilation with heat recovery , calculate thermal equivalent air flow
		v_sre0 = 0.15 + (getInt("parameter_air_flow") / heated_area) * (1-(getInt("parameter_heat_recovery") / 100));
	}
	
	$('#thermalbridgestable tr.data').each(function(){
		length = $(this).find(".length").val();
		psi = $(this).find(".psi").val();
		w_k_tb += length * psi;
	});
	
	// loss[0,1,2] = roof, wall, floor
	loss[3]  = w_k_windows;
	loss[4]  = w_k_tb;
	loss[5]  = v_sre0 * heated_area * 0.33; // renouvellement air * Ae * capacite thermique de l'air	
	
	var maxLoss = 0;
	for (i=0; i<loss.length; i++){	
		w_k_total += loss[i]; 
		setFloat("sia_loss_a"+(i+1), loss[i]);
		if (loss[i] > maxLoss){ maxLoss = loss[i]; }
	}
	var percentage = 0;
	for (j=0; j<loss.length; j++){	
		percentage = Math.round(loss[j] *100 / w_k_total)
		setInt("sia_loss_b"+(j+1),  percentage);
        $('#sia_loss_c'+(j+1)).width(Math.round((loss[j] / maxLoss) * chart_width_factor));
	}
 	
	var maxArea = 0;
	for (i=0; i<opaque_area.length; i++){	
		if ((opaque_area[i] + window_area[i]) > maxArea) {
			maxArea = opaque_area[i] + window_area[i];
		}
	}	
	
	for (i=0; i<opaque_area.length; i++){	
		setFloat("sia_area_a"+(i+1), opaque_area[i]);
		setFloat("sia_area_b"+(i+1), window_area[i]);
		$("#sia_area_c"+(i+1)).width(Math.round(opaque_area[i] / maxArea * chart_width_factor));
		$("#sia_area_d"+(i+1)).width(Math.round(window_area[i] / maxArea * chart_width_factor));
	}

	Ath_Ae = Ath / heated_area;
	
	setFloat("sia_loss_a7", w_k_total);
	setFloat("sia_380_ae", heated_area);
	setFloat("sia_380_ath", Ath); 
	setFloat("sia_380_ath_ae", Ath_Ae);

	// regulation : (1) => +0 degrees , (2) => +1 degree  , (3) => +2 degrees
	if (regulation_index == 2) {
		inside_temperature += 1;
	} else if (regulation_index == 3){
		inside_temperature += 2;		
	}

	thermal_capacity_index = getInt("parameter_thermal_capacity");
	if (thermal_capacity_index == 1) {
		thermal_capacity = 0.5;
	} else if (thermal_capacity_index == 2) {
		thermal_capacity = 0.3;
	} else if (thermal_capacity_index == 3) {
		thermal_capacity = 0.1;
	} else if (thermal_capacity_index == 4) {
		thermal_capacity = 0.05;
	} 

	var tau_0 = 16;
	var tau =  (thermal_capacity * heated_area *1000000) /  (w_k_total * 3600);
	a  = 1 + (  tau / tau_0);	

	Qww = standard_use_sia_380["cat_"+sia_category].qww;
	
	// example : 70 W/person, 12 h / day, 365 days, conversion to MJ, 50 m2/person
	internal_gain_people = standard_use_sia_380["cat_"+sia_category].qp * standard_use_sia_380["cat_"+sia_category].tp
		* 365 * 3.6 / 1000 *(heated_area / standard_use_sia_380["cat_"+sia_category].ap) / heated_area;

	internal_gain_electricity = standard_use_sia_380["cat_"+sia_category].qe * standard_use_sia_380["cat_"+sia_category].fe;

	Qi_total = internal_gain_electricity + internal_gain_people;
	
	chart_width_factor = 100; 
	var Qh_ref = 0;
	var azimutLetter = ['N', 'E', 'S', 'W'];
	for (i=1; i<=12; i++){
		Qt 		  	= (w_k_total-getFloat("sia_loss_a6")) * (inside_temperature - avg_outside_temperature[i-1]) * 24 
						* nb_days_in_month[i-1] * 3.6 / 1000 / heated_area;
		Qt_total 	+= Qt;
		Qv 			= getFloat("sia_loss_a6") * (inside_temperature - avg_outside_temperature[i-1]) * 24 
						* nb_days_in_month[i-1] * 3.6 / 1000 / heated_area; 
		Qv_total 	+= Qv;
		
		// solar gains calculation
		Qs = 0;
		for(index in windows){
			// TODO : take into account intermediate azimut like NW, SW, ...
			var azimutIndex = Math.round(windows[index]['azimut'] / 90);
			if (azimutIndex === 4){
				azimutIndex = 0;
			}
			var radiation = 'radiation' + azimutLetter[azimutIndex]; // ex : radiationE
			// ex : 'radiationN': {'month': [150, 213, 364, 443, 530, 537, 560, 493, 371, 254, 150, 121],
			var solarGain = (weatherSIA2028[station][radiation]['month'][i-1] * windows[index]['area'] 
							* (1-windows[index]['framepart']) * windows[index]['number'] * 0.9 
							* windows[index]['gg'] * windows[index]['fs']) / heated_area;
			Qs += solarGain;	
		}		

		Qs_total += Qs;

		if ((Qt+Qv) <= 0){
			ng = 0;
		} else {
			gamma = (Qi + Qs) / (Qt+Qv);
			if (gamma==1){
				ng = a / a+1;
			} else {
				ng = (1 - Math.pow(gamma, a)) / (1 - Math.pow(gamma, (a+1)));		
			}
		}
		
		Qi = Qi_total * nb_days_in_month[i-1] / 365;
		Qh = (Qt+Qv)-ng*(Qi+Qs);
		Qh_total += Qh;
		setFloat("sia_380_a"+i, Qt);
		setFloat("sia_380_b"+i, Qv);
		setFloat("sia_380_c"+i, Qi);
		setFloat("sia_380_d"+i, Qs);
		setFloat("sia_380_e"+i, ng);
		setFloat("sia_380_f"+i, Qh);
		if (i==1) {Qh_ref = Qh; }
		document.getElementById("sia_380_g"+i).width = Math.round(Qh / Qh_ref * chart_width_factor); 		
	}
	Qhli = standard_use_sia_380["cat_"+sia_category].qh_li + standard_use_sia_380["cat_"+sia_category].delta_qh_li * Ath_Ae;
	
	delta_t = standard_use_sia_380["cat_"+sia_category].ti - weatherSIA2028[station].temperature.cold;
	//todo inside_temperature - weatherSIA2028[station].temperature.cold;
	total_power = w_k_total * delta_t / 1000;
	
	setFloat("sia_380_384_201", Math.round(total_power));
	setInt("sia_380_specific_power", Math.round(total_power*1000 / heated_area));

	setFloat("sia_380_qh", Qh_total);
	setFloat("sia_380_qhli", Qhli);
	setFloat("sia_380_qww", Qww);
	setFloat("sia_380_qt", Qt_total); 
	setFloat("sia_380_qv", Qv_total); 
	setFloat("sia_380_qi", Qi_total); 
	setFloat("sia_380_qs", Qs_total); 
	setFloat("sia_380_ng", (Qt_total  + Qv_total - Qh_total) / (Qi_total + Qs_total)); 
	
}



var get_weight_factor = function (index){
	var factor = 0;
	if (index == 1){ factor = 2;}			// electricity
	else if (index == 2) {factor = 1; } 	// gas
	else if (index == 3) {factor = 1; }		// oil
	else if (index == 4) {factor = 0.7; }	// pellet
	else if (index == 5) {factor = 0.7; }	// wood
	else if (index == 6) {factor = 0.6; }	// waste heat
	return factor;
}

var calculate_minergie = function (){
	estimate_sia_380(""); // refresh calculation
	var specific_energy_use = [0,0,0,0];
	var energy_use = [0,0,0,0];
	var efficiency_factor = [0,0,0,0];
	var weight_factor = [0,0,0,0];
	var weighted_sum = [0,0,0,0];
	var minergie_sum = 0;
	var kwh_sum = 0; 
	var kwh_m2_sum = 0; 
	var hot_water_winter_ratio = 0.5;
	var solar_winter_ratio = 0.3; // solar hot water production : 70% summer months, 30% winter 
	var heated_area = getFloat("parameter_heated_area");
	var photovoltaic_area = 0;
	var solar_area = 0;
	var solar_production_summer = 0;
	var solar_production_winter = 0;
	if (document.getElementById('hvac_electricity_a1').checked){
		photovoltaic_area = getFloat('hvac_electricity_a2');
	}
	
	var heating_index = getString("hvac_heating_p1");
	var hot_water_winter_index = getString("hvac_heating_p2");
	var hot_water_summer_index = getString("hvac_heating_p3");
	
	// hot water winter :
	if ($('#hvac_heating_'+hot_water_winter_index+'8:checked').val() !== undefined) {
		solar_area = getFloat("hvac_heating_"+hot_water_winter_index+"9");
		solar_production_winter = (get_solar_production(solar_area) * solar_winter_ratio)  / heated_area; 
	}

	// hot water summer :
	if ($('#hvac_heating_'+hot_water_summer_index+'8:checked').val() !== undefined) {
		solar_area = getFloat("hvac_heating_"+hot_water_summer_index+"9");
		solar_production_summer = (get_solar_production(solar_area) * (1-solar_winter_ratio))  / heated_area; 
	}
	
	var specific_energy_use_ventilation = 0
	if(getInt("parameter_ventilation")==3){
		// mechanical ventilation : 0.35 W/m3h
		specific_energy_use_ventilation = (getInt("parameter_air_flow") * 0.35 * 8760 / 1000) / heated_area;
	} 

	specific_energy_use[0] = getFloat("sia_380_qh") / 3.6; // conversion kWh
	specific_energy_use[1] = (getFloat("sia_380_qww") * hot_water_winter_ratio / 3.6) - solar_production_winter ; // ww winter, conversion kWh
	specific_energy_use[2] = (getFloat("sia_380_qww") * (1-hot_water_winter_ratio) / 3.6) - solar_production_summer; // ww summer, conversion kWh
	if (specific_energy_use[1] < 0){
		specific_energy_use[1] = 0;
	}
	if (specific_energy_use[2] < 0){
		specific_energy_use[2] = 0;
	}
	specific_energy_use[3] = specific_energy_use_ventilation; 
	specific_energy_use[4] = get_photovoltaics_production(get_photovoltaics_power(photovoltaic_area)) / heated_area;
		
	efficiency_factor[0] = getFloat("hvac_heating_"+heating_index+"4"); // heating (hvac_heating_a4 or hvac_heating_b4)
	efficiency_factor[1] = getFloat("hvac_heating_"+hot_water_winter_index+"5"); // hot water winter
	efficiency_factor[2] = getFloat("hvac_heating_"+hot_water_summer_index+"5"); // hot water summer
	efficiency_factor[3] = 1; // ventilation
	efficiency_factor[4] = 1; // photovoltaic
	
	weight_factor[0] = get_weight_factor(getInt("hvac_heating_"+heating_index+"7"));
	weight_factor[1] = get_weight_factor(getInt("hvac_heating_"+hot_water_winter_index+"7"));
	weight_factor[2] = get_weight_factor(getInt("hvac_heating_"+hot_water_summer_index+"7"));
	weight_factor[3] = 2; // ventilation
	weight_factor[4] = -2; // photovoltaic
			
	
	var chart_width_factor = 200;		
	for (i=0; i<specific_energy_use.length; i++){
		energy_use[i] = specific_energy_use[i] * heated_area;
		kwh_sum += energy_use[i];
		kwh_m2_sum += specific_energy_use[i];		
		weighted_sum[i] = specific_energy_use[i] / efficiency_factor[i] * weight_factor[i];
		document.getElementById("minergie_f"+(i+1)).width = Math.round(Math.abs(weighted_sum[i]) / weighted_sum[0] * chart_width_factor); 
		setFloat("minergie_a"+(i+1), Math.round(energy_use[i]));
		setFloat("minergie_b"+(i+1), specific_energy_use[i]);
		setFloat("minergie_c"+(i+1), efficiency_factor[i]);
		setFloat("minergie_d"+(i+1), weight_factor[i]);
		setFloat("minergie_e"+(i+1), weighted_sum[i]); // kWh weighted
		minergie_sum = minergie_sum + weighted_sum[i];
	}	
	setFloat("minergie_a9", Math.round(kwh_sum));
	setFloat("minergie_b9", kwh_m2_sum);	
	setFloat("minergie_e9", minergie_sum);
}

var calculate_heating_power = function (fieldId){
	var heated_area	   = 0;
	var specific_power = 0;
	heated_area 	= getFloat("heating_p1");
	specific_power 	= getFloat("heating_p2");
	power 			= specific_power * heated_area / 1000;	
	setFloat("heating_p6", power);
	calculate_cost_heating(fieldId);
}

var calculate_cost_heating = function (field_id){
	var heating_only = 0;
	var power 		= 0;
	var energy_use  = 0;
	var altitude 	= 0;
	var power_conversion_factor = 0;
	var investment_cost = 0;
	var operating_cost  = 0;
	var total_cost 		= 0;
	var number_of_years = 0;
	var gas_price = 0;
	var oil_price = 0;
	var pellet_price = 0;
	var electricity_price_low = 0;
	var electricity_price_high = 0;
	var electricity_price_avg = 0;
	var chart_width_factor = 0;
	var gas_external_cost = 0;
	var electricity_external_cost = 0;
	var oil_external_cost = 0;
	var pellet_external_cost = 0;
	var external_cost = 0;
	var heated_area	   = 0;
	var specific_power = 0;	
	var cop_air = getFloat("heating_p20");
	var cop_water = getFloat("heating_p21");
	heated_area 	= getFloat("heating_p1");
	specific_power 	= getFloat("heating_p2");

	gas_external_cost = getFloat("heating_p15");
	electricity_external_cost = getFloat("heating_p16");
	oil_external_cost = getFloat("heating_p18");
	pellet_external_cost = getFloat("heating_p19");
	
	number_of_years = getInt("heating_p14");
	gas_price 	 = getFloat("heating_p9");
	oil_price 	 = getFloat("heating_p7") / 1000; // 1000 kWh per 100 L
	setFloat("heating_p12", oil_price);
	pellet_price = getFloat("heating_p8") / 5000; // 5000 kWh / tonne
	setFloat("heating_p13", pellet_price);
	electricity_price_high = getFloat("heating_p10");
	electricity_price_low  = getFloat("heating_p11");	
	heating_only	= getInt("heating_p3");
	altitude 		= getInt("heating_p4");
	power = getFloat("heating_p6");
	specific_power = power * 1000  / heated_area;	
	if (heating_only == 1) {heating_only = true;} else {heating_only = false;}
	energy_use = estimate_energy_use(power, altitude, heating_only);

	setFloat("heating_p5", energy_use);
	setFloat("heating_p30", (energy_use/3250)/0.75); // 3250 kWh/m3, 3/4 du silo utilisable
	
	
	electricity_price_avg = electricity_price_high * 0.666 + electricity_price_low * 0.3333;

	for (i=1; i<=6; i++){
		switch(i)
		{
		case 1: // gas
			investment_cost = Math.round(-0.211*power*power + 286.95*power + 18000);
			operating_cost = Math.round(number_of_years * energy_use * gas_price) +650; 
			external_cost = Math.round(number_of_years * energy_use * gas_external_cost);
			// use the first cost as a base for the chart width
			chart_width_factor = Math.round((investment_cost+operating_cost+external_cost)/100);
		  break;
		case 2: // oil 
			//20% more expensive than gas
			investment_cost = Math.round(1.2*(-0.211*power*power + 286.95*power + 18000));
			operating_cost = Math.round(number_of_years * energy_use * oil_price) +750; 
			external_cost = Math.round(number_of_years * energy_use * oil_external_cost);
		  break;
		case 3: // pellets
			investment_cost = Math.round(796.85*power + 40315);
			operating_cost = Math.round(number_of_years * energy_use * pellet_price) +750; 
			external_cost = Math.round(number_of_years * energy_use * pellet_external_cost);
		  break;
		case 4: // WP luft
			investment_cost = Math.round(864.86*power + 30000);
			operating_cost = Math.round(number_of_years * energy_use * electricity_price_avg / cop_air)+600; 
			external_cost = Math.round(number_of_years * energy_use * electricity_external_cost / cop_air);
		  break;
		case 5: // WP sole
			investment_cost = Math.round(2241.3*power + 35000);
			operating_cost = Math.round(number_of_years * energy_use * electricity_price_avg / cop_water)+400; 
			external_cost = Math.round(number_of_years * energy_use * electricity_external_cost / cop_water);
			// longueur des sondes geothermiques = puissance thermique / 40 W/m    ou   100 kWh/m de sonde
			var borehole_depth = Math.round(Math.max((power * 1000 * (1-(1/cop_water))) / getFloat("heating_p22"), (energy_use * (1-(1/cop_water))) / 100));
			setFloat("heating_p23", borehole_depth);
			setFloat("heating_p24", borehole_depth*80); // cost borehole = 80.-/m
			setFloat("heating_p25", borehole_depth*2); // circulator 2 W /m
			setFloat("heating_p26", power*200); // water flow 200 L/h
			setFloat("heating_p27", power*400); // water flow 400 L/h
			setFloat("heating_p28", Math.round(power)); // circulator power (W) = heating_power (kW)
			setFloat("heating_p29", Math.round(-0.0043*power*power+7.6*power+661)); // circulator cost
		  break;		
		case 6: // electric
			investment_cost = heated_area * 50; // 50.-/m2
			operating_cost = Math.round(number_of_years * energy_use * electricity_price_avg)+400; 
			external_cost = Math.round(number_of_years * energy_use * electricity_external_cost);
		  break;		
		default:
		} // end switch
		total_cost = investment_cost + operating_cost + external_cost;
		document.getElementById("heating_a"+i).value = investment_cost; // investitionskosten
		document.getElementById("heating_b"+i).value = operating_cost;	// betriebskosten
		document.getElementById("heating_c"+i).value = total_cost; // sum
		document.getElementById("heating_d"+i).width = Math.round(investment_cost / chart_width_factor); 
		document.getElementById("heating_e"+i).width = Math.round(operating_cost / chart_width_factor); 
		document.getElementById("heating_f"+i).width = Math.round(external_cost / chart_width_factor); 		
	}
		
} // end calculate_cost_heating

var filter_climate_station_list = function (source, target){
	var oWeatherStation = $('#'+target);
	oWeatherStation.html('');
	var stations = climateStationForCanton[$('#'+source).val()];
	for (var i in stations) {
		oWeatherStation.append('<option value="'+ stations[i] +'">'
		  + weatherSIA2028[stations[i]]['longName']  + ' ('  
		  + weatherSIA2028[stations[i]]['situation']['altitude']  + ' m, ' 
		  + weatherSIA2028[stations[i]]['temperature']['cold']  + '&deg;C)'  
		+'</option>');		
	}
}

var set_default_altitude = function (fieldId){
		var station = $("#building_climate_station").val();
		setInt(fieldId, weatherSIA2028[station]['situation']['altitude']);
}

var copy_string_value = function (from_field, to_field){
	setString(to_field, getString(from_field));
}

var copy_float_value = function (from_field, to_field){
		if (!isEmpty(getString(from_field))){
			setFloat(to_field, getFloat(from_field));
		}
}

var copy_data_to_measures = function (){
	for (i=1; i<=6; i++){
		// opake bauteile
		copy_string_value("building_element_a"+i, "aa"+i);
		copy_float_value("building_element_g"+i, "ab"+i);
		copy_float_value("building_element_d"+i, "ac"+i);
		
		// windows
		copy_string_value("building_window_a"+i, "fa"+i);
		copy_float_value("building_window_b"+i, "fb"+i);
		copy_float_value("building_window_c"+i, "fc"+i);
		copy_float_value("building_window_d"+i, "fd"+i);
	}
	//calculate_cost_windows("...");
	copy_float_value("parameter_heated_area", "ventilation_p1");
	copy_float_value("parameter_heated_area", "heating_p1");
	copy_float_value("parameter_heated_area", "hot_water_b1");
	copy_float_value("parameter_number_of_occupants", "hot_water_d1");

	//calculate_cost_ventilation("ventilation_p1");
}

var estimate_cop_air_heat_pump = function (output_temperature){ 
	var cop = 0;
	if ((output_temperature >= 28) && (output_temperature < 80)) {
		cop = 0.0013 * Math.pow(output_temperature,2) - 0.1682 * output_temperature + 7.6791;		
	}

	return cop; 
}

var estimate_cop_geo_heat_pump = function (output_temperature){
	var cop = 0;
	if ((output_temperature >= 28) && (output_temperature < 80)) {
		cop = 0.0012 * Math.pow(output_temperature,2) - 0.1684 * output_temperature + 8.1818;
	}
	return cop; 
}

var estimate_solar_panel_area = function (fieldId){	
	setFloat(fieldId, Math.round(getFloat('parameter_heated_area')/100)*2.5); // 2.5 m2 solar panel per 100 m2
}

var estimate_cop = function (fieldId){
	var heating_index = getInt(fieldId);
	var heating_temperature = 0;
	var hot_water_temperature = 55;
	var cop_heating = 0;
	var cop_hot_water = 0;
	
	var temperature_index = getInt("parameter_radiator");
	
	if (temperature_index == 1){
		heating_temperature = 60;
	} else if (temperature_index == 2){
		heating_temperature = 50;
	} else if (temperature_index == 3){
		heating_temperature = 40;
	} else if (temperature_index == 4){
		heating_temperature = 42;
	} else if (temperature_index == 5){
		heating_temperature = 35;
	} else if (temperature_index == 6){
		heating_temperature = 28;
	} else { // error
		heating_temperature = 0;
	}    
	
	if (heating_index == 1) {
		// old boiler
		cop_heating = 0.85;
		cop_hot_water = 0.75;
	} else if (heating_index == 2){
		// condensing boiler
		cop_heating = 0.95;
		cop_hot_water = 0.85;
	} else if (heating_index == 3){
		// kaminofen
		cop_heating = 0.8;
		cop_hot_water = 0.7;
	} else if (heating_index == 4){
		// electric
		cop_heating = 0.95;
		cop_hot_water = 0.9;
	} else if (heating_index == 5){
		// air heat pump
		cop_heating = estimate_cop_air_heat_pump(heating_temperature);
		cop_hot_water = estimate_cop_air_heat_pump(hot_water_temperature);
	} else if (heating_index == 6){
		// geothermal heat pump
		cop_heating = estimate_cop_geo_heat_pump(heating_temperature);
		cop_hot_water = estimate_cop_geo_heat_pump(hot_water_temperature);
	}
	
	// output to corresponding form fields :
	if (fieldId == "hvac_heating_a2") {  
		setFloat("hvac_heating_a4", cop_heating);
		setFloat("hvac_heating_a5", cop_hot_water);		
	} else if (fieldId == "hvac_heating_b2"){
		setFloat("hvac_heating_b4", cop_heating);
		setFloat("hvac_heating_b5", cop_hot_water);		
	}
	
}

var calculate_energy_use_ratio = function (fieldId){
	var heated_area	   = 0;
	var specific_power = 0;
	var heating_only = 0;
	var power 		= 0;
	var energy_use  = 0;
	var altitude 	= 0;
	var sum_energy_use = 0; 
	for (i=1; i<=5; i++){
		heated_area 	= getFloat("energy_use_ratio_a"+i);
		specific_power 	= getFloat("energy_use_ratio_b"+i);
		heating_only	= getInt("energy_use_ratio_c"+i);
		altitude 		= 500; // getInt("building_altitude"); // TODO : replace with real altitude  
		power 			= (specific_power / 1000) * heated_area;	
		if (heating_only == 1) {heating_only = true;} else {heating_only = false;}
		energy_use = estimate_energy_use(power, altitude, heating_only);
		if (isNaN(energy_use)){
			setFloat("energy_use_ratio_d"+i, 0);
			setFloat("energy_use_ratio_e"+i, 0);
		} else {			
			sum_energy_use += energy_use;
			setFloat("energy_use_ratio_d"+i, power);
			setFloat("energy_use_ratio_e"+i, energy_use);
		}
	}
	setFloat("energy_use_ratio_e6", sum_energy_use);
	var percentage = 0;
	for (i=1; i<=5; i++){
		percentage = getFloat("energy_use_ratio_e"+i) / sum_energy_use * 100;
		if (isNaN(percentage)){
			setFloat("energy_use_ratio_f"+i, 0);			
		} else {
			setFloat("energy_use_ratio_f"+i, percentage);			
		}
	}
}


var write_report = function (){
	div_output = document.getElementById("report_output");
	
	div_output.innerHTML = "<hr size='1' />";
	div_output.innerHTML += "<small>GEAK plus v.0.5 - " + get_today_formatted() + "</small>";
	
	div_output.innerHTML += "<img src='images/report_header.png' alt='GEAK plus' />";
	div_output.innerHTML += "<p style='text-align:center; font-weight:bold;'>" + getString("project_name") + "</p>"; 
	div_output.innerHTML += "<p><b>Auftraggeber :</b><br />" + getString("house_owner_first_name") +" "
		+ getString("house_owner_last_name") + "<br />" + getString("house_owner_address_street") 
		+ "<br />" + getString("house_owner_address_postal_code") + " " + getString("house_owner_address_city") 
		+ "<br />" +"T : " + getString("house_owner_phone") 
		+ "<br />" + getString("house_owner_email") + "</p>";		
	div_output.innerHTML += "<p><b>Objekt : </b><br />" + getString("building_address_street") 
		+"<br />" + getString("building_address_postal_code") + " " + getString("building_address_city") +  "</p>";
	div_output.innerHTML += "<p><b>Akten Nr : </b> "+getString("project_number") +"</p>";
	div_output.innerHTML += "<p><b>Energieberater : </b><br />"+ getString("expert_firm") 
		+ "<br />" + getString("expert_first_name") + " " + getString("expert_last_name")
		+ "<br />" + getString("expert_address_street") + "<br />" + getString("expert_address_postal_code") 
		+ " " +  getString("expert_address_city") + "<br />" + "T : "+ getString("expert_phone") 
		+ "<br />" + getString("expert_email") +  "</p>";
	div_output.innerHTML += "";
	div_output.innerHTML += "";
	div_output.innerHTML += "";
	div_output.innerHTML += "";


	div_output.innerHTML += "<hr size='1' />";	
}

var export_dynamic_table = function(id, prefix) {
	var result = '';
	var dynamicTable = new Object(); 
	var currentRow;
	var index = 0;
	$('#'+id+' tr.data').each(function(){	
		currentRow = new Object();
		$(this).find('input').each(function(){
			key = $(this).attr('class');
			value = $(this).val();
			currentRow[key] = value;
		});	
		$(this).find('select').each(function(){
			key = $(this).attr('class');
			value = $(this).val();
			currentRow[key] = value;
		});
	dynamicTable[prefix+'_'+index] = currentRow;
	index++;
	});
	result = JSON.stringify(dynamicTable); 
	result = '"dyn_'+ id + '" : ' + result + ', '
	//console.log(result); // debug
	return result;
}

var export_data = function (){
	var output_object = new Object();
	var prop = "";
	var input_withoud_id = "";
	var input_with_id = "";
	var type = '';
	$('#import_export').val('');

	// save dynamic tables (i.e where fields have no IDs):  
	input_withoud_id += export_dynamic_table('heatedareatable', 'ae');
	input_withoud_id += export_dynamic_table('opaqueelementstable', 'op');
	input_withoud_id += export_dynamic_table('windowconstructiontable', 'wc');
	input_withoud_id += export_dynamic_table('windowshadowtable', 'sh');
	input_withoud_id += export_dynamic_table('windowlisttable', 'wl');	
	input_withoud_id += export_dynamic_table('thermalbridgestable', 'tb'); 
	
	// export fields with unique IDs
	$(':input').each(function(){
		type = $(this).attr('type');
		if (!(type == 'button' || type == 'file' || type == 'hidden' || type == 'image' 
			|| type == 'password' || type == 'reset' || type == 'submit')){
				
				// OK if type = text, checkbox, radio, || or textarea, select, 
				// skip if type = button, file, hidden, image, password, reset, submit	
				
				prop = $(this).attr('id');
				if (prop != undefined){ // !isEmpty(prop)
					output_object[prop] = $(this).val();			
				}	
		}

	});
	
	input_with_id = JSON.stringify(output_object); // converts the object to a JSON string	
	input_with_id = '\n"inputs_with_id" : ' + input_with_id ;
	
	$('#import_export').val('{'+input_withoud_id + input_with_id + '}');
}


var import_data = function (){

	$('#building_canton').val('--');
	filter_climate_station_list('building_climate_station');
	var input_string = $('#import_export').val(); 
	var input_global_object = JSON.parse(input_string);
	var debug = "- Import log file -\n";
	
	var prop_name_array = new Object();
	for (prop in input_global_object) {
		var prop_name_array	= prop.split('_', 3);

		// either 'dyn_*' or 'inputs_with_id'
		if (prop_name_array[0] === 'dyn'){
			// import dynamic array 
			debug += "Importing table : " + prop_name_array[1] + '\n';
			// TODO : import with fill_table(table_selector, json_data)
			fill_table($('#'+ prop_name_array[1] +' .tableheader'), input_global_object[prop]);
			
		} else if (prop === 'inputs_with_id'){
			// import inputs with id
			debug += "\nFollowing (key : value) pairs imported : \n";
			var input_object = input_global_object[prop];
			for(property in input_object)
			{
				debug += property + " : "  + input_object[property] + "\n";
				if (property != null &&  [property] != null) {
					document.getElementById([property]).value = input_object[property]; 			
				}
			}
		} else {
			// error : unknown property name
		}
	} // end for loop
	calculate_fs1();
	document.getElementById("import_export").value = debug;
}

var set_default_hw_usage = function (source, field1, field2, field3){
	//alert('fonction set_default_hw_usage en cours..');
	var result = $('#'+source).val().split('-');
	//alert(result[0],'-', result[1],'-',result[2]);
	setString(field1, result[0]);
	setString(field2, result[1]);
	setString(field3, result[2]);	
	estimate_hw();
}

var estimate_hw = function (){
	var hw_heating_power = 0;
	var hw_temperature_cold_water = getFloat("hw_temperature_cold_water");
	var hw_temperature_hot_water_used = getFloat("hw_temperature_hot_water_used");
	var hw_temperature_hot_water_stored = getFloat("hw_temperature_hot_water_stored");
	var hw_boiler_efficiency = getFloat("hw_boiler_efficiency");
	var hw_instant_usage = getFloat("hw_instant_usage");
	var hw_hour_usage = getFloat("hw_hour_usage"); 
	var hw_day_usage = getFloat("hw_day_usage");
	var hw_boiler_load_time = 0; 
	var hw_boiler_capacity = 0; 
	var hw_power = 0;
	var hw_power_eco = 0;
	var hw_power_normal = 0;
	var water_thermal_capacity = 1.16; // 	Wh/L K	= constant

	if ($('#hw_radio_custom_power').is(':checked')){
		hw_heating_power = getFloat("hw_heating_power");
	} else {  // hw_radio_default_power = checked  
		hw_heating_power = getFloat("sia_380_384_201");
	}

	if ($('#hw_instant_production').is(':checked')){
		hw_boiler_load_time = 0.167; // 10 minutes = 0.17 h
		hw_power = (water_thermal_capacity * hw_instant_usage * (hw_temperature_hot_water_used - hw_temperature_cold_water) / 1000)/ hw_boiler_load_time;		
		hw_boiler_capacity = Math.round(hw_instant_usage / hw_boiler_efficiency);
		hw_power_normal =  Math.max(hw_heating_power, hw_heating_power*0.85+hw_power);
		hw_power_eco = hw_power_normal;
	} else if ($('#hw_hour_production').is(':checked')){
		hw_boiler_load_time = 1; // Selon SIA 384/1 point 2.31 : 1h si rechauffage diurne, 2h sinon
		hw_boiler_capacity = Math.round((((hw_temperature_hot_water_used - hw_temperature_cold_water)/
			(hw_temperature_hot_water_stored - hw_temperature_cold_water))*hw_hour_usage)/hw_boiler_efficiency);
		hw_power =(water_thermal_capacity*hw_boiler_capacity*(hw_temperature_hot_water_stored-hw_temperature_cold_water)/1000)/hw_boiler_load_time;
		hw_power_normal =  Math.max(hw_heating_power, hw_heating_power*0.85+hw_power);
		hw_power_eco = hw_power_normal;
	} else { // hw_day_production = checked
		hw_boiler_load_time = 4; // 4h
		hw_boiler_capacity =Math.round((((hw_temperature_hot_water_used-hw_temperature_cold_water)/
			(hw_temperature_hot_water_stored-hw_temperature_cold_water))*hw_day_usage)/hw_boiler_efficiency);
		hw_power =(water_thermal_capacity*hw_boiler_capacity*(hw_temperature_hot_water_stored-hw_temperature_cold_water)/1000)/hw_boiler_load_time;
		hw_power_normal = Math.max(hw_heating_power, hw_heating_power*0.85+hw_power);		
		hw_power_eco = Math.max(hw_power, hw_heating_power);
	}
	
	setFloat("hw_boiler_load_time", hw_boiler_load_time);
	setFloat("hw_boiler_capacity", hw_boiler_capacity);
	setFloat("hw_power", hw_power);
	setFloat("hw_power_eco", hw_power_eco);
	setFloat("hw_power_normal", hw_power_normal);
	
}

var estimate_hw_time = function (){
	// temps de charge [h] = 1.16 [Wh /LK]  * volume [L] * delta T entre l'eau froide et chaude [K] / puissance [W]
	var water_thermal_capacity = 1.16; // [Wh / L K]
	var hw_time_temp_high = getFloat("hw_time_temp_high");
	var hw_time_boiler_capacity = getFloat("hw_time_boiler_capacity");
	var hw_time_power = getFloat("hw_time_power");
	var hw_time_temp_low = getFloat("hw_time_temp_low");
	var hw_time_load = water_thermal_capacity * hw_time_boiler_capacity * (hw_time_temp_high - hw_time_temp_low) / 
	(hw_time_power *1000); // 1 kW = 1'000 W

	setFloat("hw_time_load", hw_time_load);

}

var plot_fs1 = function (){
	var data = [{label:"horizon", data : [[0, $('#fs1_angle_0').val()],[45, $('#fs1_angle_1').val()],
		[90, $('#fs1_angle_2').val()],[135, $('#fs1_angle_3').val()],[180, $('#fs1_angle_4').val()],
		[225, $('#fs1_angle_5').val()],[270, $('#fs1_angle_6').val()],[315, $('#fs1_angle_7').val()]]}];

	var options = {
    series: {
		color : "rgb(180, 180, 180)",
		lines: { show: true, fill : true, fillColor : "rgb(204, 204, 204)" },
		points: { show: false, fill : true, fillColor : "rgb(204, 204, 204)" }
    },
	xaxis:{
			ticks: [[0, "N"], [45, "N-E"], [90, "E"], [135, "S-E"], [180, "S"], [225, "S-W"], [270, "W"], [315, "N-W"]]
		
	},
	yaxis:{ ticks : [0,10,20,30,40] }
	
  };

	$.plot($("#graph_fs1"), data, options);
}

var calculate_fs1_alpha = function () {
	var alpha = 0;
	var h1 = $('#fs1_h1').val() *1;
	var h2 = $('#fs1_h2').val() *1;
	var l  = $('#fs1_l').val() *1;
	var h  = h2 - 0.5 * h1;
	if ((h > 0) && (l > 0)) {
		alpha = Math.round(Math.atan(h/l)*180/Math.PI);	
	}
	$('#fs1_alpha').val(alpha);
}



var get_fs1_factor = function (fs1_angle, azimut) {	
	// azimut between 0 and 360�
	// fs1_angle between 0 and 90�		
	var fs1_table = []; // N , NE, E, SE, S 
	fs1_table[0] = [1,1,1,1,1];
	fs1_table[1] = [1,0.97,0.94,0.95,0.96];
	fs1_table[2] = [0.97,0.89,0.81,0.82,0.82];
	fs1_table[3] = [0.94,0.81,0.68,0.63,0.59];
	fs1_table[4] = [0.9,0.75,0.6,0.53,0.45];

	var fs1_index = Math.round(fs1_angle / 10);
	if (fs1_index > 4) {fs1_index = 4;}
	
	if (azimut > 180){
		azimut = 360 - azimut;
	}
	
	var azimut_index = Math.round(azimut / 45);
	
	return fs1_table[fs1_index][azimut_index];
};

var calculate_fs1 = function () {
	for (var i=0; i<=7; i++){ 
		$('#fs1_factor_'+i).val(get_fs1_factor($('#fs1_angle_'+i).val(), i*45));			
	}
	plot_fs1();
};

var fill_fs1_angle = function () {
	var angle = $('#fs1_situation').val();
	for (var i=0; i<=7; i++){ 
		$('#fs1_angle_'+i).val(angle);				
	}
	calculate_fs1();
}

var get_fs23_factor = function(data){
	var fs2 = 0;  // between 0 and 1
	var fs3 = 0;  // between 0 and 1
	var fs31 = 0;  // between 0 and 1
	var fs32 = 0;  // between 0 and 1
	var beta = 0;  	// between 0 and 90�
	var gamma1 = 0; // between 0 and 90�
	var gamma2 = 0;	// between 0 and 90�
	var A = parseFloat(data['a']); // distance du surplomb
	var B = parseFloat(data['b']); // longueur du surplomb
	var C = parseFloat(data['c']); // distance �cran lat�ral gauche
	var D = parseFloat(data['d']); // longueur �cran lat�ral gauche
	var E = parseFloat(data['e']); // distance �cran lat�ral droit
	var F = parseFloat(data['f']); // longueur �cran lat�ral droit
	var G = parseFloat(data['g']); // facteur de voilage
	var H = parseFloat(data['h']); // hauteur de la fenetre
	var L = parseFloat(data['l']); // largeur de la fenetre
	var azimut = parseFloat(data['azimut']); // between 0 and 360�
	var azimut_symetric = 0;
	var fs2_table = []; // N , NE, E, SE, S 
	fs2_table[0]=[1,1,1,1,1];
	fs2_table[1]=[0.96,0.955,0.95,0.95,0.95];
	fs2_table[2]=[0.91,0.9,0.89,0.9,0.91];
	fs2_table[3]=[0.8,0.785,0.77,0.76,0.75];
	fs2_table[4]=[0.66,0.625,0.59,0.555,0.52];
	var fs31_table = []; // N , NE, E, SE, S, SW, W, NW
	fs31_table[0]=[1,1,1,1,1,1,1,1]; // 0�
	fs31_table[1]=[1,1,1,0.985,0.97,0.965,0.96,0.98]; // 15�
	fs31_table[2]=[1,1,1,0.97,0.94,0.93,0.92,0.96]; // 30�
	fs31_table[3]=[1,1,1,0.92,0.84,0.84,0.84,0.92]; // 45�
	fs31_table[4]=[1,1,1,0.86,0.72,0.735,0.75,0.875]; // 60�
	var fs32_table = []; // N , NE, E, SE, S, SW, W, NW
	fs32_table[0]=[1,1,1,1,1,1,1,1]; // 0�
	fs32_table[1]=[1,0.98,0.96,0.965,0.97,0.985,1,1]; // 15�
	fs32_table[2]=[1,0.96,0.92,0.93,0.94,0.97,1,1]; // 30�
	fs32_table[3]=[1,0.92,0.84,0.84,0.84,0.92,1,1]; // 45�
	fs32_table[4]=[1,0.875,0.75,0.735,0.72,0.86,1,1]; // 60�
	
	// calculate angles with dimensions of the lateral and horizontal shadings
	
	beta = Math.round(Math.atan(B/((H/2)+A))*180/Math.PI);
	
	gamma1 = Math.round(Math.atan(D/((L/2)+C))*180/Math.PI);
	gamma2 = Math.round(Math.atan(F/((L/2)+E))*180/Math.PI);

	var fs2_index = Math.round(beta / 15); 	// round angle to closest 15�
	if (fs2_index > 4) {fs2_index = 4;}
	if (azimut > 180){
		azimut_symetric = 360 - azimut;
	} else {
		azimut_symetric = azimut;
	}
	var azimut_index = Math.round(azimut_symetric / 45);
	fs2 = fs2_table[fs2_index][azimut_index];
	//console.log('fs2_index : ', fs2_index, 'azimut_index : ', azimut_index);

	var fs31_index = Math.round(gamma1 / 15); 	// round angle to closest 15�
	if (fs31_index > 4) {fs31_index = 4;}
 	azimut_index = Math.round(azimut / 45);
	fs31 = fs31_table[fs31_index][azimut_index];

	var fs32_index = Math.round(gamma2 / 15); 	// round angle to closest 15�
	if (fs32_index > 4) {fs32_index = 4;}
 	//azimut_index = Math.round(azimut / 45);
	fs32 = fs32_table[fs32_index][azimut_index];
 
	var fs = {'fs2': fs2, 'fs3': fs31*fs32} // TODO : take G into account (facteur de voilage)
	return fs;
}

var editTable = function(target){
	$(target).closest('table').find('.data .deletable').slideToggle('fast');	
	$(target).closest('table').find('.trash').toggle();
	$(target).closest('table').find('.ok').toggle();
	$(target).closest('table').find('.addrow').toggle();
	$(target).closest('table').find('.reset').toggle();
	return false;	
}

var addRow = function(target, data){
	//$(target).closest('div').find('.areafooter').before(createAreaRow());
	var $newRow = $(target).closest('table').find('.template').clone(true);
    $newRow.removeClass('template').addClass('data'); //.show();
	for (var i in data) {
		//console.log('i', i, 'data[i] : ', data[i] );
		$newRow.find('.'+i).val(data[i]);		
	}
	$(target).closest('table').find('.tablefooter').before($newRow);
}

var removeRow = function (target){
	var currentRow = $(target).closest('tr');
	currentRow.fadeOut(200, function () {
		var currentPosition = currentRow.closest('table').find('.template'); 
        currentRow.remove();
		// TODO : updateAreaTable(currentPosition);
      });	
}

var removeSelectedRows = function (target){
	$(target).closest('table').find('tr.data').each(function(){
		isChecked = $(this).find('input.check_delete').attr('checked');
		if (isChecked){
			$(this).remove();
		}
	});
}

var copy_area = function (caller){
	setFloat("parameter_heated_area", $(caller).closest('table').find('.area_total').val());
}


var updateAreaTable = function (target){
	var sum = 0;
	var partial_sum = 0;
	$(target).closest('table').find('tr.data').each(function(){
		partial_sum = $(this).find(".sign").val() * $(this).find(".number").val() * $(this).find(".width").val() * $(this).find(".length").val();
		sum = sum + partial_sum;
		$(this).find(".area").val(partial_sum); 
	});
	$(target).closest('table').find('.area_total').val(sum);
}

var createSelectFromTable = function(source, target){
	var sourceFields  = $(source);
	var targetSelect = $(target);
	targetSelect.html('');
	sourceFields.each(function(){
		var uniqueid = $(this).closest('td').find('.uniqueid').val();
		targetSelect.append('<option value="'+uniqueid+'">'+$(this).val()+'</option>');
	});
}

var updateElementsLists = function(){
	createSelectFromTable('#windowconstructiontable .data .name', '#windowlisttable .windowtypeselect');
	createSelectFromTable('#windowshadowtable .data .name', '#windowlisttable .windowshadowselect');
	createSelectFromTable('#opaqueelementstable .data .name', '#windowlisttable .opaqueelementsselect');

}

var openwindrose = function(){
	 $('#windrose').dialog('open');	
}

var getUniqueId = function(){
	var newDate = new Date;
	return 'uid-' + newDate.getTime();
}

var updateId = function(source, target){
	//var id = $(source).attr('id');
	var idfield =  $(source).closest('td').find('.uniqueid');	
	var id = idfield.val();
	if (id === undefined || id === '' || id === null){
		//console.log('No ID attribute set so far..');
		var uniqueId = getUniqueId();
		idfield.val(uniqueId);
		//$(source).attr('id', uniqueId); 
		$('#windowlisttable .'+target).append('<option value="'+uniqueId+'">'+$(source).val()+'</option>')
	} else {
		//console.log('One ID found : ', $(source).attr('id'));
		$('#windowlisttable .'+target).find('option[value="'+ id +'"]').text($(source).val());
	}
}

var updateTilt = function(target){
	var selection = $(target).val();
	var tiltValue = 0;
	if (selection==1){ // roof
		tiltValue = 30;
	} else if (selection==2){ // wall
		tiltValue = 90;			
	} else {
		tiltValue = 0;
	}
	
	$(target).closest('tr').find('.tilt').val(tiltValue);
}

var rotateBuilding = function(question, target){
	var angle = prompt(question,"45");
	var azimut = 0;
	$(target).closest('table').find('tr.data').each(function(){
		azimut = $(this).find(".azimut");
		azimut.val(((1*azimut.val()) + (1*angle) + 360) % 360);
	});
}

var calculate_horizon_blocking = function(){
	$("#transferHorizonButton").hide();
	$('#horizon_spinner').show();
	$.ajax({ 
		type: "POST", 
		url: "horizon_webservice.php",
		dataType : 'json',
		data: {
			lat : $('#ch1903_lat').val(),
			lng : $('#ch1903_lng').val()
		},
		success: function(data){ 
			$('#horizon_spinner').hide();
			if(!data.error) { // php ajax query succeeded
				
				$('#ch1903_altitude').val(data.originAltitude);
				var serie1 = [];
				for(var index in data.horizon) {
					serie1.push([index*1, data.horizon[index]]);
				}
				//console.log(serie1);
				
				var graph_data = [{label:"horizon", data : serie1}];

				var options = {
					series: {
						color : "rgb(180, 180, 180)",
						lines: { show: true, fill : true, fillColor : "rgb(204, 204, 204)" },
						points: { show: false }
					},
					xaxis:{
						ticks: [[0, "N"], [45, "N-E"], [90, "E"], [135, "S-E"], [180, "S"], [225, "S-W"], [270, "W"], [315, "N-W"]]
					},
					yaxis:{ ticks : [0,10,20,30,40] }
				}; // yaxis max: 45, min: 0

				$.plot($("#graph_horizon"), graph_data, options);
				if (window.opener && !window.opener.closed){
					var res = confirm("Copy horizon and close window ?");
					if (res==true){
						window.opener.$('#fs1_angle_0').val(data.horizon['0']);
						window.opener.$('#fs1_angle_1').val(data.horizon['45']);
						window.opener.$('#fs1_angle_2').val(data.horizon['90']);
						window.opener.$('#fs1_angle_3').val(data.horizon['135']);
						window.opener.$('#fs1_angle_4').val(data.horizon['180']);
						window.opener.$('#fs1_angle_5').val(data.horizon['225']);
						window.opener.$('#fs1_angle_6').val(data.horizon['270']);
						window.opener.$('#fs1_angle_7').val(data.horizon['315']);	
						window.opener.calculate_fs1();
						window.close();
					}
			  	}

			} else { // PHP ajax query failed
				$("#horizon_result").html("<p>Error : "+data.msg+"</p>");
			}
		},
		error : function(XMLHttpRequest, textStatus, errorThrown) {
			$('#horizon_spinner').hide();
			$("#horizon_result").html("<p>Ajax Error</p>");


		}
	});
	return false;
}

// Convert WGS lat/long (� dec) to CH y
function WGStoCHy(lat, lng) {
  // Converts degrees dec to sex
  lat = DECtoSEX(lat);
  lng = DECtoSEX(lng);
  // Converts degrees to seconds (sex)
  lat = DEGtoSEC(lat);
  lng = DEGtoSEC(lng);
  // Axiliary values (% Bern)
  var lat_aux = (lat - 169028.66)/10000;
  var lng_aux = (lng - 26782.5)/10000;
  // Process Y
  y = 600072.37 
     + 211455.93 * lng_aux 
     -  10938.51 * lng_aux * lat_aux
     -      0.36 * lng_aux * Math.pow(lat_aux,2)
     -     44.54 * Math.pow(lng_aux,3);
  return y;
}

// Convert WGS lat/long (� dec) to CH x
function WGStoCHx(lat, lng) {
  // Converts degrees dec to sex
  lat = DECtoSEX(lat);
  lng = DECtoSEX(lng);
  // Converts degrees to seconds (sex)
  lat = DEGtoSEC(lat);
  lng = DEGtoSEC(lng);
  // Axiliary values (% Bern)
  var lat_aux = (lat - 169028.66)/10000;
  var lng_aux = (lng - 26782.5)/10000;
  // Process X
  x = 200147.07
     + 308807.95 * lat_aux 
     +   3745.25 * Math.pow(lng_aux,2)
     +     76.63 * Math.pow(lat_aux,2)
     -    194.56 * Math.pow(lng_aux,2) * lat_aux
     +    119.79 * Math.pow(lat_aux,3);
  return x;  
}

// Convert CH y/x to WGS lat
function CHtoWGSlat(y, x) {
  // Converts militar to civil and  to unit = 1000km
  // Axiliary values (% Bern)
  var y_aux = (y - 600000)/1000000;
  var x_aux = (x - 200000)/1000000;
  // Process lat
  lat = 16.9023892
       +  3.238272 * x_aux
       -  0.270978 * Math.pow(y_aux,2)
       -  0.002528 * Math.pow(x_aux,2)
       -  0.0447   * Math.pow(y_aux,2) * x_aux
       -  0.0140   * Math.pow(x_aux,3);
  // Unit 10000" to 1 " and converts seconds to degrees (dec)
  lat = lat * 100/36;
  return lat;
}

// Convert CH y/x to WGS long
function CHtoWGSlng(y, x) {
  // Converts militar to civil and  to unit = 1000km
  // Axiliary values (% Bern)
  var y_aux = (y - 600000)/1000000;
  var x_aux = (x - 200000)/1000000;
  // Process long
  lng = 2.6779094
        + 4.728982 * y_aux
        + 0.791484 * y_aux * x_aux
        + 0.1306   * y_aux * Math.pow(x_aux,2)
        - 0.0436   * Math.pow(y_aux,3);
  // Unit 10000" to 1 " and converts seconds to degrees (dec)
  lng = lng * 100/36;
  return lng;  
}

// Convert SEX DMS angle to DEC
function SEXtoDEC(angle) {
  // Extract DMS
  var deg = parseInt( angle );
  var min = parseInt( (angle-deg)*100 );
  var sec = (((angle-deg)*100) - min) * 100;
  // Result in degrees sex (dd.mmss)
  return deg + (sec/60 + min)/60;
}

// Convert DEC angle to SEX DMS
function DECtoSEX(angle) {
  // Extract DMS
  var deg = parseInt( angle );
  var min = parseInt( (angle-deg)*60 );
  var sec =  (((angle-deg)*60)-min)*60;
  // Result in degrees sex (dd.mmss)
  return deg + min/100 + sec/10000;
}

// Convert Degrees angle to seconds
function DEGtoSEC(angle) {
  // Extract DMS
  var deg = parseInt( angle );
  var min = parseInt( (angle-deg)*100 );
  var sec = (((angle-deg)*100) - min) * 100;
  // Result in degrees sex (dd.mmss)
  return sec + min*60 + deg*3600;
}


// SUMMER COMFORT

function calculate_solar_gains(){
	// Protection solaire ouverte (moins de 150 W/m2) :
	// N, NE, E, SE, S, SW, W, NW, H
	var solar_less_150_w = new Array(1183, 744, 598, 510, 377, 507, 617, 768, 244);
	// 	Protection solaire fermée (plus de 150 W/m2) :
	var solar_more_150_w = new Array(521,1607, 2692, 3184, 3194, 3145, 2646, 1585,5402);
	// facteur de pondération pour le calcul de la puissance max
	var weight_factor_radiation = new Array(0.2, 0.5, 0.8, 1, 0.8, 1, 0.8, 0.5, 1.2);
	var solar_power_factor_direct = 0.7; // max 900 W/m2 direct
	var solar_power_factor_diffuse = 0.23; // max 200 W/m2 diffuse
	
	var solar_power = 0;
	var solar_power_max = 0;
	
	var heated_area = getFloat("solar_gain_p1")
	var g_value_glazing = $('#solar_gain_p2').val()*1;
	var glazing_factor = (1-(getFloat("solar_gain_p3")/100)) ;
	var glazing_area = 0;
	var g_value_with_shading = 0;
	var shading_factor = 0;
	var solar_gain = 0;
	var solar_gain_sum = 0;
	var window_area_sum = 0;
	var window_area = 0;

	for (var i=1; i<=9; i++){
		window_area = getFloat("solar_gain_b"+i);
		window_area_sum += window_area;		
	}
	
	for (var i=1; i<=9; i++){
		window_area = getFloat("solar_gain_b"+i);
		glazing_area = window_area * glazing_factor;
		g_value_with_shading = $('#solar_gain_c'+i).val()*1;
		if(g_value_with_shading == 1){
			g_value_with_shading = g_value_glazing;
		}
		shading_factor = getFloat("solar_gain_d"+i);
		// solar power (direct + diffuse)
		solar_power = (glazing_area * g_value_with_shading * shading_factor * solar_power_factor_direct) 
						+ ((window_area_sum*glazing_factor)-glazing_area)*g_value_glazing * solar_power_factor_diffuse;
		solar_power = solar_power * weight_factor_radiation[i-1];
		if (window_area == 0){
			solar_power = 0;
		}
		//glazing_area * g_value_with_shading * shading_factor * weight_factor_radiation[i-1] * solar_power_factor;
		setFloat("solar_gain_e"+i, solar_power);
		if (solar_power > solar_power_max){
			solar_power_max = solar_power;
		}
		// solar gains
		solar_gain = (((g_value_glazing * solar_less_150_w[i-1]) + (g_value_with_shading * solar_more_150_w[i-1])) 
					* glazing_area * shading_factor) / heated_area;
		solar_gain_sum += solar_gain;
		setFloat("solar_gain_f"+i, solar_gain);
	}
	setFloat("solar_gain_b10", window_area_sum);
	setFloat("solar_gain_e10", solar_power_max);		
	setFloat("solar_gain_f10", solar_gain_sum);
	calculate_results();
}

function calculate_internal_gains(){
	var power = 0;
	var power_sum = 0;
	var specific_power = 0;
	var specific_power_sum = 0;		
	var heated_area = getFloat("solar_gain_p1");
	var internal_gain = 0;
	var internal_gain_sum = 0;
	var electricity_calculated = 0;
	var electricity_calculated_partial = 0;
	
	var electricity_real = getFloat("electricity_real");
	var hours = 0;
	
	for (var i=1; i<=4; i++){
		power = (getFloat("internal_gain_a"+i) * getFloat("internal_gain_b"+i))/1000;
		if (isNaN(power)){power=0;}
		setFloat("internal_gain_d"+i, power);
		power_sum += power;
		specific_power = power*1000/heated_area;
		setFloat("internal_gain_e"+i, specific_power);
		specific_power_sum += specific_power;		
		hours = getFloat("internal_gain_c"+i);	
		internal_gain = power * 1000 * hours / heated_area;
		if (isNaN(internal_gain)){internal_gain=0;}
		setFloat("internal_gain_f"+i, internal_gain);	 
		internal_gain_sum += internal_gain;
		if (i>1){
			// calculate electricity use
			electricity_calculated_partial = getFloat('number_of_days')*hours*power;
			if (!isNaN(electricity_calculated_partial)){
				electricity_calculated += electricity_calculated_partial;					
			}
		}
	}
	setFloat("internal_gain_d5", power_sum);	 
	setFloat("internal_gain_e5", specific_power_sum);	 
	setFloat("internal_gain_f5", internal_gain_sum);	 

	setFloat("electricity_calculated", electricity_calculated);	 

	setFloat("electricity_diff", 100*(electricity_calculated-electricity_real)/electricity_real);		
	calculate_results();
}

var arrayMax = function(myArray) {
	var max = myArray[0];
	var len = myArray.length;
	for (var i = 1; i < len; i++) if (myArray[i] > max) max = myArray[i];
	return max;
}

function calculate_results(){
	var gains_array = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0);
	var gains_total = 0;
	var max_value = 0;
	var chart_width_factor = 400; // width in px
	var heated_area = getFloat("solar_gain_p1");
	var cooling_power = 0;
	var cooling_avg = 0;
			
	for (var i=1; i<=4; i++){
		gains_array[i-1] = getFloat("internal_gain_f"+i);
	}

	for (var i=1; i<=9; i++){
		gains_array[i+3] = getFloat("solar_gain_f"+i);
	}
	
	max_value = arrayMax(gains_array);
	
	for (var i=1; i<=13; i++){
		gains_total += gains_array[i-1];
		document.getElementById("graph_gain_"+i).width = Math.round(chart_width_factor*gains_array[i-1]/max_value);
	}		
	cooling_power = (getFloat("solar_gain_e10") + getFloat("internal_gain_d5")); 
	cooling_avg = (gains_total * heated_area / 24)/1000  ; // 24 h, W -> kW
	setFloat("graph_gain_0", gains_total);
	setFloat("cooling_power_a1", cooling_power);
	setFloat("cooling_power_b1", cooling_power*1000/heated_area);
	setFloat("cooling_power_a2", cooling_avg);	
	setFloat("cooling_power_b2", cooling_avg*1000/heated_area);
	setFloat("cooling_power_a3", cooling_power*0.45);
	setFloat("cooling_power_b3", cooling_power*0.45*1000/heated_area);
	setFloat("cooling_power_a4", cooling_power*0.7);
	setFloat("cooling_power_b4", cooling_power*0.7*1000/heated_area);
		
}

function fill_all_summer(){
	setString("solar_gain_p1", "170");
	setString("solar_gain_p3", "30");
	
	setString("solar_gain_b1", "24");
	setString("solar_gain_b2", "0");
	setString("solar_gain_b3", "18");
	setString("solar_gain_b4", "9");
	setString("solar_gain_b5", "15");
	setString("solar_gain_b6", "0");
	setString("solar_gain_b7", "15");
	setString("solar_gain_b8", "0");
	setString("solar_gain_b9", "0");

	setString("solar_gain_d1", "1");
	setString("solar_gain_d2", "1");
	setString("solar_gain_d3", "0.8");
	setString("solar_gain_d4", "1");
	setString("solar_gain_d5", "1");
	setString("solar_gain_d6", "1");
	setString("solar_gain_d7", "0.35");
	setString("solar_gain_d8", "1");
	setString("solar_gain_d9", "1");
	
	setString("internal_gain_a1", "5");
	setString("internal_gain_a2", "14");
	setString("internal_gain_a3", "17");
	setString("internal_gain_a4", "0");

	setString("internal_gain_b1", "80");
	setString("internal_gain_b2", "100");
	setString("internal_gain_b3", "60");
	setString("internal_gain_b4", "0");

	setString("internal_gain_c1", "10");
	setString("internal_gain_c2", "10");
	setString("internal_gain_c3", "10");
	setString("internal_gain_c4", "10");
	
	setString("number_of_days", "300");
	setString("electricity_real", "8920");
		
	calculate_solar_gains();
	calculate_internal_gains();
	
}


