#nullable enable
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.Util;
namespace SHI.Modal.NW
{
///
/// 네트워크 다이어그램 노드의 드래그 모드를 정의합니다.
///
public enum NodeDragMode
{
/// 드래그 불가 (고정 위치)
None,
/// 수평(X축) 이동만 가능
HorizontalOnly,
/// 수직(Y축) 이동만 가능 (기본값)
VerticalOnly,
/// 자유롭게 이동 가능
Free
}
///
/// NW(네트워크 다이어그램) 차트를 표시하는 UI Toolkit 컴포넌트입니다.
///
/// 개요:
///
/// JSON 파일에서 작업 데이터를 로드하여 네트워크 다이어그램 형태로 시각화합니다.
/// 각 작업은 노드로 표시되며, ERE_NW_NXT_ACTV_CD 필드를 통해 노드 간 연결선이 그려집니다.
/// 노드를 드래그하여 위치를 조정할 수 있습니다.
///
///
/// 주요 기능:
///
/// - JSON 데이터 로드 및 파싱 (NWChartDataTask)
/// - 노드 자동 배치 (겹침 방지 알고리즘)
/// - 노드 간 연결선 렌더링 (충돌 우회 경로)
/// - 노드 드래그 이동 (수직/수평/자유 모드)
/// - 타임라인 헤더 (날짜 기반)
///
///
/// 네트워크 구조:
///
/// - ERE_NW_ACTV_CD - 현재 노드의 활동 코드
/// - ERE_NW_NXT_ACTV_CD - 다음 노드로의 연결 (화살표)
/// - STDT - 시작일 (노드의 X 위치 결정)
///
///
/// 사용 예시:
///
/// var chart = root.Q<NWChart>();
/// chart.DragMode = NodeDragMode.VerticalOnly;
/// chart.Load("path/to/nw_data.json");
/// chart.OnExpand += () => { /* 확장 처리 */ };
///
///
/// 관련 리소스:
///
/// - Resources/SHI/Modal/NW/NWChart.uxml - 메인 레이아웃
///
///
[UxmlElement]
public partial class NWChart : VisualElement, IDisposable
{
#region IDisposable
private bool _disposed = false;
#endregion
private const string UXML_PATH = "SHI/Modal/NW/NWChart";
public Action? OnExpand;
///
/// 노드 드래그 모드 설정
///
public NodeDragMode DragMode { get; set; } = NodeDragMode.VerticalOnly;
private Button? _expandBtn;
// Network diagram settings
private float pixelsPerDay = 18f;
private float nodeWidth = 60f;
private float nodeHeight = 30f;
private Color nodeColor = new Color(0.2f, 0.6f, 0.9f, 1f);
private Color nodeEndColor = new Color(0.9f, 0.8f, 0.2f, 1f);
private Color lineColor = new Color(0.3f, 0.3f, 0.3f, 1f);
private VisualElement? root;
private VisualElement? headerTimeline;
private VisualElement? monthsLayer;
private VisualElement? daysLayer;
private VisualElement? networkCanvas;
private VisualElement? nodesLayer;
private VisualElement? linesLayer;
private ScrollView? contentScroll;
private List? tasks;
private Dictionary tasksByActivityCode = new();
private Dictionary nodeElements = new();
private Dictionary nodePositions = new();
// 연결선 캐싱 (fromCode_toCode -> ConnectionElements)
private Dictionary connectionCache = new();
// 연결선 요소들을 묶어서 관리
private class ConnectionElements
{
public VisualElement[] Lines = Array.Empty();
public VisualElement? Arrow;
public string FromCode = "";
public string ToCode = "";
public int Ptch;
}
// 노드 외곽 우회를 위한 여백
private float routingPadding = 8f;
// 드래그 관련 변수
private VisualElement? draggingNode;
private string? draggingActivityCode;
private Vector2 dragStartMousePos;
private Vector2 dragStartNodePos;
private bool isDragging;
private DateTime projectStartDate;
public DateTime ProjectStartDate => projectStartDate;
private DateTime projectEndDate;
public DateTime ProjectEndDate => projectEndDate;
private int totalDays;
private float canvasHeight;
public NWChart()
{
var visualTree = Resources.Load(UXML_PATH);
if (visualTree != null)
{
visualTree.CloneTree(this);
}
else
{
Debug.LogError($"Failed to load UXML at path: {UXML_PATH}");
}
_expandBtn = this.Q