Files
2026-01-16 15:10:19 +01:00

351 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static WebWindowTest.Json.WindowConst;
namespace WebWindowTest.Models
{
public class AreaDimension
{
#region Public Constructors
public AreaDimension(double dDimension, MeasureTypes MeasureType)
{
m_dDimension = dDimension;
m_SelMeasureType = MeasureType;
//m_Parent = Parent;
}
#endregion Public Constructors
#region Public Properties
public virtual double dDimension
{
get
{
return m_dDimension;
}
set
{
m_dDimension = value;
}
}
//public Area Parent
//{
// get
// {
// return m_Parent;
// }
// set
// {
// m_Parent = value;
// }
//}
public MeasureTypes MeasureType
{
get
{
return m_SelMeasureType;
}
}
public List<IdNameStruct> MeasureTypeList
{
get
{
return m_MeasureTypeList;
}
}
public MeasureTypes SelMeasureType
{
get
{
return m_SelMeasureType;
}
set
{
m_SelMeasureType = value;
}
}
public virtual int SelMeasureTypeIndex
{
get
{
return (int)m_SelMeasureType;
}
set
{
if (m_SelMeasureType != (MeasureTypes)value)
{
MeasureTypes newType = (MeasureTypes)value;
}
}
}
#endregion Public Properties
#region Private Fields
protected double m_dDimension;
protected List<IdNameStruct> m_MeasureTypeList = new List<IdNameStruct>
{
new IdNameStruct((int)MeasureTypes.ABSOLUTE, "Absolute"),
new IdNameStruct((int)MeasureTypes.PROPORTIONAL, "Proportional"),
new IdNameStruct((int)MeasureTypes.PERCENTAGE, "Percentage"),
};
protected MeasureTypes m_SelMeasureType;
// reference
// protected Area m_Parent;
#endregion Private Fields
#region Public Methods
public void SetDimension(double dValue)
{
m_dDimension = dValue;
}
/// <summary>
/// Metodo per convertire la dimensione dal vecchio tipo al nuovo tipo
/// </summary>
/// <param name="oldType"> Vecchio tipo </param>
/// <param name="newType"> Nuovo tipo </param>
/// <returns></returns>
public double ConvertDimension(List<AreaDimension> itemList, MeasureTypes oldType, MeasureTypes newType, double widthTot, int indexSash)
{
switch (oldType)
{
case MeasureTypes.ABSOLUTE:
{
if (newType.Equals(MeasureTypes.PERCENTAGE))
{
//return Double.Round((m_dDimension / m_Parent.Width) * 100, 1);
return (dDimension / widthTot) * 100;
}
else
{
return Double.Round(CalculatePropVal(itemList, indexSash, widthTot));
}
}
case MeasureTypes.PROPORTIONAL:
{
if (newType.Equals(MeasureTypes.ABSOLUTE))
{
//return Double.Round(ConvertFromPropVal(newType), 2);
return ConvertFromPropVal(itemList, newType, widthTot);
}
else
{
//return Double.Round(ConvertFromPropVal(newType), 1);
return ConvertFromPropVal(itemList, newType, widthTot);
}
}
case MeasureTypes.PERCENTAGE:
{
if (newType.Equals(MeasureTypes.ABSOLUTE))
{
//return Double.Round((m_dDimension * m_Parent.Width) / 100, 2);
return (dDimension * widthTot) / 100;
}
else
{
return Double.Round(CalculatePropVal(itemList, indexSash, widthTot));
}
}
}
return -1;
}
#endregion Public Methods
#region Internal Methods
/// <summary>
/// Calcolo MCD
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
internal double CalculateMCD(double a, double b)
{
while (b >= 0.01)
{
double temp = b;
b = a % b;
a = temp;
}
//return Double.Round(a,2);
return a;
}
/// <summary>
/// Metodo per ricalcolare i valori proporzionali a causa della modifica di uno
/// </summary>
/// <returns></returns>
internal double CalculatePropVal(List<AreaDimension> itemList, int indexArea, double widthTot)
{
if (itemList.Where(m => m.MeasureType.Equals(MeasureTypes.PROPORTIONAL)).ToList().Count == 0)
{
return 1;
}
List<double> absoluteValue = new List<double>();
foreach (var item in itemList)
{
absoluteValue.Add(item.CalculateAbsoluteValue(itemList, widthTot));
}
int numProportional = itemList.Where(x => x.SelMeasureType == MeasureTypes.PROPORTIONAL).Count();
if(itemList.Count > 2 && numProportional == itemList.Count - 1)
{
int inedMin = absoluteValue.IndexOf(absoluteValue.Min());
var mcd = CalculateMCD(absoluteValue.ElementAt(indexArea), absoluteValue.ElementAt(inedMin));
itemList.ElementAt(inedMin).SetDimension(absoluteValue.ElementAt(inedMin) / mcd);
itemList.ElementAt(indexArea).SetDimension(absoluteValue.ElementAt(indexArea) / mcd);
}
else
{
for (int i = 0; i < itemList.Count; i++)
{
if (!itemList.ElementAt(i).Equals(this) &&
itemList.ElementAt(i).MeasureType.Equals(MeasureTypes.PROPORTIONAL))
{
if (absoluteValue.ElementAt(indexArea) <= absoluteValue.ElementAt(i))
{
var mcd = CalculateMCD(absoluteValue.ElementAt(indexArea), absoluteValue.ElementAt(i));
itemList.ElementAt(i).SetDimension(absoluteValue.ElementAt(i) / mcd);
itemList.ElementAt(indexArea).SetDimension(absoluteValue.ElementAt(indexArea) / mcd);
}
else
{
var mcd = CalculateMCD(absoluteValue.ElementAt(indexArea), absoluteValue.ElementAt(i));
itemList.ElementAt(i).SetDimension(absoluteValue.ElementAt(i) / mcd);
itemList.ElementAt(indexArea).SetDimension(absoluteValue.ElementAt(indexArea) / mcd);
}
break;
}
}
}
return itemList.ElementAt(indexArea).dDimension;
}
/// <summary>
/// Metodo per trasformare una dimensione in valore assoluto rispetto alla larghezza totale
/// </summary>
/// <param name="widthTot"> Larghezza totale </param>
/// <returns></returns>
internal double CalculateAbsoluteValue(List<AreaDimension> itemList, double widthTot)
{
switch (SelMeasureType)
{
case MeasureTypes.ABSOLUTE:
{
//return Double.Round(dDimension, 2);
return dDimension;
}
case MeasureTypes.PROPORTIONAL:
{
//return Double.Round(Proportional2AbsolutVal(), 2);
return ProportionalToAbsoluteVal(itemList, dDimension, widthTot);
}
case MeasureTypes.PERCENTAGE:
{
//return Double.Round((dDimension / 100) * widthTot, 1);
return (dDimension / 100) * widthTot;
}
}
return 0;
}
/// <summary>
/// Metodo per convertire una dimensione da un valore assoluto al suo rispettivo tipo
/// </summary>
/// <param name="absoluteVal"> Valore assoluto </param>
/// <param name="type"> Tipo di misura della dimensione </param>
/// <param name="widthTot"> Larghezza totale </param>
/// <returns></returns>
internal double ConvertIn(List<AreaDimension> itemList, double absoluteVal, MeasureTypes type, double widthTot)
{
switch (type)
{
case MeasureTypes.ABSOLUTE:
{
return absoluteVal;
}
case MeasureTypes.PROPORTIONAL:
{
return ProportionalToAbsoluteVal(itemList, absoluteVal, widthTot);
}
case MeasureTypes.PERCENTAGE:
{
return (absoluteVal / widthTot) * 100;
}
}
return -1;
}
/// <summary>
/// Metodo per convertire da misura proporzionale a misura assoluta o percentuale
/// </summary>
/// <param name="newType"></param>
/// <returns></returns>
internal double ConvertFromPropVal(List<AreaDimension> itemList, MeasureTypes newType, double widthTot)
{
double tot = widthTot;
//Somma misura non proporzionali
double sumNotProp = itemList.Where(m => m.MeasureType != MeasureTypes.PROPORTIONAL && !m.Equals(this))
.Sum(m => m.CalculateAbsoluteValue(itemList, tot));
//Calcolo residuo
double res = tot - sumNotProp;
if (res < 0) res = 0;
//Misure proporzionali
var proportionalList = itemList.Where(m => m.SelMeasureType == MeasureTypes.PROPORTIONAL)
.ToList();
double sumPesi = proportionalList.Sum(p => p.dDimension);
if (sumPesi == 0) sumPesi = 1;
if (newType.Equals(MeasureTypes.ABSOLUTE))
{
return res / sumPesi * dDimension;
}
else
{
return (res / sumPesi * dDimension) / tot * 100;
}
}
/// <summary>
/// Metodo per trasformare il valore proporzionale in assoluto
/// </summary>
/// <returns></returns>
internal double ProportionalToAbsoluteVal(List<AreaDimension> itemList, double dimensionProp, double widthTot)
{
double tot = widthTot;
//Somma misura non proporzionali
double sumNotProp = itemList.Where(m => m.MeasureType != MeasureTypes.PROPORTIONAL)
.Sum(m => m.CalculateAbsoluteValue(itemList, tot));
//Calcolo residuo
double res = tot - sumNotProp;
if (res < 0) res = 0;
//Misure proporzionali
var proportionalList = itemList.Where(m => m.SelMeasureType == MeasureTypes.PROPORTIONAL)
.ToList();
double sumPesi = proportionalList.Sum(p => p.dDimension);
if (sumPesi == 0) sumPesi = 1;
return res / sumPesi * dimensionProp;
}
#endregion Public Method
}
}