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 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 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 /// /// 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 double CalculatePropVal(List itemList, int indexArea, double widthTot) { if (itemList.Where(m => m.MeasureType.Equals(MeasureTypes.PROPORTIONAL)).ToList().Count == 0) { return 1; } 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(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; } /// /// 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); 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 ConvertIn(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 res / sumPesi * dDimension; } else { return (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 } }