using static WebWindowComplex.Json.WindowConst; namespace WebWindowComplex.Models { public class AreaDimension { #region Public Constructors public AreaDimension(double dDimension, MeasureTypes MeasureType, Area Parent) { 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 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 m_MeasureTypeList = new List { 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; } /// /// Metodo per convertire la dimensione dal vecchio tipo al nuovo tipo /// /// Vecchio tipo /// Nuovo tipo /// public double ConvertDimension(List itemList, MeasureTypes oldType, MeasureTypes newType, double dimTot, int indexSash) { switch (oldType) { case MeasureTypes.ABSOLUTE: { if (newType.Equals(MeasureTypes.PERCENTAGE)) { //return Double.Round((m_dDimension / m_Parent.Width) * 100, 1); return (dDimension / dimTot) * 100; } return -1; //else //{ // return Double.Round(CalculatePropVal(itemList, indexSash, dimTot)); //} } case MeasureTypes.PROPORTIONAL: { if (newType.Equals(MeasureTypes.ABSOLUTE)) { //return Double.Round(ConvertFromPropVal(newType), 2); return ConvertFromPropVal(itemList, newType, dimTot); } else { //return Double.Round(ConvertFromPropVal(newType), 1); return ConvertFromPropVal(itemList, newType, dimTot); } } case MeasureTypes.PERCENTAGE: { if (newType.Equals(MeasureTypes.ABSOLUTE)) { //return Double.Round((m_dDimension * m_Parent.Width) / 100, 2); return (dDimension * dimTot) / 100; } return -1; //else //{ // return Double.Round(CalculatePropVal(itemList, indexSash, dimTot)); //} } } return -1; } #endregion Public Methods #region Internal Methods /// /// Calcolo MCD /// /// /// /// 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; } /// /// Metodo per ricalcolare i valori proporzionali a causa della modifica di uno /// /// internal List RicalculatePropVal(List itemList, int indexArea, double widthTot) { List ans = itemList; if (itemList.Where(m => m.MeasureType.Equals(MeasureTypes.PROPORTIONAL)).ToList().Count == 0) { ans.ElementAt(indexArea).SetDimension(1); return ans; } List absoluteValue = new List(); foreach (var item in itemList) { absoluteValue.Add(item.CalculateAbsoluteValue(itemList, widthTot)); } int numProportional = itemList.Where(x => x.SelMeasureType == MeasureTypes.PROPORTIONAL).Count(); if(numProportional > 1) { List mcdList = new List(); foreach(var elem in itemList.Where(x => x.SelMeasureType == MeasureTypes.PROPORTIONAL).ToList()) { mcdList.Add(CalculateMCD(absoluteValue.ElementAt(indexArea), absoluteValue.ElementAt(itemList.IndexOf(elem)))); } int mcdDuplicati = mcdList.GroupBy(n => n) .Where(g => g.Count() > 1) .Select(g => g.Key) .Count(); if (mcdList.Contains(1) || mcdDuplicati < mcdList.Count - 1) return ans; else { for(int i = 0; i < itemList.Count; i++) ans.ElementAt(i).SetDimension(Math.Round(absoluteValue.ElementAt(i) / mcdList.FirstOrDefault())); } //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)); ans.ElementAt(i).SetDimension(Math.Round(absoluteValue.ElementAt(i) / mcd)); ans.ElementAt(indexArea).SetDimension(Math.Round(absoluteValue.ElementAt(indexArea) / mcd)); } else { var mcd = CalculateMCD(absoluteValue.ElementAt(indexArea), absoluteValue.ElementAt(i)); ans.ElementAt(i).SetDimension(Math.Round(absoluteValue.ElementAt(i) / mcd)); ans.ElementAt(indexArea).SetDimension(Math.Round(absoluteValue.ElementAt(indexArea) / mcd)); } break; } } } return ans; } /// /// Metodo per trasformare una dimensione in valore assoluto rispetto alla larghezza totale /// /// Larghezza totale /// internal double CalculateAbsoluteValue(List itemList, double widthTot) { switch (SelMeasureType) { case MeasureTypes.ABSOLUTE: { //return Double.Round(dDimension, 2); double overlapElem = 0; if (m_Parent is Sash s) { // Calcolo overlap int indexSash = -1; if (this is SashDimension sashDimCurr) { indexSash = s.SashList.IndexOf(sashDimCurr); } else indexSash = itemList.IndexOf(this); int indElem = indexSash == 0 ? 1 : s.SashList.ElementAt(indexSash).ElementDimensionList.Count - 1; if (!s.bIsDimensionLight && s.SashList.ElementAt(indexSash).ElementDimensionList.Count > 0) { if(s.SashList.Count > 0) overlapElem = s.SashList.ElementAt(indexSash).ElementDimensionList.ElementAt(indElem).dOverlap / 2; else overlapElem = s.SashList.ElementAt(indexSash).ElementDimensionList.ElementAt(indElem).dOverlap; } } 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; } /// /// Metodo per convertire una dimensione da un valore assoluto al suo rispettivo tipo /// /// Valore assoluto /// Tipo di misura della dimensione /// Larghezza totale /// internal double ConvertAbsoluteIn(List 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; } /// /// Metodo per convertire da misura proporzionale a misura assoluta o percentuale /// /// /// internal double ConvertFromPropVal(List 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 Math.Round(res / sumPesi * dDimension, 2); } else { return Math.Round((res / sumPesi * dDimension) / tot * 100); } } /// /// Metodo per trasformare il valore proporzionale in assoluto /// /// internal double ProportionalToAbsoluteVal(List 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 } }