using System.Runtime.InteropServices; using System.Security.Principal; using WebWindowComplex.Json; using static WebWindowComplex.Json.WindowConst; namespace WebWindowComplex.Models { public class SashDimension { #region Public Constructors public SashDimension(double dDimension, MeasureTypes MeasureType, Sash Parent, int nSashId) { m_dDimension = dDimension; m_Parent = Parent; m_nSashId = nSashId; SetMeasureType(MeasureType); // assengno maniglia if (Parent.SashList.Count == 0 || !Parent.SashList.Any(x => x.bHasHandle)) m_bHasHandle = true; // assegno tipo di anta if (Parent.SashList.Count == 0) SetOpeningType(Openings.TILTTURN_LEFT); else if (Parent.SashList.Count == 1) { switch (Parent.SashList[0].OpeningType) { case Openings.TURNONLY_LEFT: { SetOpeningType(Openings.TURNONLY_RIGHT); break; } case Openings.TURNONLY_RIGHT: { SetOpeningType(Openings.TURNONLY_LEFT); break; } case Openings.TILTTURN_LEFT: { SetOpeningType(Openings.TURNONLY_RIGHT); break; } case Openings.TILTTURN_RIGHT: { SetOpeningType(Openings.TURNONLY_LEFT); break; } case Openings.TILTONLY_TOP: { SetOpeningType(Openings.TILTONLY_BOTTOM); break; } case Openings.TILTONLY_BOTTOM: { SetOpeningType(Openings.TILTONLY_TOP); break; } case Openings.COMPLANARSLIDE_LEFT: { SetOpeningType(Openings.COMPLANARSLIDE_RIGHT); break; } case Openings.COMPLANARSLIDE_RIGHT: { SetOpeningType(Openings.COMPLANARSLIDE_LEFT); break; } case Openings.LIFTSLIDE_LEFT: { SetOpeningType(Openings.LIFTSLIDE_RIGHT); break; } case Openings.LIFTSLIDE_RIGHT: { SetOpeningType(Openings.LIFTSLIDE_LEFT); break; } } } else SetOpeningType(Parent.SashList[Parent.SashList.Count - 1].OpeningType); } #endregion Public Constructors #region Public Properties public bool bHasHandle { get { return m_bHasHandle; } set { m_bHasHandle = value; } } public List JointList { get { return m_JointList; } set { m_JointList = value; } } public double dDimension { get { return m_dDimension; } set { double widthTot = CalculateWidthSashGroup(m_Parent.ParentWindow.AreaList.FirstOrDefault(), m_Parent.ParentWindow.AreaList.FirstOrDefault().DimensionList.Where(x => x.sName == "Width").First().dValue); double valMinAbsolute = 200; double valMaxAbsolute = widthTot - valMinAbsolute * (m_Parent.SashList.Count - 1); bool valueAccept = false; switch (MeasureType) { case MeasureTypes.ABSOLUTE: { valueAccept = (value < valMaxAbsolute && value > valMinAbsolute) ? true : false; break; } case MeasureTypes.PROPORTIONAL: { valMaxAbsolute = 20; valueAccept = (value >= 1) ? true : false; break; } case MeasureTypes.PERCENTAGE: { valMaxAbsolute = valMaxAbsolute / widthTot * 100; valMinAbsolute = valMinAbsolute / widthTot * 100; valueAccept = (value < valMaxAbsolute && value > valMinAbsolute) ? true : false; break; } } if (valueAccept) { List dimensions = m_Parent.SashList; List absoluteValList = new List(); foreach (var item in m_Parent.SashList) { absoluteValList.Add(item.CalculateAbsoluteValue(widthTot)); } int nIndex = dimensions.IndexOf(this); int proportionalCount = dimensions.Where(x => x.MeasureType.Equals(MeasureTypes.PROPORTIONAL)).ToList().Count; int percentageCount = dimensions.Where(x => x.MeasureType.Equals(MeasureTypes.PERCENTAGE)).ToList().Count; // Le dimensioni sono solo in proporzionale if (proportionalCount == absoluteValList.Count || SelMeasureType.Equals(MeasureTypes.PROPORTIONAL) || (SelMeasureType.Equals(MeasureTypes.ABSOLUTE) && proportionalCount == absoluteValList.Count -1)) { m_dDimension = value; } // Le dimensioni sono solo in percentuale else if (percentageCount == dimensions.Count) { if (value < dDimension) { // L'anta modificata non è l'ultima if (nIndex < dimensions.Count - 1) dimensions[nIndex + 1].SetDimension(dimensions[nIndex + 1].dDimension + (m_dDimension - value)); else if (dimensions.Count > 1) dimensions[nIndex - 1].SetDimension(dimensions[nIndex - 1].dDimension + (m_dDimension - value)); else { m_dDimension = 100; return; } } else { double dRes = value; // se non ultima anta if (nIndex < dimensions.Count - 1) { for (var nInd = 0; nInd <= nIndex - 1; nInd++) dRes += dimensions[nInd].dDimension; dRes = (100 - dRes) / (dimensions.Count - nIndex - 1); for (var Ind = nIndex + 1; Ind <= dimensions.Count - 1; Ind++) dimensions[Ind].SetDimension(dRes); } // se ultima anta else if (dimensions.Count > 1) { if (dimensions.Count > 2) { for (var Ind = 0; Ind <= nIndex - 2; Ind++) dRes += dimensions[Ind].dDimension; } dRes = (100 - dRes); dimensions[nIndex - 1].SetDimension(dRes); } else { m_dDimension = 100; return; } } m_dDimension = value; } // Le dimensioni sono miste o solo in assoluto else { double valueInAbsolute = 0; switch (MeasureType) { case MeasureTypes.ABSOLUTE: { valueInAbsolute = value; break; } case MeasureTypes.PROPORTIONAL: { var pesi = value + dimensions .Where(x => x.MeasureType.Equals(MeasureTypes.PROPORTIONAL) && !x.Equals(this)) .Sum(x => x.m_dDimension); valueInAbsolute = widthTot / pesi * value; break; } case MeasureTypes.PERCENTAGE: { valueInAbsolute = (value / 100) * widthTot; break; } } if (value < dDimension) { // L'anta modificata non è l'ultima if (nIndex < absoluteValList.Count - 1) { absoluteValList[nIndex + 1] = absoluteValList[nIndex + 1] + (absoluteValList[nIndex] - valueInAbsolute); absoluteValList[nIndex] = valueInAbsolute; } // L'anta modificata è l'ultima else if (dimensions.Count > 1) { absoluteValList[nIndex - 1] = absoluteValList[nIndex - 1] + (absoluteValList[nIndex] - valueInAbsolute); absoluteValList[nIndex] = valueInAbsolute; } } else { // L'anta modificata non è l'ultima if (nIndex < absoluteValList.Count - 1) { absoluteValList[nIndex + 1] = absoluteValList[nIndex + 1] - (valueInAbsolute - absoluteValList[nIndex]); absoluteValList[nIndex] = valueInAbsolute; } // L'anta modificata è l'ultima else if (dimensions.Count > 1) { absoluteValList[nIndex - 1] = absoluteValList[nIndex - 1] - (valueInAbsolute - absoluteValList[nIndex]); absoluteValList[nIndex] = valueInAbsolute; } } if (MeasureType.Equals(MeasureTypes.PROPORTIONAL)) m_dDimension = value; for (int i = 0; i < absoluteValList.Count; i++) { var item = m_Parent.SashList.ElementAt(i); item.SetDimension(ConvertIn(absoluteValList[i], (MeasureTypes)item.SelMeasureTypeIndex, widthTot)); } } } } } public int nSashId { get { return m_nSashId; } } public Openings OpeningType { get { return m_SelOpeningType; } } public List OpeningTypeList { get { return m_OpeningTypeList; } } public Openings SelOpeningType { get { return m_SelOpeningType; } set { m_SelOpeningType = value; m_Parent.ClearHardwareOptionList(); m_Parent.SetFirstHardware(); } } public int SelOpeningTypeIndex { get { return (int)m_SelOpeningType; } set { Openings newOpening = (Openings)value; if ((newOpening != Openings.TILTTURN_LEFT && newOpening != Openings.TILTTURN_RIGHT) || (newOpening == Openings.TILTTURN_LEFT && m_bHasHandle) || (newOpening == Openings.TILTTURN_RIGHT && m_bHasHandle)) { m_SelOpeningType = newOpening; m_Parent.ClearHardwareOptionList(); m_Parent.RefreshHardwareList(); m_Parent.SetFirstHardware(); } } } 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 int SelMeasureTypeIndex { get { return (int)m_SelMeasureType; } set { if(m_SelMeasureType != (MeasureTypes)value) { MeasureTypes newType = (MeasureTypes)value; double widthTot = CalculateWidthSashGroup(m_Parent.ParentWindow.AreaList.FirstOrDefault(), m_Parent.ParentWindow.AreaList.FirstOrDefault().DimensionList.Where(x => x.sName == "Width").First().dValue); m_dDimension = ConvertDimension(m_SelMeasureType, newType, widthTot); m_SelMeasureType = (MeasureTypes)value; } } } #endregion Public Properties #region Public Methods /// /// Metodo per convertire la dimensione dal vecchio tipo al nuovo tipo /// /// Vecchio tipo /// Nuovo tipo /// public double ConvertDimension(MeasureTypes oldType, MeasureTypes newType, double widthTot) { switch (oldType) { case MeasureTypes.ABSOLUTE: { if (newType.Equals(MeasureTypes.PERCENTAGE)) { //return Double.Round((m_dDimension / m_Parent.Width) * 100, 1); return (m_dDimension / widthTot) * 100; } else { return CalculatePropVal(widthTot); } } case MeasureTypes.PROPORTIONAL: { if (newType.Equals(MeasureTypes.ABSOLUTE)) { //return Double.Round(ConvertFromPropVal(newType), 2); return ConvertFromPropVal(newType, widthTot); } else { //return Double.Round(ConvertFromPropVal(newType), 1); return ConvertFromPropVal(newType, widthTot); } } case MeasureTypes.PERCENTAGE: { if (newType.Equals(MeasureTypes.ABSOLUTE)) { //return Double.Round((m_dDimension * m_Parent.Width) / 100, 2); return (m_dDimension * widthTot) / 100; } else { return CalculatePropVal(widthTot); } } } return -1; } /// /// Metodo per copiare l'intero oggetto /// /// public SashDimension Copy() { SashDimension newSashDim = new SashDimension(dDimension, MeasureType, m_Parent, m_nSashId); newSashDim.SetMeasureType(MeasureType); newSashDim.SetOpeningType(SelOpeningType); newSashDim.SetHasHandle(bHasHandle); foreach (var item in JointList) { Joint newJoint = item.Copy(); newSashDim.JointList.Add(newJoint); } return newSashDim; } #endregion Public Methods #region Internal Methods /// /// Metodo per calcolare larghezza intera sash group /// /// area di partenza /// larghezza di partenza /// internal double CalculateWidthSashGroup(Area area, double width) { for(int i = 0; i < area.AreaList.Count; i++) { double risultato = -1; if (area.Equals(m_Parent)) return width; Area item = area.AreaList[i]; if (area is Split) { Split split = (Split)area; if (split.SplitVertList.Count > 0) { switch (split.SplitVertList.ElementAt(i).SelMeasureType) { case MeasureTypes.ABSOLUTE: { risultato = CalculateWidthSashGroup(item, split.SplitVertList.ElementAt(i).dDimension); break; } case MeasureTypes.PROPORTIONAL: { //risultato = CalculateWidthSashGroup(item, split.SplitVertList.ElementAt(i).dDimension); break; } case MeasureTypes.PERCENTAGE: { risultato = CalculateWidthSashGroup(item, split.SplitVertList.ElementAt(i).dDimension * width / 100); break; } } if (risultato != -1) return risultato; } else { risultato = CalculateWidthSashGroup(item, width); } } else if (area is Sash) { Sash sash = (Sash)area; switch (sash.SashList.ElementAt(i).SelMeasureType) { case MeasureTypes.ABSOLUTE: { risultato = CalculateWidthSashGroup(item, sash.SashList.ElementAt(i).dDimension); break; } case MeasureTypes.PROPORTIONAL: { //risultato = CalculateWidthSashGroup(item, sash.SashList.ElementAt(i).dDimension); break; } case MeasureTypes.PERCENTAGE: { risultato = CalculateWidthSashGroup(item, sash.SashList.ElementAt(i).dDimension * width / 100); break; } } if (risultato != -1) return risultato; } else { risultato = CalculateWidthSashGroup(item, width); if (risultato != -1) return risultato; } } return width; } /// /// Calcolo MCD /// /// /// /// internal static 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(double widthTot) { if (m_Parent.SashList.Where(m => m.MeasureType.Equals(MeasureTypes.PROPORTIONAL)).ToList().Count == 0) { return 1; } List absoluteValue = new List(); foreach (var item in m_Parent.SashList) { absoluteValue.Add(item.CalculateAbsoluteValue(widthTot)); } for (int i = 0; i < m_Parent.SashList.Count; i++) { if (!m_Parent.SashList.ElementAt(i).Equals(this) && m_Parent.SashList.ElementAt(i).MeasureType.Equals(MeasureTypes.PROPORTIONAL)) { int nIndex = m_Parent.SashList.IndexOf(this); if (absoluteValue.ElementAt(nIndex) <= absoluteValue.ElementAt(i)) { var mcd = CalculateMCD(absoluteValue.ElementAt(nIndex), absoluteValue.ElementAt(i)); m_Parent.SashList.ElementAt(i).m_dDimension = absoluteValue.ElementAt(i) / mcd; m_dDimension = absoluteValue.ElementAt(nIndex) / mcd; } else { var mcd = CalculateMCD(absoluteValue.ElementAt(nIndex), absoluteValue.ElementAt(i)); m_Parent.SashList.ElementAt(i).m_dDimension = absoluteValue.ElementAt(i) / mcd; m_dDimension = absoluteValue.ElementAt(nIndex) / mcd; } break; } } return m_dDimension; } /// /// Metodo per trasformare una dimensione in valore assoluto rispetto alla larghezza totale /// /// Larghezza totale /// internal double CalculateAbsoluteValue(double widthTot) { switch (MeasureType) { case MeasureTypes.ABSOLUTE: { //return Double.Round(dDimension, 2); return dDimension; } case MeasureTypes.PROPORTIONAL: { //return Double.Round(Proportional2AbsolutVal(), 2); return ProportionalFromAbsoluteVal(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(double absoluteVal, MeasureTypes type, double widthTot) { switch (type) { case MeasureTypes.ABSOLUTE: { return absoluteVal; } case MeasureTypes.PROPORTIONAL: { return ProportionalFromAbsoluteVal(widthTot); } case MeasureTypes.PERCENTAGE: { return (absoluteVal / widthTot) * 100; } } return -1; } /// /// Metodo per convertire da misura proporzionale a misura assoluta o percentuale /// /// /// internal double ConvertFromPropVal(MeasureTypes newType, double widthTot) { double tot = widthTot; //Somma misura non proporzionali double sumNotProp = m_Parent.SashList .Where(m => m.MeasureType != MeasureTypes.PROPORTIONAL && !m.Equals(this)) .Sum(m => m.CalculateAbsoluteValue(tot)); //Calcolo residuo double res = tot - sumNotProp; if (res < 0) res = 0; //Misure proporzionali var proportionalList = m_Parent.SashList .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 ProportionalFromAbsoluteVal(double widthTot) { double tot = widthTot; //Somma misura non proporzionali double sumNotProp = m_Parent.SashList .Where(m => m.MeasureType != MeasureTypes.PROPORTIONAL) .Sum(m => m.CalculateAbsoluteValue(tot)); //Calcolo residuo double res = tot - sumNotProp; if (res < 0) res = 0; //Misure proporzionali var proportionalList = m_Parent.SashList .Where(m => m.SelMeasureType == MeasureTypes.PROPORTIONAL) .ToList(); double sumPesi = proportionalList.Sum(p => p.dDimension); if (sumPesi == 0) sumPesi = 1; return res / sumPesi * dDimension; } internal JsonSashDimension Serialize() { JsonSashDimension JsonSashDimension = new JsonSashDimension(OpeningType, MeasureType, m_bHasHandle, m_dDimension, m_nSashId); foreach (var Joint in JointList) JsonSashDimension.JointList.Add(Joint.Serialize()); return JsonSashDimension; } internal void SetDimension(double dValue) { m_dDimension = dValue; } internal void SetHasHandle(bool value) { m_bHasHandle = value; } internal void SetOpeningType(Openings value) { m_SelOpeningType = value; } internal void SetMeasureType(MeasureTypes value) { m_SelMeasureType = value; } internal void SetSelMeasureType(MeasureTypes value) { if (m_SelMeasureType != (MeasureTypes)value) { MeasureTypes newType = (MeasureTypes)value; double widthTot = CalculateWidthSashGroup(m_Parent.ParentWindow.AreaList.FirstOrDefault(), m_Parent.ParentWindow.AreaList.FirstOrDefault().DimensionList.Where(x => x.sName == "Width").First().dValue); m_dDimension = ConvertDimension(m_SelMeasureType, newType, widthTot); m_SelMeasureType = (MeasureTypes)value; } } #endregion Internal Methods #region Private Fields private bool m_bHasHandle; private double m_dDimension; private int m_nSashId; private List m_OpeningTypeList = new List { new IdNameStruct((int)Openings.TURNONLY_LEFT, "A bandiera sinistra"), new IdNameStruct((int)Openings.TURNONLY_RIGHT, "A bandiera destra"), new IdNameStruct((int)Openings.TILTTURN_LEFT, "Ad anta-ribalta sinistra"), new IdNameStruct((int)Openings.TILTTURN_RIGHT, "Ad anta-ribalta destra"), new IdNameStruct((int)Openings.TILTONLY_TOP, "Solo verso alto"), new IdNameStruct((int)Openings.TILTONLY_BOTTOM, "Solo verso basso"), new IdNameStruct((int)Openings.PIVOT, "Pivot"), new IdNameStruct((int)Openings.FIXED, "Fissa"), new IdNameStruct((int)Openings.COMPLANARSLIDE_LEFT, "Complanare sinistra"), new IdNameStruct((int)Openings.COMPLANARSLIDE_RIGHT, "Complanare destra"), new IdNameStruct((int)Openings.LIFTSLIDE_LEFT, "Scorrevole sinistra"), new IdNameStruct((int)Openings.LIFTSLIDE_RIGHT, "Scorrevole destra") //new IdNameStruct((int)Openings.TURNONLY_LEFT, ">"), //new IdNameStruct((int)Openings.TURNONLY_RIGHT, "<"), //new IdNameStruct((int)Openings.TILTTURN_LEFT, ">*"), //new IdNameStruct((int)Openings.TILTTURN_RIGHT, "<*"), //new IdNameStruct((int)Openings.TILTONLY_TOP, "˄"), //new IdNameStruct((int)Openings.TILTONLY_BOTTOM, "˅"), //new IdNameStruct((int)Openings.PIVOT, "◊"), //new IdNameStruct((int)Openings.FIXED, "X"), //new IdNameStruct((int)Openings.COMPLANARSLIDE_LEFT, "-→"), //new IdNameStruct((int)Openings.COMPLANARSLIDE_RIGHT, "←-"), //new IdNameStruct((int)Openings.LIFTSLIDE_LEFT, "┌→"), //new IdNameStruct((int)Openings.LIFTSLIDE_RIGHT, "←┐") }; private List m_MeasureTypeList = new List { new IdNameStruct((int)MeasureTypes.ABSOLUTE, "Absolute"), new IdNameStruct((int)MeasureTypes.PROPORTIONAL, "Proportional"), new IdNameStruct((int)MeasureTypes.PERCENTAGE, "Percentage"), }; // reference private Sash m_Parent; private List m_JointList = new List(); private Openings m_SelOpeningType; private MeasureTypes m_SelMeasureType; #endregion Private Fields } }