// Rotor with surface mounted magnets radially magnetized
//console.log("------ start script ------");
// Copyright 2018-2024, Vladimir Kuptsov
include('..\\sDraw.js');

function Rotor()
{ 
	// Rotor inner radius
	this.Rrinner = motor.rotorInnerRadius;
	// Rotor outer radius
	this.Rrouter = motor.rotorOuterRadius;
	// Number of pole pairs
	this.Npp = motor.rotorNumberPolePairs;
	//Air gap length
	var lag = motor.airGap;
	
	// Default rotor dimensions:
	// Magnet depth:
	this.Dpm = 5*lag;
	// Magnet angle:
	this.Apm = 130;
	// Magnet fillet radius
	this.Fpm = 0;
	// Magnet inset depth
	this.Dis = 0;
	// Magnetization: "Radial" | "Parallel"
	this.Magnetization = "Radial";
	// Retaining sleeve type: "Non-conductive or no retaining sleeve" | "Conductive retaining sleeve"
	this.RetainingSleeveType = "Non-conductive or no retaining sleeve";
	// Retaining sleeve thickness
	this.Trs = 0;	
	this.R_3_1 = null; //Свойство хранения радиуса дуги воздушного пространства
	
};

/**
* Статический метод определения максимального радиуса скругления между двумя кругами с одним центром
*
*/
Rotor.prototype.getMaxRadiusFilletByRadiuses = function(radius_1, radius_2, type){
	switch(type){
	case 'inner':
		return (radius_1 * radius_1 - radius_2 * radius_2)/(2 * radius_1);
	case 'outer':
		return (radius_1 * radius_1 - radius_2 * radius_2)/(2 * radius_2);
	}
}

Rotor.prototype.bildFilletIntersection = function (){
	var g1 = couplingSegments(this.line_5_2, this.arc_2_1, this.fpm_tmp); 
	this.geomr.push(g1[0]);
	this.geomr.push(g1[1]);
	this.geomr.push(g1[2]);
	
	this.arc_fpm = g1[2];
	
	this.p_line_5_2 = g1[0];
}

Rotor.prototype.calcRealDis = function (){
	this.dis_r = this.Dis;
	this.full_sinking = false;
	this.R_low_general_limit = null;
	if(this.p_line_5_2 == null){
		//Радиус скругления максимальный и соответственно линии 5-2 нет
		this.dis_r = 0;
	}else if(this.p_line_5_2 !== null){
		this.R_low_general_limit = calcLengthBy2Points(0, 0, this.p_line_5_2.p1.x(), this.p_line_5_2.p1.y());
		var len_line_5_2 = this.p_line_5_2.length;
		if(len_line_5_2 <= this.dis_r){
			if(this.fpm_tmp > 0.001){
				console.warn('Insert depth was reduced not to overlap the magnet fillet.');
			}else{
				this.full_sinking = true;
			}
			this.dis_r = len_line_5_2;
		}
	}
}


// generate rotor geometry 
// call from с++ code
Rotor.prototype.getGeometry = function (){
	// Machine type: InnerRotor | OuterRotor
	var machineType = motor.machineType;
	// Rotor inner radius
	this.Rrinner = motor.rotorInnerRadius;
	// Rotor outer radius
	this.Rrouter = motor.rotorOuterRadius; 
	// Number of pole pairs
	this.Npp = motor.rotorNumberPolePairs;
	// Air gap length
	this.lag = motor.airGap;
	
	// draw rotor geometry
	this.geomr = new Array;
	
	var point_0 = new QPointF(0, 0);
	
	var alfa = 360/this.Npp/4;
	var alfa_pm = alfa*(this.Apm/180);
	var beta = alfa_pm + (alfa-alfa_pm)/2;
	var line_0_3 = sDraw.createLineByPointAngle(0, 0, 90-alfa);
	var line_0_2 = sDraw.createLineByPointAngle(0, 0, 90-alfa_pm);
	this.line_general = sDraw.createLineByPointAngle(0, 0, 90-beta+0.002);
	
	var circle_Rrouter = sDraw.createCircle(0, 0, this.Rrouter);
	var circle_Rrinner = sDraw.createCircle(0, 0, this.Rrinner);
	this.dpm_real = this.Dpm;
	if (this.RetainingSleeveType == "Conductive retaining sleeve") {
		this.Trs_real = this.Trs; }
	else {
		this.Trs_real = 0; }
	
	if (motor.isInnerRotor()) {  // inner rotor
		if(this.Rrouter - this.dpm_real - this.Trs_real < this.Rrinner){
			this.Trs_real = this.Rrouter - this.Rrinner - this.dpm_real;
			if (this.Trs_real < 0) {
				this.Trs_real = 0; }
			if (this.RetainingSleeveType == "Conductive retaining sleeve" && this.Trs > 0) {
				console.warn('The retaining sleeve thickness has been corrected to fit the available space: Trs = ' + this.Trs_real); }
		}
		if(this.Rrouter - this.dpm_real < this.Rrinner){
			this.dpm_real = this.Rrouter - this.Rrinner;
			console.warn('Magnet depth is greater than the difference between the outer and inner radius. Magnet depth has been corrected: Dpm = ' + this.dpm_real);
		}
		var circle_Rsleeve = sDraw.createCircle(0, 0, this.Rrouter - this.Trs_real);   // sleeve inner radius circle
		var point_1 = new QPointF(0, this.Rrouter - this.Trs_real);
		
		var circle_Rpm = sDraw.createCircle(0, 0, this.Rrouter - this.dpm_real - this.Trs_real);
		
		//>>>var point_2 = sDraw.intersection(line_0_2, circle_Rrouter, (alfa_pm == 90) ? 'right' : 'higher');   
		var point_2 = sDraw.intersection(line_0_2, circle_Rsleeve, (alfa_pm == 90) ? 'right' : 'higher');   
		var point_5 = sDraw.intersection(line_0_2, circle_Rpm, (alfa_pm == 90) ? 'right' : 'higher'); 
		
		//>>>var arc_3_1 = new Arc(Math.radToDeg(line_0_3.angleRad), 90, this.Rrouter, 0, 0);
		var arc_3_1 = new Arc(Math.radToDeg(line_0_3.angleRad), 90, this.Rrouter - this.Trs_real, 0, 0);
		//>>>var arc_5_4 = new Arc(Math.radToDeg(line_0_2.angleRad), 90, this.Rrouter - this.dpm_real, 0, 0);
		var arc_5_4 = new Arc(Math.radToDeg(line_0_2.angleRad), 90, this.Rrouter - this.dpm_real - this.Trs_real, 0, 0);
		var arc_8_7 = new Arc(Math.radToDeg(line_0_3.angleRad), 90, this.Rrinner, 0, 0);
		this.line_5_2 = new Segment(point_5, point_2);
		var s_line_5_2 = sDraw.createLineBy2Points(point_5.x(), point_5.y(), point_2.x(), point_2.y());
		var line_0_5 = new Segment(point_0, point_5);
		//>>>this.arc_2_1 = new Arc(Math.radToDeg(line_0_2.angleRad), 90, this.Rrouter, 0, 0);
		this.arc_2_1 = new Arc(Math.radToDeg(line_0_2.angleRad), 90, this.Rrouter - this.Trs_real, 0, 0);		
		var line_5_2_angle = Math.radToDeg(s_line_5_2.angleRad);
		
		this.geomr.push(arc_5_4);    // arc 5-4
		this.geomr.push(arc_8_7);    // arc 8-7
		
		//Максимальный радиус скругления
		//>>>var fpm_max = this.getMaxRadiusFilletByRadiuses(this.Rrouter, this.Rrouter - this.dpm_real, 'inner');
		var fpm_max = this.getMaxRadiusFilletByRadiuses(this.Rrouter - this.Trs_real, this.Rrouter - this.dpm_real - this.Trs_real, 'inner');
		
		var fpm_max_y_angle = 90 - line_5_2_angle;
		var fpm_max_y = Math.sin(Math.degToRad(fpm_max_y_angle)) * (this.Rrouter - this.Trs_real) / (1 + Math.sin(Math.degToRad(fpm_max_y_angle)));
		
		var fpm_angle_real;
		if(this.Fpm >= fpm_max){
			console.warn('Magnet fillet radius does not fit magnet size; maximum possible fillet radius is used instead');
			//Проверка на пересечение с осью y - проверяем на условие line_5_2_angle + fpm_angle >= 90 град
			this.fpm_tmp = fpm_max;
			//>>>var fpm_angle = Math.radToDeg(Math.asin(this.fpm_tmp/(this.Rrouter - this.fpm_tmp)));
			var fpm_angle = Math.radToDeg(Math.asin(this.fpm_tmp/(this.Rrouter - this.Trs_real - this.fpm_tmp)));
			if(line_5_2_angle + fpm_angle >= 90){
				console.warn('Magnet fillet radius intersects the y axis. Magnet fillet radius has been corrected');
				//Скругляем пересечение
				this.fpm_tmp = fpm_max_y;
				
				this.bildFilletIntersection();
				fpm_angle_real = fpm_max_y_angle;
			}else{
				//Строим дугу с максимальным радиусом скругления
				//точка 9 - находим 
				var line_0_9 = sDraw.createLineByPointAngle(point_0.x(), point_0.y(), line_5_2_angle + fpm_angle);
				//>>>var point_9 = sDraw.intersection(line_0_9, circle_Rrouter, 'higher');
				var point_9 = sDraw.intersection(line_0_9, circle_Rsleeve, 'higher');
				var arc1 = sDraw.createArcBy2PointsAndRadius(point_9.x(), point_9.y(), point_5.x(), point_5.y(), this.fpm_tmp, 1);
				//>>>var arc_1_9 = new Arc(Math.radToDeg(line_0_9.angleRad), 90, this.Rrouter, 0, 0);
				var arc_1_9 = new Arc(Math.radToDeg(line_0_9.angleRad), 90, this.Rrouter - this.Trs_real, 0, 0);
				this.geomr.push(arc_1_9);
				this.geomr.push(arc1);
				
				this.arc_fpm = arc1;
				this.p_line_5_2 = null;
				fpm_angle_real = fpm_angle; 
			}
		}else{
			//Проверка на пересечение с осью y - проверяем на условие line_5_2_angle + fpm_angle >= 90 град
			this.fpm_tmp = this.Fpm;
			//>>>var fpm_angle = Math.radToDeg(Math.asin(this.fpm_tmp/(this.Rrouter - this.fpm_tmp)));//Угол скругления относительно точки начала координат
			var fpm_angle = Math.radToDeg(Math.asin(this.fpm_tmp/(this.Rrouter - this.Trs_real - this.fpm_tmp)));//Угол скругления относительно точки начала координат
			if(line_5_2_angle + fpm_angle >= 90){
				console.warn('Magnet fillet radius intersects the y axis. Magnet fillet radius has been corrected');
				//Скругляем пересечение
				this.fpm_tmp = fpm_max_y;
				
				this.bildFilletIntersection();
				fpm_angle_real = fpm_max_y_angle;
			}else{
				//Скругляем пересечение
				this.bildFilletIntersection();
				fpm_angle_real = fpm_angle;
			}
		}
		
		//Вычисляем погруженность магнита в сталь, т.е. радиус дуги 6-5
		this.calcRealDis();
		//>>>this.Rosteel = this.Rrouter - this.dpm_real + this.dis_r;
		this.Rosteel = this.Rrouter - this.Trs_real - this.dpm_real + this.dis_r;
		var arc_6_5 = new Arc(Math.radToDeg(line_0_3.angleRad), Math.radToDeg(line_0_2.angleRad), this.Rosteel, 0, 0);
		this.geomr.push(arc_6_5);    // arc 6-5
		
		this.Rsteel = this.Rosteel;
		
		//Строим дугу 3-1
		if(this.fpm_tmp > 0.001 && this.Trs_real == 0){
			var circe_fpm = sDraw.createCircle(this.arc_fpm.centerX, this.arc_fpm.centerY, this.arc_fpm.radius);  // magnet fillet full circle
			// determine the aiggap mesh border notch in magnet fillet area (to prevent sharp angle between rotor-airgap border and fillet)
			var notchdepth = this.lag/5;      // notch depth is 20% of air gap length
			if (notchdepth > this.arc_fpm.radius/2) {
				notchdepth = this.arc_fpm.radius/2; }
			var circle_Rnotchdepth = sDraw.createCircle(0, 0, this.Rrouter - notchdepth);  
			var point_notch1 = sDraw.intersection(circle_Rnotchdepth, circe_fpm, 'right');  // notch first point (where notch crossing magnet fillet)
			//console.info("point_notch1: " + point_notch1);
			var line_notch = sDraw.createLineByPointAngle(point_notch1.x(), point_notch1.y(), 45);   // notch angle is 45 degrees
			var point_notch2 = sDraw.intersection(line_notch, circle_Rrouter, 'higher');   // notch second point (where notch crossing rotor-airgap border)
			var line_0_point_notch2 = sDraw.createLineBy2Points(0, 0, point_notch2.x(), point_notch2.y());
			// create rotor-airgap border with notch
			if (Math.radToDeg(line_0_point_notch2.angleRad) > 90 - alfa) {
				var arc_3_point_notch2 = new Arc(90 - alfa, Math.radToDeg(line_0_point_notch2.angleRad), this.Rrouter, 0, 0);
				this.geomr.push(arc_3_point_notch2);
			}else{
				point_notch2 = sDraw.intersection(line_0_3, circle_Rrouter, 'higher');   // change notch second point
			}
			var segment_notch = new Segment(point_notch1, point_notch2);
			this.geomr.push(segment_notch);
			this.R_3_1 = this.Rrouter;
		}else if(this.fpm_tmp > 0.001 && this.Trs_real > 0){
			var circe_fpm = sDraw.createCircle(this.arc_fpm.centerX, this.arc_fpm.centerY, this.arc_fpm.radius);  // magnet fillet full circle
			// determine the aiggap mesh border notch in magnet fillet area (to prevent sharp angle between rotor-airgap border and fillet)
			var notchdepth = this.Trs_real/10;      // notch depth is 10% of retaining sleeve thickness
			if (notchdepth > this.arc_fpm.radius/2) {
				notchdepth = this.arc_fpm.radius/2; }
			var circle_Rnotchdepth = sDraw.createCircle(0, 0, this.Rrouter - this.Trs_real - notchdepth);  
			var point_notch1 = sDraw.intersection(circle_Rnotchdepth, circe_fpm, 'right');  // notch first point (where notch crossing magnet fillet)
			//console.info("point_notch1: " + point_notch1);
			var line_notch = sDraw.createLineByPointAngle(point_notch1.x(), point_notch1.y(), 45);   // notch angle is 45 degrees
			var circle_sleeve_innerborder = sDraw.createCircle(0, 0, this.Rrouter - this.Trs_real);
			var point_notch2 = sDraw.intersection(line_notch, circle_sleeve_innerborder, 'higher');   // notch second point (where notch crossing inner retaining sleeve border)
			//console.info("point_notch2: " + point_notch2);
			var line_0_point_notch2 = sDraw.createLineBy2Points(0, 0, point_notch2.x(), point_notch2.y());
			// create rotor-retaining sleeve border with notch
			if (Math.radToDeg(line_0_point_notch2.angleRad) > 90 - alfa) {
				var arc_3_point_notch2 = new Arc(90 - alfa, Math.radToDeg(line_0_point_notch2.angleRad), this.Rrouter - this.Trs_real, 0, 0);
				this.geomr.push(arc_3_point_notch2);
			}else{
				point_notch2 = sDraw.intersection(line_0_3, circle_sleeve_innerborder, 'higher');   // change notch second point
			}
			var segment_notch = new Segment(point_notch1, point_notch2);
			this.geomr.push(segment_notch);
			//this.R_3_1 = this.Rrouter;
			//this.geomr.push(arc_3_1);    // arc 3-1
			this.R_3_1 = this.Rrouter - this.Trs_real;
		}else{
			this.geomr.push(arc_3_1);    // arc 3-1
			this.R_3_1 = this.Rrouter - this.Trs_real;
		}		
		this.circle_Rpm_iron = sDraw.createCircle(0, 0, (this.Rrinner + this.Rsteel)/2);
		
		if (this.Trs_real>0) {
			var arc_3rs_1rs = new Arc(Math.radToDeg(line_0_3.angleRad), 90, this.Rrouter, 0, 0);
			this.geomr.push(arc_3rs_1rs);    // arc 3rs-1rs of retaining sleeve
		}
	}
	else {      // outer rotor	
		this.Trs_real = 0;
		if(this.Rrinner + this.dpm_real > this.Rrouter){
			this.dpm_real = this.Rrouter - this.Rrinner;
			console.warn('The magnet depth is greater than the difference between the outer and inner radius. The magnet depth has been corrected: Dpm = ' + this.dpm_real);
		}	
		var circle_Rpm = sDraw.createCircle(0, 0, this.Rrinner + this.dpm_real);
				
		var point_1 = new QPointF(0, this.Rrinner);
		var point_2 = sDraw.intersection(line_0_2, circle_Rrinner, (alfa_pm == 90) ? 'right' : 'higher');   
		var point_5 = sDraw.intersection(line_0_2, circle_Rpm, (alfa_pm == 90) ? 'right' : 'higher'); 
		//var point_3 = sDraw.intersection(line_0_3, circle_Rrinner, 'higher'); 
		//var point_6 = sDraw.intersection(line_0_3, circle_Rpm, 'higher'); 
		
		var line_0_5 = new Segment(point_0, point_5);
				
		var arc_3_1 = new Arc(Math.radToDeg(line_0_3.angleRad), 90, this.Rrinner, 0, 0);
		var arc_5_4 = new Arc(Math.radToDeg(line_0_2.angleRad), 90, this.Rrinner + this.dpm_real, 0, 0);
		var arc_8_7 = new Arc(Math.radToDeg(line_0_3.angleRad), 90, this.Rrouter, 0, 0);
		this.line_5_2 = new Segment(point_5, point_2);
		var s_line_2_5 = sDraw.createLineBy2Points(point_2.x(), point_2.y(), point_5.x(), point_5.y());
		this.arc_2_1 = new Arc(Math.radToDeg(line_0_2.angleRad), 90, this.Rrinner, 0, 0);
		
		var line_2_5_angle = Math.radToDeg(s_line_2_5.angleRad);
		
		//geomr.push(arc_3_1);    // arc 3-1
		this.geomr.push(arc_5_4);    // arc 6-4
		this.geomr.push(arc_8_7);    // arc 8-7
		//geomr.push(line_5_2);    // line 5-2
		
		var fpm_max = this.getMaxRadiusFilletByRadiuses(this.Rrinner + this.dpm_real, this.Rrinner, 'outer');
		var fpm_max_y_angle = 90 - line_2_5_angle;
		var fpm_max_y = Math.sin(Math.degToRad(fpm_max_y_angle)) * this.Rrinner / (1 - Math.sin(Math.degToRad(fpm_max_y_angle)));
		
		var fpm_angle_real;
		if(this.Fpm >= fpm_max){
			console.warn('Magnet fillet radius does not fit magnet size; maximum possible fillet radius is used instead');
			//Проверка на пересечение с осью y - проверяем на условие line_2_5_angle + fpm_angle >= 90 град
			this.fpm_tmp = fpm_max;
			var fpm_angle = Math.radToDeg(Math.asin(this.fpm_tmp/(this.Rrinner + this.fpm_tmp)));//Находим угол кривой относительно центра
			if(line_2_5_angle + fpm_angle >= 90){
				console.warn('Magnet fillet radius intersects the y axis. Magnet fillet radius has been corrected');
				//Строим дугу с максимальным радиусом скругления
				//точка 9 = точка 1
				//Скругляем пересечение
				this.fpm_tmp = fpm_max_y;
				this.bildFilletIntersection();
				fpm_angle_real = fpm_max_y_angle;
			}else{
				//точка 9 - находим 
				//var fpm_angle = Math.radToDeg(Math.atan(fpm_max/(this.Rrinner + this.dpm_real)));
				var line_0_9 = sDraw.createLineByPointAngle(point_0.x(), point_0.y(), line_2_5_angle + fpm_angle);
				var point_9 = sDraw.intersection(line_0_9, circle_Rrinner, 'higher');
				var arc1 = sDraw.createArcBy2PointsAndRadius(point_5.x(), point_5.y(), point_9.x(), point_9.y(), this.fpm_tmp, 1);
				var arc_1_9 = new Arc(Math.radToDeg(line_0_9.angleRad), 90, this.Rrinner, 0, 0);
				this.geomr.push(arc_1_9);
				this.geomr.push(arc1);
				
				this.arc_fpm = arc1;
				this.p_line_5_2 = null;
				fpm_angle_real = fpm_angle;
			}
		}else{
			//Проверка на пересечение с осью y - проверяем на условие line_2_5_angle + fpm_angle >= 90 град
			this.fpm_tmp = this.Fpm;
			var fpm_angle = Math.radToDeg(Math.asin(this.fpm_tmp/(this.Rrinner + this.fpm_tmp)));
			if(line_2_5_angle + fpm_angle >= 90){
				console.warn('Magnet fillet radius intersects the y axis. Magnet fillet radius has been corrected');
				//Скругляем пересечение
				this.fpm_tmp = fpm_max_y;
				this.bildFilletIntersection();
				fpm_angle_real = fpm_max_y_angle;
			}else{
				this.bildFilletIntersection();
				fpm_angle_real = fpm_angle;
			}
		}
		
		//Вычисляем погруженность магнита в сталь, т.е. радиус дуги 6-5
		this.calcRealDis();
		this.Risteel = this.Rrinner + this.dpm_real - this.dis_r;
		var arc_6_5 = new Arc(Math.radToDeg(line_0_3.angleRad), Math.radToDeg(line_0_2.angleRad), this.Risteel, 0, 0);
		this.geomr.push(arc_6_5);    // arc 6-5
		
		this.Rsteel = this.Risteel;
		
		//Строим дугу 3-1
		if(this.fpm_tmp > 0.001){
			var circe_fpm = sDraw.createCircle(this.arc_fpm.centerX, this.arc_fpm.centerY, this.arc_fpm.radius);  // magnet fillet full circle
			// determine the aiggap mesh border notch in magnet fillet area (to prevent sharp angle between rotor-airgap border and fillet)
			var notchdepth = this.lag/5;     // notch depth is 20% of air gap length
			if (notchdepth > this.arc_fpm.radius/2) {
				notchdepth = this.arc_fpm.radius/2; }
			var circle_Rnotchdepth = sDraw.createCircle(0, 0, this.Rrinner + notchdepth);
			var point_notch1 = sDraw.intersection(circle_Rnotchdepth, circe_fpm, 'right');  // notch first point (where notch crossing magnet fillet)
			var line_notch = sDraw.createLineByPointAngle(point_notch1.x(), point_notch1.y(), -45);   // notch angle is -45 degrees
			var point_notch2 = sDraw.intersection(line_notch, circle_Rrinner, 'higher');   // notch second point (where notch crossing rotor-airgap border)
			var line_0_point_notch2 = sDraw.createLineBy2Points(0, 0, point_notch2.x(), point_notch2.y());
			// create rotor-airgap border with notch
			if (Math.radToDeg(line_0_point_notch2.angleRad) > 90 - alfa) {
				var arc_3_point_notch2 = new Arc(90 - alfa, Math.radToDeg(line_0_point_notch2.angleRad), this.Rrinner, 0, 0);
				this.geomr.push(arc_3_point_notch2);
			}else{
				point_notch2 = sDraw.intersection(line_0_3, circle_Rrinner, 'higher');   // change notch second point
			}
			var segment_notch = new Segment(point_notch1, point_notch2);
			this.geomr.push(segment_notch);
		}else{
			this.geomr.push(arc_3_1);    // arc 3-1
		}		
		this.R_3_1 = this.Rrinner;
		
		this.circle_Rpm_iron = sDraw.createCircle(0, 0, (this.Rrinner + this.dpm_real + this.Rsteel)/2);
	}
	
		
	return this.geomr;
};

// call from с++ code
Rotor.prototype.getMaterials = function() { // assign material types

	var materials = new Array();
	var delta = 0.001;
	if (Math.abs(motor.rotorOuterRadius - motor.rotorInnerRadius - this.Trs_real) > this.dpm_real) {
		if (motor.isInnerRotor()) {  // inner rotor
			materials.push( new IronMaterial(delta, (motor.rotorOuterRadius - this.dpm_real - this.Trs_real + motor.rotorInnerRadius) / 2)); }   // rotor iron
		else {   // outer rotor		
			materials.push( new IronMaterial(delta, (motor.rotorOuterRadius + motor.rotorInnerRadius + this.dpm_real) / 2)); }   // rotor iron
	}else if(Math.abs(motor.rotorOuterRadius - motor.rotorInnerRadius - this.Trs_real) == this.dpm_real && this.dis_r > 0 && this.Apm < 180){
		this.point_iron = sDraw.intersection(this.line_general, this.circle_Rpm_iron, 'higher');  // point to assign iron material
		if (motor.isInnerRotor()) {  // inner rotor
			materials.push( new IronMaterial(this.point_iron.x(), this.point_iron.y())); }   // rotor iron
		else {   // outer rotor		
			materials.push( new IronMaterial(this.point_iron.x(), this.point_iron.y())); }   // rotor iron
	}
	
	if (this.Apm > 0 && this.dpm_real > 0) {   // magnet
		if (this.Magnetization == "Radial") {
			var materialMagnet = new MagnetRadialMaterial; }
		else if (this.Magnetization == "Parallel") {
			var materialMagnet = new MagnetParallelMaterial; }
		else { 
			console.error('Undefined magnetization type'); }
		materialMagnet.center = new QPointF(0, 0);
		materialMagnet.direction = Direction.From;
		materialMagnet.angle = 90;  
		if (motor.isInnerRotor()) {  // inner rotor
			materialMagnet.pos = new QPointF(delta, motor.rotorOuterRadius - this.Trs_real - this.dpm_real/2);
		}
		else {   // outer rotor		
			materialMagnet.pos = new QPointF(delta, motor.rotorInnerRadius + this.dpm_real/2);
		}
		materials.push(materialMagnet); 
	}
	if ((this.Apm < 180 || (this.Apm == 180 && this.fpm_tmp > 0.01)) && this.dpm_real > 0 && !this.full_sinking) {
		if(this.Apm < 180 || (this.Apm == 180 && this.R_low_general_limit == null)){
			var circle_Rpm_general = sDraw.createCircle(0, 0, (this.R_3_1 + this.Rsteel)/2);
		}else if(this.Apm == 180 && this.R_low_general_limit !== null){
			var circle_Rpm_general = sDraw.createCircle(0, 0, (this.R_3_1 + this.R_low_general_limit)/2);
		}
		this.point_general = sDraw.intersection(this.line_general, circle_Rpm_general, 'higher');  // point to assign general material
		materials.push( new GeneralMaterial(this.point_general.x(), this.point_general.y())); 
	}  // general
		
	if (this.Trs_real > 0) { // retaining sleeve (conductor)
		materials.push( new ConductorMaterial(delta, motor.rotorOuterRadius - this.Trs_real/2)); }
	
	return materials;
};
	
var rotor = new Rotor();

// rotor widgets constuctor
function RotorUI(ui)
{
	this.ui = ui;

	this.labelDpm = new QLabel("Magnet depth (Dpm):");
	this.labelDpm.toolTip = "Use the ‘? Guide’ button above for explanation on this parameter";
	this.editDpm = new QDoubleSpinBox;
	this.editDpm.objectName = "Dpm";
	this.editDpm.setRange(0.0, motor.rotorOuterRadius);
	this.editDpm.decimals = 2;
	this.editDpm.singleStep = 1;
	this.editDpm.keyboardTracking = false;
	this.editDpm.value = rotor.Dpm;
	//this.editDpm['valueChanged(double)'].connect(this, function(value){
	//	rotor.Dpm = value;
	//});
	this.unitsDpm = new QLabel("mm");
	
	this.labelApm = new QLabel("Magnet angle (Apm):");
	this.labelApm.toolTip = "Use the ‘? Guide’ button above for explanation on this parameter";
	this.editApm = new QDoubleSpinBox;
	this.editApm.objectName = "Apm";
	this.editApm.setRange(0, 180);
	this.editApm.decimals = 1;
	this.editApm.singleStep = 1;
	this.editApm.keyboardTracking = false;
	this.editApm.value = rotor.Apm;
	//this.editApm['valueChanged(double)'].connect(this, function(value){
	//	rotor.Apm = value;
	//});
	this.unitsApm = new QLabel("el.deg.");
	
	this.labelFpm = new QLabel("Magnet fillet radius (Fpm):");
	this.labelFpm.toolTip = "Use the ‘? Guide’ button above for explanation on this parameter";
	this.editFpm = new QDoubleSpinBox;
	this.editFpm.objectName = "Fpm";
	this.editFpm.setRange(0.0, motor.rotorOuterRadius);
	this.editFpm.decimals = 2;
	this.editFpm.singleStep = 0.1;
	this.editFpm.keyboardTracking = false;
	this.editFpm.value = rotor.Fpm;
	//this.editFpm['valueChanged(double)'].connect(this, function(value){
	//	rotor.Fpm = value;
	//});
	this.unitsFpm = new QLabel("mm");

	this.labelDis = new QLabel("Magnet inset depth (Dis):");
	this.labelDis.toolTip = "Use the ‘? Guide’ button above for explanation on this parameter";
	this.editDis = new QDoubleSpinBox;
	this.editDis.objectName = "Dis";
	this.editDis.setRange(0, Math.abs(motor.rotorOuterRadius - motor.rotorInnerRadius));
	this.editDis.decimals = 1;
	this.editDis.singleStep = 1;
	this.editDis.keyboardTracking = false;
	this.editDis.value = rotor.Dis;
	//this.editDis['valueChanged(double)'].connect(this, function(value){
	//	rotor.Dis = value;
	//});
	this.unitsDis = new QLabel("mm");
	
	this.labelMagnetization = new QLabel("Magnetization:");
	this.comboboxMagnetization = new QComboBox();
	this.comboboxMagnetization.objectName = "Magnetization";
	this.comboboxMagnetization.addItem("Radial");
	this.comboboxMagnetization.addItem("Parallel");
	this.comboboxMagnetization.currentText = rotor.Magnetization;
	//this.comboboxMagnetization['currentIndexChanged(int)'].connect(this, function(value){
	//	rotor.Magnetization = this.comboboxMagnetization.currentText;
	//});
	
	this.labelRetainingSleeveType = new QLabel("Retaining sleeve:");
	this.labelRetainingSleeveType.toolTip = "Use 'Conductive retaining sleeve' item to include eddy current loss in retaining sleeve into analysis." + "\n" +
	"Retaining sleeve will use material assigned for 'Conductor' in the 'Materials' panel on the right." + "\n" +
	"Retaining sleeve loss will appear in the 'Other eddy current loss' parameter of 'Magnetostatic Analysis'";
	this.comboboxRetainingSleeveType = new QComboBox();
	this.comboboxRetainingSleeveType.objectName = "RetainingSleeveType";
	this.comboboxRetainingSleeveType.addItem("Non-conductive or no retaining sleeve");
	this.comboboxRetainingSleeveType.addItem("Conductive retaining sleeve");
	this.comboboxRetainingSleeveType.currentText = rotor.RetainingSleeveType;
	this.comboboxRetainingSleeveType.toolTip = "Use 'Conductive retaining sleeve' item to include eddy current loss in retaining sleeve into analysis." + "\n" +
	"Retaining sleeve will use material assigned for 'Conductor' in the 'Materials' panel on the right." + "\n" +
	"Retaining sleeve loss will appear in the 'Other eddy current loss' parameter of 'Magnetostatic Analysis'";
	//this.comboboxRetainingSleeveType['currentIndexChanged(int)'].connect(this, function(value){
	//	rotor.RetainingSleeveType = this.comboboxRetainingSleeveType.currentText;
	//});
	
	this.labelTrs = new QLabel("Retaining sleeve thickness (Trs):");
	this.labelTrs.toolTip = "Use the ‘? Guide’ button above for explanation on this parameter";
	this.editTrs = new QDoubleSpinBox;
	this.editTrs.objectName = "Trs";
	this.editTrs.setRange(0, Math.abs(motor.rotorOuterRadius - motor.rotorInnerRadius));
	this.editTrs.decimals = 1;
	this.editTrs.singleStep = 1;
	this.editTrs.keyboardTracking = false;
	this.editTrs.value = rotor.Trs;
	//this.editTrs['valueChanged(double)'].connect(this, function(value){
	//	rotor.Trs = value;
	//});
	this.unitsTrs = new QLabel("mm");
	
	
	this.layout = new QGridLayout(ui);
	
	this.layout.addWidget(this.labelDpm, 0, 0);
	this.layout.addWidget(this.editDpm, 0, 1);
	this.layout.addWidget(this.unitsDpm, 0, 2);

	this.layout.addWidget(this.labelApm, 1, 0);
	this.layout.addWidget(this.editApm, 1, 1);
	this.layout.addWidget(this.unitsApm, 1, 2);
	
	this.layout.addWidget(this.labelFpm, 2, 0);
	this.layout.addWidget(this.editFpm, 2, 1);
	this.layout.addWidget(this.unitsFpm, 2, 2);
	
	this.layout.addWidget(this.labelDis, 3, 0);
	this.layout.addWidget(this.editDis, 3, 1);
	this.layout.addWidget(this.unitsDis, 3, 2);
	
	this.layout.addWidget(this.labelMagnetization, 4, 0);
	this.layout.addWidget(this.comboboxMagnetization, 4, 1, 1, 2);
	
	this.layout.addWidget(this.labelRetainingSleeveType, 5, 0);
	this.layout.addWidget(this.comboboxRetainingSleeveType, 5, 1, 1, 2);
	
	this.layout.addWidget(this.labelTrs, 6, 0);
	this.layout.addWidget(this.editTrs, 6, 1);
	this.layout.addWidget(this.unitsTrs, 6, 2);
	
};

// update rotor widgets
RotorUI.prototype.updateUI = function()
{
	//console.log("rotorUI.updateUI");
	
	if (motor.isInnerRotor()) {  // inner rotor
		var visibleRetainingSleeveType = true;
		var visibleTrs = rotor.RetainingSleeveType == "Conductive retaining sleeve";
	}
	else {                       // outer rotor
		var visibleRetainingSleeveType = false;
		var visibleTrs = false;
	}
	this.labelRetainingSleeveType.setVisible(visibleRetainingSleeveType);
	this.comboboxRetainingSleeveType.setVisible(visibleRetainingSleeveType);
	this.labelTrs.setVisible(visibleTrs);
	this.editTrs.setVisible(visibleTrs);
	this.unitsTrs.setVisible(visibleTrs);
}

// call this function from c++ code
createRotorUI = function(ui)
{
	rotorUI = new RotorUI(ui);
	rotorUI.updateUI();
}

	

	
	
	
