Files
2026-02-04 18:16:30 +01:00

1292 lines
50 KiB
C#

using Egw.Window.Data;
using Microsoft.AspNetCore.Components;
using Newtonsoft.Json;
using System.Threading.Tasks;
using WebWindowTest.Compo;
using WebWindowTest.DTO;
using WebWindowTest.Json;
using WebWindowTest.Models;
using WebWindowTest;
using static WebWindowTest.Json.WindowConst;
using static WebWindowTest.LayoutConst;
namespace WebWindowTest
{
public partial class Test : IDisposable
{
#region Public Enums
public enum DataReq
{
/// <summary>
/// Nessuna richiesta
/// </summary>
None = 0,
/// <summary>
/// Richiesta hardware opzioni
/// </summary>
ReqHwOpt,
/// <summary>
/// Richiesta svg
/// </summary>
ReqSvg,
/// <summary>
/// Richiesta shape sash group
/// </summary>
ReqShape
}
#endregion Public Enums
#region Public Properties
/// <summary>
/// Classe override css x SVG (x rescale)
/// </summary>
[Parameter]
public string CssSvg { get; set; } = "responsive-svg";
/// <summary>
/// Preselezione valori
/// </summary>
[Parameter]
public SelectPayload? CurrSelection { get; set; } = null;
/// <summary>
/// Richiesta azione al parent
/// </summary>
[Parameter]
public EventCallback<DataAction> EC_ActionReq { get; set; }
/// <summary>
/// Richiesta update da JWD (SVG, calcoli vari...)
/// </summary>
[Parameter]
public EventCallback<Dictionary<string, string>> EC_DoUpdate { get; set; }
/// <summary>
/// Richiesta chiusura JWD (+ refresh)
/// se torna true --> richiesta salvataggio
/// se torna false --> richiesta revert
/// </summary>
[Parameter]
public EventCallback<bool> EC_OnClose { get; set; }
/// <summary>
/// Sollevo evento errore validazione con una lista di errori rilevati
/// </summary>
[Parameter]
public EventCallback<Dictionary<string, string>> EC_ValidError { get; set; }
/// <summary>
/// Elenco anagrafiche di base
/// </summary>
[Parameter]
public BaseListPayload ListPayload { get; set; } = null!;
/// <summary>
/// Dati live controllo (JWD, SVG, ...)
/// </summary>
[Parameter]
public LivePayload LiveData { get; set; } = null!;
#endregion Public Properties
#region Public Methods
public void Dispose()
{
if (m_CurrWindow != null)
{
m_CurrWindow = null;
}
}
#endregion Public Methods
#region Protected Fields
protected List<string> currLoading = new List<string>();
/// <summary>
/// Dati live precedenti x comparazione
/// </summary>
protected LivePayload? prevLiveData = null;
#endregion Protected Fields
#region Protected Properties
protected List<Fill> FillList
{
get => m_FillList;
}
protected Frame FrameWindow
{
get => m_Frame!;
set => m_Frame = value;
}
protected List<ItemTable> ItemTableList
{
get => m_ItemTableList;
}
/// <summary>
/// Componente SVG da mostrare
/// </summary>
protected MarkupString outSvg
{
get
{
// aggiunta gestione classe svg per posizionamento con costraints
var newSvg = LiveData.SvgPreview.Replace("<svg", $"<svg class=\"{CssSvg}\"");
return (MarkupString)newSvg;
}
}
protected List<Sash> SashList
{
get => m_SashList;
}
protected List<Splitted> SplittedList
{
get => m_SplittedList;
}
protected string SelColorMaterial { get; set; } = "";
protected string SelFamilyHardware { get; set; } = "";
protected string SelGlass { get; set; } = "";
protected string SelMaterial { get; set; } = ""!;
protected string SelProfile { get; set; } = "";
protected List<Split> SplitList
{
get => m_SplitList;
}
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Metodo per riempire la lista ItemTable in modo da poter rappresentarla come tabella
/// </summary>
/// <param name="node"> Area da classificare </param>
/// <param name="row"> numero di riga </param>
/// <param name="col"> numero di colonna </param>
/// <param name="maxRow"> numero di riga massimo </param>
/// <param name="maxCol"> numero di colonna massimo </param>
protected void CreateElementTable(Area node, int row, int col, int maxRow, int maxCol)
{
if (node != null)
{
switch (node.AreaType)
{
case AreaTypes.FRAME:
{
if (node.AreaList.Count >= 1)
ItemTableList.Add(new ItemTable(AreaTypes.FRAME, "FR", row, col, -1, node.AreaList.Count));
else
ItemTableList.Add(new ItemTable(AreaTypes.FRAME, "FR", row, col, -1, 0));
row++;
col++;
maxRow++;
maxCol++;
break;
}
case AreaTypes.SASH:
{
string nWIndow;
// Se ha fratelli
if ((node.ParentArea.ParentArea != null && node.ParentArea.ParentArea.AreaList.Count > 1) ||
(node.ParentArea != null && node.ParentArea.AreaList.Count > 1))
{
for (int i = 0; i < SashList.Count; i++)
{
if (SashList[i].Equals(node))
{
nWIndow = SashList.Count == 1 ? "" : $"{i + 1}";
// Se il nodo ha figli, salvo il numero nell'oggetto
if (node.AreaList.Count >= 1)
ItemTableList.Add(new ItemTable(AreaTypes.SASH, "SG" + nWIndow, maxRow, col, i, node.AreaList.Count));
else
ItemTableList.Add(new ItemTable(AreaTypes.SASH, "SG" + nWIndow, maxRow, col, i, 0));
}
}
maxCol++;
}
else
{
// Se il nodo ha figli, salvo il numero nell'oggetto
if (node.AreaList.Count >= 1)
ItemTableList.Add(new ItemTable(AreaTypes.SASH, "SG", row, col, 0, node.AreaList.Count));
else
ItemTableList.Add(new ItemTable(AreaTypes.SASH, "SG", row, col, 0, 0));
maxCol++;
}
row++;
col++;
maxRow++;
break;
}
case AreaTypes.FILL:
{
if ((node.ParentArea.AreaList.Count > 1 && node.ParentArea.AreaList.First().Equals(node)) ||
(node.ParentArea.ParentArea != null && node.ParentArea.ParentArea.AreaList.Count > 1 && node.ParentArea.ParentArea.AreaList.First().AreaList.First().Equals(node)))
maxCol++;
string nFill;
for (int i = 0; i < FillList.Count; i++)
{
if (FillList[i].Equals(node))
{
nFill = FillList.Count == 1 ? "" : $"{i + 1}";
ItemTableList.Add(new ItemTable(AreaTypes.FILL, "FL" + nFill, maxRow, col, i, 0));
break;
}
}
row++;
col++;
maxRow++;
break;
}
case AreaTypes.SPLIT:
{
// Se il nodo ha fratelli o cugini
if (node.ParentArea.AreaList.Count > 1 || (node.ParentArea.ParentArea != null && node.ParentArea.ParentArea.AreaList.Count > 1))
{
if (node.ParentArea.AreaList.First().Equals(node) || node.ParentArea.ParentArea.AreaList.First().Equals(node))
maxCol++;
for (int i = 0; i < SplitList.Count; i++)
{
if (SplitList[i].Equals(node))
{
string nSplit = SplitList.Count == 1 ? "" : $"{i + 1}";
if (node.AreaList.Count >= 1)
ItemTableList.Add(new ItemTable(AreaTypes.SPLIT, "SP" + nSplit, maxRow, col, i, node.AreaList.Count));
else
ItemTableList.Add(new ItemTable(AreaTypes.SPLIT, "SP" + nSplit, maxRow, col, i, 0));
}
}
}
else
{
for (int i = 0; i < SplitList.Count; i++)
{
if (SplitList[i].Equals(node))
{
string nSplit = SplitList.Count == 1 ? "" : $"{i + 1}";
if (node.AreaList.Count >= 1)
ItemTableList.Add(new ItemTable(AreaTypes.SPLIT, "SP" + nSplit, row, col, i, node.AreaList.Count));
else
ItemTableList.Add(new ItemTable(AreaTypes.SPLIT, "SP" + nSplit, row, col, i, 0));
maxCol++;
}
}
}
row++;
col++;
maxRow++;
break;
}
case AreaTypes.SPLITTED:
{
break;
}
}
foreach (var item in node.AreaList)
{
if (maxRow < m_maxRow)
CreateElementTable(item, row, col, m_maxRow, maxCol);
else
CreateElementTable(item, row, col, maxRow, maxCol);
}
}
if (maxCol > m_maxCol)
{
m_maxCol = maxCol;
}
if (maxRow > m_maxRow)
{
m_maxRow = maxRow;
}
}
/// <summary>
/// Metodo per riempire le liste Sash, Split, Splitted e Fill
/// </summary>
/// <param name="node"> Area da classificare </param>
/// <param name="IntoSash"> Parametro per sapere se si è dentro un'anta </param>
protected void CreateWindowsList(Area node, bool IntoSash)
{
if (node != null)
{
if (node.ParentArea is Sash || IntoSash == true)
IntoSash = true;
switch (node.AreaType)
{
case AreaTypes.FRAME:
{
FrameWindow = (Frame)node;
break;
}
case AreaTypes.SASH:
{
m_SashList.Add((Sash)node);
break;
}
case AreaTypes.FILL:
{
m_FillList.Add((Fill)node);
break;
}
case AreaTypes.SPLIT:
{
m_SplitList.Add((Split)node);
break;
}
case AreaTypes.SPLITTED:
{
if (node.ParentArea is Split && !IntoSash && node.AreaList.First() is Fill)
{
m_SplittedList.Add((Splitted)node);
}
break;
}
}
foreach (var item in node.AreaList)
{
CreateWindowsList(item, IntoSash);
}
}
}
/// <summary>
/// Calcola CSS warning
/// </summary>
/// <param name="fKey"></param>
/// <returns></returns>
protected string cssValid(string fKey)
{
return listWarnings.ContainsKey(fKey) ? "border border-danger" : "";
}
/// <summary>
/// Richiesta chiusura SENZA salvataggio (= restore prev)
/// </summary>
/// <returns></returns>
protected async Task DoClose()
{
editLock = false;
await EC_OnClose.InvokeAsync(false);
}
/// <summary>
/// Richiesta update anteprima SVG
/// </summary>
/// <param name="doForce">Forza richiesta anche con JWD invariato</param>
/// <param name="hideHw">Nasconde hw (def. false) poiché senza è piu rapido</param>
/// <returns></returns>
protected async Task DoPreviewSvg(bool doForce = false, bool hideHw = false)
{
if (m_CurrWindow != null)
{
#if DEBUG
var CurrJwd = JsonConvert.SerializeObject(m_CurrWindow.Serialize(false), Formatting.Indented);
var CalcJwd = JsonConvert.SerializeObject(m_CurrWindow.Serialize(hideHw), Formatting.Indented);
#else
var CurrJwd = JsonConvert.SerializeObject(m_CurrWindow.Serialize(false));
var CalcJwd = JsonConvert.SerializeObject(m_CurrWindow.Serialize(hideHw));
#endif
// verifico variazione JWD
if (!prevJwd.Equals(CurrJwd) || doForce || prevReq != (int)DataReq.ReqSvg)
{
prevJwd = CurrJwd;
prevReq = (int)DataReq.ReqSvg;
Dictionary<string, string> Args = new Dictionary<string, string>();
Args.Add("Mode", $"{(int)Enums.QuestionModes.PREVIEW}");
Args.Add("SerializedData", CalcJwd);
await EC_DoUpdate.InvokeAsync(Args);
}
}
}
/// <summary>
/// Richiesta calcolo Options HW
/// </summary>
/// <param name="groupIdList">Lista degli ID numerici dei gruppi da valutare</param>
/// <returns></returns>
protected async Task DoReqOptHardware(List<int> groupIdList, bool isFirst = false)
{
if (m_CurrWindow != null)
{
loadListAdd("LoadHwOpt");
#if DEBUG
var CurrJwd = JsonConvert.SerializeObject(m_CurrWindow.Serialize(), Formatting.Indented);
#else
var CurrJwd = JsonConvert.SerializeObject(m_CurrWindow.Serialize());
#endif
// verifico variazione JWD
if (!prevJwd.Equals(CurrJwd) || isFirst || prevReq != (int)DataReq.ReqHwOpt)
{
prevJwd = CurrJwd;
prevReq = (int)DataReq.ReqHwOpt;
Dictionary<string, string> Args = new Dictionary<string, string>();
Args.Add("Mode", $"{(int)Enums.QuestionModes.HARDWARE}");
Args.Add("SubMode", $"{(int)Enums.QuestionHwSubModes.HARDWAREOPTIONS}");
Args.Add("SerializedData", CurrJwd);
string listGroupId = JsonConvert.SerializeObject(groupIdList);
Args.Add("GroupId", listGroupId);
await EC_DoUpdate.InvokeAsync(Args);
}
}
}
/// <summary>
/// Richiesta Shape compatibile da JWD
/// </summary>
/// <param name="groupIdList">Lista degli ID numerici dei gruppi da valutare</param>
/// <returns></returns>
protected async Task DoReqShape(List<int> groupIdList)
{
if (m_CurrWindow != null)
{
#if DEBUG
var CurrJwd = JsonConvert.SerializeObject(m_CurrWindow.Serialize(), Formatting.Indented);
#else
var CurrJwd = JsonConvert.SerializeObject(m_CurrWindow.Serialize());
#endif
// verifico variazione JWD
if (!prevJwd.Equals(CurrJwd) || prevReq != (int)DataReq.ReqShape)
//if (!prevLiveData.CurrJwd.Equals(CurrJwd))
{
prevJwd = CurrJwd;
prevReq = (int)DataReq.ReqShape;
Dictionary<string, string> Args = new Dictionary<string, string>();
Args.Add("Mode", $"{(int)Enums.QuestionModes.HARDWARE}");
Args.Add("SubMode", $"{(int)Enums.QuestionHwSubModes.SASHSHAPE}");
Args.Add("SerializedData", CurrJwd);
string listGroupId = JsonConvert.SerializeObject(groupIdList);
Args.Add("GroupId", listGroupId);
await EC_DoUpdate.InvokeAsync(Args);
}
}
}
/// <summary>
/// Metodo di reset
/// </summary>
protected Task DoReset()
{
return Task.CompletedTask;
// Da fare
}
/// <summary>
/// Richiesta chiusura con salvataggio
/// </summary>
/// <returns></returns>
protected async Task DoSave()
{
editLock = false;
//manca salvataggio JWD
await EC_OnClose.InvokeAsync(true);
}
protected override void OnAfterRender(bool firstRender)
{
isRendered = true;
}
/// <summary>
/// Primo init componente
/// </summary>
protected override void OnInitialized()
{
// reset editLock...
editLock = false;
listErrPre = new Dictionary<string, string>();
listErrLink = new Dictionary<string, string>();
listWarnings = new Dictionary<string, string>();
}
/// <summary>
/// Gestione update post ricezione parametri da controllo chiamante
/// </summary>
protected override async Task OnParametersSetAsync()
{
isLoading = true;
// SOLO SE sono presenti...
if (ListPayload.IsPopulated() && LiveData.IsValid())
{
bool updRequested = false;
listErrPre = new Dictionary<string, string>();
listErrLink = new Dictionary<string, string>();
listWarnings = new Dictionary<string, string>();
// controllo elenchi BasePayload siano validi...
if (ListPayload.IsValid())
{
// SOLO SE modificato live data...
if (prevLiveData == null || !prevLiveData.Equals(LiveData))
{
bool needDeser = prevLiveData == null || !prevLiveData.JwdEqual(LiveData);
updRequested = true;
prevLiveData = new LivePayload()
{
CurrJwd = LiveData.CurrJwd,
DictOptionsXml = LiveData.DictOptionsXml,
DictShape = LiveData.DictShape,
SvgPreview = LiveData.SvgPreview
};
// Aggiornati parametri di ingresso selezionati
UpdateSelParameter();
// provo a deserializzare SE necessario
if (needDeser)
{
JsonWindow WindowFromJson = new JsonWindow("", "", "", "");
try
{
WindowFromJson = JsonConvert.DeserializeObject<JsonWindow>(LiveData.CurrJwd, new PolymorphicJsonConverter()) ?? new JsonWindow("", "", "", "");
setCurrWindow(WindowFromJson);
//SOLO SE non sono in edit...
if (!editLock)
{
currStep = CompileStep.Tree;
}
}
// altrimenti errore!
catch (Exception ex)
{
listErrLink.Add("Window", $"Deserializing Error:{Environment.NewLine}{ex}");
// uso un oggetto "basico" per non fermarmi
//string jwd = "{\r\n \"ProfilePath\": \"Profilo78\",\r\n \"Material\": \"Pino\",\r\n \"ColorMaterial\": \"Black\",\r\n \"Glass\": \"Vetro BE 2S 4T/16/4T\",\r\n \"AreaList\": [\r\n {\r\n \"Shape\": \"RECTANGLE\",\r\n \"DimensionList\": [\r\n {\r\n \"Index\": 1,\r\n \"Name\": \"Width\",\r\n \"Value\": 800.0\r\n },\r\n {\r\n \"Index\": 2,\r\n \"Name\": \"Height\",\r\n \"Value\": 1200.0\r\n }\r\n ],\r\n \"JointList\": [\r\n {\r\n \"Index\": 1,\r\n \"JointType\": \"FULL_H\"\r\n },\r\n {\r\n \"Index\": 2,\r\n \"JointType\": \"FULL_H\"\r\n },\r\n {\r\n \"Index\": 3,\r\n \"JointType\": \"FULL_H\"\r\n },\r\n {\r\n \"Index\": 4,\r\n \"JointType\": \"FULL_H\"\r\n }\r\n ],\r\n \"BottomRail\": false,\r\n \"BottomRailQty\": 0,\r\n \"GroupId\": 1,\r\n \"AreaList\": [\r\n {\r\n \"FillType\": \"GLASS\",\r\n \"GroupId\": 7,\r\n \"AreaList\": [],\r\n \"AreaType\": \"FILL\"\r\n }\r\n ],\r\n \"AreaType\": \"FRAME\"\r\n }\r\n ]\r\n}";
//WindowFromJson = JsonConvert.DeserializeObject<JsonWindow>(jwd, new PolymorphicJsonConverter()) ?? new JsonWindow("", "", "", "");
//setCurrWindow(WindowFromJson);
//await DoPreviewSvg(true);
Window window = new Window();
Frame frame = new Frame(null, window);
List<FrameDimension> DimensionList = new List<FrameDimension>
{
new FrameDimension(frame, 1, "Width", 800, false),
new FrameDimension(frame, 1, "Height", 1200, true)
};
List<Joint> JointList = new List<Joint>
{
new Joint(frame, 1, Joints.FULL_H),
new Joint(frame, 2, Joints.FULL_H),
new Joint(frame, 3, Joints.FULL_H),
new Joint(frame, 4, Joints.FULL_H)
};
//FrameArcElement ae = new FrameArcElement(frame, window, 10, true, true);
JsonWindow jsonWindow = new JsonWindow("Profilo78", "Pino", "Black", "Vetro BE 2S 4T/16/4T");
JsonFrame jsonFrame = new JsonFrame(Shapes.RECTANGLE, null, false, 0, 1);
jsonWindow.AreaList.Add(jsonFrame);
//jsonFrame.ArcElement = ae.Serialize();
foreach (var Dimension in DimensionList)
jsonFrame.DimensionList.Add(Dimension.Serialize());
foreach (var Joint in JointList)
jsonFrame.JointList.Add(Joint.Serialize());
jsonFrame.AreaList.Add(Fill.CreateFill(frame, FillTypes.GLASS).Serialize(true));
string jwd = JsonConvert.SerializeObject(jsonWindow);
WindowFromJson = JsonConvert.DeserializeObject<JsonWindow>(jwd, new PolymorphicJsonConverter()) ?? new JsonWindow("", "", "", "");
setCurrWindow(WindowFromJson);
await DoPreviewSvg(true);
}
}
else
{
// usando m_currWindow (preesistente) impostare i parametri...
UpdateDict();
}
}
checkWarnings();
if (SashList.Count > 0)
{
currAntaIndex = 0;
}
if (updRequested)
{
// se mancasse dizionario forme chiamo quello
if (LiveData.DictShape.Count == 0 && listErrLink.Count == 0)
{
if (firstDisplay && isRendered)
{
firstDisplay = false;
// preview SVG senza HW
await DoPreviewSvg(true, true);
}
List<int> reqList = SashList.Select(x => x.GroupId).ToList();
if (reqList.Count > 0)
{
//prevReq = (int)DataReq.ReqShape;
await DoReqShape(reqList);
}
}
else
{
// chiedo SVG
//prevReq = (int)DataReq.ReqSvg;
if (prevReq != (int)DataReq.ReqSvg || !prevLiveData.JwdEqual(LiveData.CurrJwd))
{
if (prevReq != (int)DataReq.ReqHwOpt)
await DoPreviewSvg(true);
else if (LiveData.DictOptionsXml.Count > 0)
await DoPreviewSvg(true);
}
}
}
}
else
{
checkErrorPre();
}
isLoading = false;
}
}
/// <summary>
/// Metodo per costruire oggetti della Window
/// </summary>
/// <param name="WindowFromJson"></param>
protected void setCurrWindow(JsonWindow WindowFromJson)
{
if (m_CurrWindow != null)
{
m_CurrWindow = null;
}
m_CurrWindow = WindowFromJson.Deserialize();
FrameWindow = m_CurrWindow.AreaList[0];
if (m_PreviousWindow != null)
{
for (int i = 0; i < 2; i++)
m_CurrWindow.AreaList.First().DimensionList[i].dDimension = m_PreviousWindow.AreaList.First().DimensionList[i].dDimension;
if (m_CurrWindow.AreaList.First().Shape == Shapes.TRIANGLE)
{
for (int i = 0; i < 2; i++)
m_CurrWindow.AreaList.First().JointList[i].SetSelJointType(m_PreviousWindow.AreaList.First().JointList[i].SelJointType);
}
else
{
for (int i = 0; i < 4; i++)
m_CurrWindow.AreaList.First().JointList[i].SetSelJointType(m_PreviousWindow.AreaList.First().JointList[i].SelJointType);
}
}
if (m_CurrWindow != null)
{
// Aggiornamento liste sash, split, splitted, fill e itemTable
UpdateLists();
}
if (SashList.Count > 0)
currAntaIndex = 0;
// Aggiorno window con dati shape e hw option
UpdateDict();
}
/// <summary>
/// Aggiornamento dei dati con informazioni ricevute dai dizionari
/// </summary>
protected void UpdateDict()
{
// se ho i dizionari delle forme le aggiungo
if (LiveData.DictShape.Count > 0)
{
// Inserisco le forme ricevuto nei sash group
foreach (var item in LiveData.DictShape)
{
Sash sashFromGroupId = SashList.First(x => x.GroupId == item.Key);
sashFromGroupId.SashShape = item.Value;
sashFromGroupId.UpdateShape(item.Value);
}
if (prevReq == (int)DataReq.ReqShape)
{
if (reqHwOpt > 0)
{
List<int> reqList = SashList.Select(x => x.GroupId).ToList();
_ = DoReqOptHardware(reqList);
}
}
}
// se ho le opzioni hw le aggiungo
if (LiveData.DictOptionsXml.Count > 0)
{
loadListRem("LoadHwOpt");
foreach (var item in SashList)
{
if (LiveData.DictOptionsXml.ContainsKey(item.GroupId))
{
item.SetHardwareOption(LiveData.DictOptionsXml[item.GroupId]);
}
}
}
}
/// <summary>
/// Metodo che resetta le liste (sash, split, splitted, fill e itemTable) e le crea nuovamente
/// </summary>
protected void UpdateLists()
{
m_maxCol = 0;
m_maxRow = 0;
m_FillList = new List<Fill>();
m_SashList = new List<Sash>();
m_SplitList = new List<Split>();
m_SplittedList = new List<Splitted>();
m_ItemTableList = new List<ItemTable>();
CreateWindowsList((m_CurrWindow!).AreaList.First(), false);
CreateElementTable(m_CurrWindow.AreaList.First(), 1, 1, 1, 1);
}
/// <summary>
/// Metodo per settare i parmateri di ingresso selezionati
/// </summary>
protected void UpdateSelParameter()
{
Frame.m_AllThresholdList = ListPayload.Threshold;
Sash.m_HardwareCompleteList = ListPayload.Hardware;
Sash.s_FamilyHardwareList = ListPayload.FamilyHardware;
if (CurrSelection != null && CurrSelection.IsValid())
{
SelFamilyHardware = CurrSelection.FamilyHardware ?? "";
SelColorMaterial = CurrSelection.ColorMaterial ?? "";
SelMaterial = CurrSelection.Material ?? "";
SelGlass = CurrSelection.Glass ?? "";
SelProfile = CurrSelection.Profile ?? "";
}
}
#endregion Protected Methods
#region Private Fields
private int currAntaIndex = 0;
private int currFillIndex = -1;
private int currSashIndex = -1;
private int currSplitIndex = -1;
private CompileStep currStep;
private bool editLock = false;
private bool firstDisplay = true;
/// <summary>
/// Booleana fase loading
/// </summary>
private bool isLoading = false;
private bool isRendered = false;
/// <summary>
/// ELenco errori di coerenza/link dati (vanno risolti per disegnare/procedere)
/// </summary>
private Dictionary<string, string> listErrLink = new Dictionary<string, string>();
/// <summary>
/// Elenco errori preliminari (mancano elementi di base di validazione modello dati))
/// </summary>
private Dictionary<string, string> listErrPre = new Dictionary<string, string>();
/// <summary>
/// Elenco warnings non bloccanti
/// </summary>
private Dictionary<string, string> listWarnings = new Dictionary<string, string>();
private List<Fill> m_FillList = new List<Fill>();
private Frame? m_Frame;
private List<ItemTable> m_ItemTableList = new List<ItemTable>();
private int m_maxCol = 0;
private int m_maxRow = 0;
private List<Sash> m_SashList = new List<Sash>();
private List<Split> m_SplitList = new List<Split>();
private List<Splitted> m_SplittedList = new List<Splitted>();
#endregion Private Fields
#region Private Properties
private Window? m_CurrWindow { get; set; } = null;
private Window? m_PreviousWindow { get; set; } = null;
/// <summary>
/// Salvataggio JWD precedente x evitare loop su update (aggiornato dopo chiamate redis)
/// </summary>
private string prevJwd { get; set; } = "";
/// <summary>
/// Salvataggio tipo di domanda precedente
/// </summary>
private int prevReq { get; set; } = 0;
private int reqHwOpt { get; set; } = 0;
#endregion Private Properties
#region Private Methods
/// <summary>
/// Metodo per andare allo step successivo
/// </summary>
/// <param name="newStep"> step successivo </param>
private void AdvStep(CompileStep newStep)
{
currStep = newStep;
currSashIndex = -1;
currFillIndex = -1;
currSplitIndex = -1;
}
/// <summary>
/// Verifica errori prelimionari per mostrare dove sia il problema
/// </summary>
private void checkErrorPre()
{
// verifico 1:1 le liste e indico cosa manca
if (ListPayload.Hardware == null || ListPayload.Hardware.Count == 0)
{
listErrPre.Add("Hardware", "Missing Hardware List!");
}
else
{
if (ListPayload.FamilyHardware == null || ListPayload.FamilyHardware.Count == 0)
{
listErrPre.Add("FamilyHardware", "Missing Family HW List!");
}
}
if (ListPayload.Glass == null || ListPayload.Glass.Count == 0)
{
listErrPre.Add("Glass", "Missing Glass List!");
}
if (ListPayload.Material == null || ListPayload.Material.Count == 0)
{
listErrPre.Add("Material", "Missing Material List!");
}
if (ListPayload.ColorMaterial == null || ListPayload.ColorMaterial.Count == 0)
{
listErrPre.Add("ColorMaterial", "Missing ColorMaterial List!");
}
if (ListPayload.Profile == null || ListPayload.Profile.Count == 0)
{
listErrPre.Add("Profile", "Missing Profile List!");
}
}
/// <summary>
/// Verifica warning minori (es coerenza colori...)
/// </summary>
private void checkWarnings()
{
// verifico 1:1 le liste e i valori siano coerenti...
if (ListPayload.ColorMaterial != null && ListPayload.ColorMaterial.Count > 0)
{
// verifico colore attuale sia consistente...
if (m_CurrWindow != null)
{
if (!ListPayload.ColorMaterial.Contains(m_CurrWindow.sColorMaterial))
{
listWarnings.Add("ColorMaterial", $"Missing Color: {m_CurrWindow.sColorMaterial}");
}
if (!ListPayload.Glass.Contains(m_CurrWindow.sGlass))
{
listWarnings.Add("Glass", $"Missing Glass: {m_CurrWindow.sGlass}");
}
if (!ListPayload.Material.Contains(m_CurrWindow.sMaterial))
{
listWarnings.Add("Material", $"Missing Material: {m_CurrWindow.sMaterial}");
}
if (!ListPayload.Profile.Contains(m_CurrWindow.sProfilePath))
{
listWarnings.Add("Profile", $"Missing Profile: {m_CurrWindow.sProfilePath}");
}
}
}
}
/// <summary>
/// Helper aggiunta elemento a lista caricamento
/// </summary>
/// <param name="loadCode"></param>
private void loadListAdd(string loadCode)
{
if (!currLoading.Contains(loadCode))
{
currLoading.Add(loadCode);
}
}
/// <summary>
/// Helper rimozione elemento a lista caricamento
/// </summary>
/// <param name="loadCode"></param>
private void loadListRem(string loadCode)
{
if (currLoading.Contains(loadCode))
{
currLoading.Remove(loadCode);
}
}
/// <summary>
/// Metodo per cambiare step
/// </summary>
/// <param name="newStep"> step successivo </param>
private void NextStep(CompileStep newStep, int Index = 1)
{
editLock = true;
currStep = newStep;
switch (newStep)
{
case CompileStep.Sash:
{
currSashIndex = Index;
currFillIndex = -1;
currSplitIndex = -1;
break;
}
case CompileStep.Fill:
{
currFillIndex = Index;
currSashIndex = -1;
currSplitIndex = -1;
break;
}
case CompileStep.Split:
{
currSplitIndex = Index;
currSashIndex = -1;
currFillIndex = -1;
break;
}
}
}
/// <summary>
/// Metodo per cambiare step
/// </summary>
/// <param name="Args"></param>
private void NextStepArgs(DataNextStep Args)
{
CompileStep newStep = Args.currCompileStep;
int Index = Args.index;
NextStep(newStep, Index);
}
/// <summary>
/// Richiesta reset dizionario Shape con action
/// </summary>
/// <param name="args"></param>
private async Task ReqResetDict(DataUpdateRes args)
{
await EC_ActionReq.InvokeAsync(args.req);
}
/// <summary>
/// Ritorno step Tree
/// </summary>
/// <param name="args"></param>
private void ReturnTree(bool args)
{
AdvStep(CompileStep.Tree);
}
private Area SearchArea(Area currentArea, int idSearch, Area itemSearch)
{
if (currentArea.GroupId == idSearch && currentArea.AreaType.Equals(itemSearch.AreaType))
{
return currentArea;
}
foreach (Area child in currentArea.AreaList)
{
Area found = SearchArea(child, idSearch, itemSearch);
if (found != null)
{
return found;
}
}
return null;
}
/// <summary>
/// Calcola il css del tab selezionato
/// </summary>
/// <param name="testStep"> Step </param>
/// <returns></returns>
private string tabNavCss(CompileStep testStep, int Index = -1)
{
if (testStep == CompileStep.Sash)
{
if ((currSashIndex == 0 && Index == 0) || (currSashIndex == 1 && Index == 1))
return "nav-link active fw-bold";
else
return "nav-link text-secondary";
}
else if (testStep == CompileStep.Fill)
{
if ((currFillIndex == 0 && Index == 0) || (currFillIndex == 1 && Index == 1))
return "nav-link active fw-bold";
else
return "nav-link text-secondary";
}
else if (testStep == CompileStep.Split)
{
if ((currSplitIndex == 0 && Index == 0) || (currSplitIndex == 1 && Index == 1))
return "nav-link active fw-bold";
else
return "nav-link text-secondary";
}
return (testStep == currStep) ? "nav-link active fw-bold" : "nav-link text-secondary";
}
/// <summary>
/// Metodo per cambiare tutti i Fill e richiedere aggiornamento SVG
/// </summary>
/// <param name="reqFillType"> tipo di fill richiesto </param>
/// <returns></returns>
protected async Task ChangeAllFill(FillTypes reqFillType)
{
updateAllFill(FrameWindow, reqFillType);
await DoPreviewSvg();
}
/// <summary>
/// Metodo per aggiornare tutti i Fill al nuovo tipo
/// </summary>
/// <param name="area"> area corrente</param>
/// <param name="type"> tipo a cui aggiornare</param>
private void updateAllFill(Area area, FillTypes type)
{
if (area.AreaType.Equals(AreaTypes.FILL))
{
Fill fill = (Fill)area;
fill.SetSelFillType(type);
return;
}
foreach (Area child in area.AreaList)
{
updateAllFill(child, type);
}
}
/// <summary>
/// Aggiornamento Fill
/// </summary>
/// <param name="newFill"> Fill da aggiornare</param>
/// <returns></returns>
private async Task UpdatePreviewFill(Fill newFill)
{
if (newFill != null)
{
// cerco il record
var currRec = (Fill)SearchArea(FrameWindow, newFill.GroupId, newFill);
// lo aggiorno
currRec = newFill;
await DoPreviewSvg();
}
}
/// <summary>
/// Aggiornamento Frame
/// </summary>
/// <param name="newFrame"> nuovo frame</param>
/// <returns></returns>
private async Task UpdatePreviewFrame(DataUpdateFrame args)
{
Frame newFrame = args.currFrame;
bool forceSvgNoHw = args.svgNoHw;
if (newFrame != null)
{
// cerco il record
var currRec = m_CurrWindow.AreaList.FirstOrDefault(x => x.GroupId == newFrame.GroupId);
// lo aggiorno
currRec = newFrame;
if (forceSvgNoHw)
await DoPreviewSvg(true, true);
else
await DoPreviewSvg();
}
}
/// <summary>
/// Aggiornamento opzioni dato nuovo frame
/// </summary>
/// <param name="newFrame"> nuovo frame </param>
/// <returns></returns>
private async Task UpdateHwOptionsFrame(Frame newFrame)
{
if (newFrame != null)
{
// cerco il record
var currRec = m_CurrWindow.AreaList.FirstOrDefault(x => x.GroupId == newFrame.GroupId);
// lo aggiorno
currRec = newFrame;
// resetto hw lst
await EC_ActionReq.InvokeAsync(DataAction.ResetHwOpt);
reqHwOpt++;
if (prevReq == (int)DataReq.ReqShape)
{
// richiesta calcolo opzioni hardware per la singola sash group
List<int> reqList = SashList.Select(x => x.GroupId).ToList();
// chiamo con gruppo della nuova sash
await DoReqOptHardware(reqList);
}
}
}
/// <summary>
/// Aggiornamento opzioni data nuova sash group
/// </summary>
/// <param name="newSash"> nuovo frame </param>
/// <returns></returns>
private async Task UpdateHwOptionsSash(Sash newSash)
{
if (newSash != null)
{
// cerco il record
var currRec = SearchArea(FrameWindow, newSash.GroupId, newSash);
// lo aggiorno
currRec = newSash;
// resetto hw lst
await EC_ActionReq.InvokeAsync(DataAction.ResetHwOpt);
//reqHwOpt++;
//if(prevReq == (int)DataReq.ReqShape)
//{
// richiesta calcolo opzioni hardware per la singola sash group
List<int> reqList = SashList.Select(x => x.GroupId).ToList();
// chiamo con gruppo della nuova sash
await DoReqOptHardware(reqList);
//}
}
}
/// <summary>
/// Richiesta opzioni hardware per la prima volta
/// </summary>
/// <param name="newSash"> nuovo frame </param>
/// <returns></returns>
private async Task ReqFirstOptionHw(Sash newSash)
{
if (newSash != null)
{
// cerco il record
var currRec = SearchArea(FrameWindow, newSash.GroupId, newSash);
// lo aggiorno
currRec = newSash;
// resetto hw lst
await EC_ActionReq.InvokeAsync(DataAction.ResetHwOpt);
// richiesta calcolo opzioni hardware per la singola sash group
List<int> reqList = SashList.Select(x => x.GroupId).ToList();
// chiamo con gruppo della nuova sash
await DoReqOptHardware(reqList);
}
}
/// <summary>
/// Aggiornamento Frame
/// </summary>
/// <param name="newFrame"> nuovo frame</param>
/// <returns></returns>
private async Task UpdatePreviewSplit(DataUpdateSplit args)
{
Split newSplit = args.currSplit;
bool forceSvgNoHw = args.svgNoHw;
bool noSvg = args.noSvg;
if (newSplit != null)
{
// cerco il record
var currRec = SearchArea(FrameWindow, newSplit.GroupId, newSplit);
// lo aggiorno
currRec = newSplit;
if (!noSvg)
{
if (forceSvgNoHw)
await DoPreviewSvg(true, true);
else
await DoPreviewSvg();
}
}
}
/// <summary>
/// Metodo per aggiornare Splitted
/// </summary>
/// <param name="currSplitted"> Splitted da aggiornare</param>
/// <returns></returns>
private async Task UpdatePreviewSplitted(Splitted currSplitted)
{
if (currSplitted != null)
{
var item = SearchArea(FrameWindow, currSplitted.GroupId, currSplitted);
item = currSplitted;
// ricalcolo liste
UpdateLists();
// richiedo update shape
List<int> reqList = SashList.Select(x => x.GroupId).ToList();
await DoPreviewSvg();
await DoReqShape(reqList);
}
}
/// <summary>
/// Aggiornamento opzioni dato update sash
/// </summary>
/// <param name="newSash"> nuova sash </param>
/// <returns></returns>
private async Task UpdatePreviewSashGroup(DataUpdateSash args)
{
Sash newSash = args.currSash;
bool svgNoHw = args.svgNoHw;
bool noSvg = args.noSvg;
if (svgNoHw)
{
Sash item = (Sash)SearchArea(FrameWindow, newSash.GroupId, newSash);
if (newSash != null && item != null)
{
item = newSash;
await DoPreviewSvg(true, true);
}
}
else
{
Sash item = (Sash)SearchArea(FrameWindow, newSash.GroupId, newSash);
if (newSash != null && item != null)
{
item = newSash;
if (!noSvg)
await DoPreviewSvg();
}
}
}
/// <summary>
/// Calcola bottone per tutti i Fill
/// </summary>
/// <returns></returns>
private string buttonFillCss(FillTypes reqFillTypes)
{
foreach (var fill in FillList)
{
if (!fill.FillType.Equals(reqFillTypes))
return "btn btn-outline-secondary btn-sm";
}
return "btn btn-secondary btn-sm";
}
#endregion Private Methods
}
}