/**
 *   UI 데이타 관리 
 *   
 *   중국 상하이 팀에서 사용 하던 UI 공용 데이타 공간, 
 *   대부분 삭제 하고 한국에서 추가 할 필요가 있을때 추가 하길..
 *   
 **/
class UIData extends UICommonAPI;

// 해상도
var int currentScreenWidth;
var int currentScreenHeight;
//var bool isClassicServer;

var string roleTypeStr;
var string classDescription;

// 레벨업 체크를 위한 변수들
var userinfo prevUserInfo, currUserInfo;

// 한 파티창에 들어갈수 있는 최대 파티원의 수.
const               NEW_PARTY_MAXCOUNT = 7;
var int             MAXLV ;
const               MAXLV2DISPLAY = 199;


const               HUNTINGZONE_MAXCOUNT = 500;
const               RAID_MAXCOUNT = 2000;
const               RAID_MIN      = 0;

const               RAID_BLOODY_MAXCOUNT = 2500;
const               RAID_BLOODY_MIN      = 2000;

//역활 수 최대 개수
const ROLETYPEMAX = 9;
const ROLETYPEMAX_ADEN = 13;

/************************************************** 아레나 * ************************************************/
// 섬멸전 변신 ID
const TRANSFORMID_DRAGONSLAYER = 11;
const TRANSFORMID_DRAGON = 10;

// NEW 245
const CASTLE_NUM_TOTAL = 2;
const PEACE_ZONE_TYPE = 11;

// 소유하고 있는 아데나 수량
var Int64 adenaCount;

// pc방 포인트
var int PcCafePoint;
var bool bIsPcCafe;

// 혈맹 포인트
var int clanNameValue;
var int craftPoint;
var INT64 nVitalityPoint;
var INT64 nSP;
// getUCProperty 로 여러 값을 가져오기 위한 임시 값
var int tmpDataInt;
var string tmpDataString;
var bool tmpDataBoolean;
var string preState;
var int teleportFreeLevel;
var int clientStartSec;
var int serverStartTime;
var int serverTimeZone;
var int serverDaylight;
var int clientTimeZone;
var int daylightSeconds;
var private bool bTimer24Set;
var private L2UITimerObject timer24Object;

static function UIData Inst()
{
	return UIData(GetScript("UIData"));
}

event OnLoad()
{
	// 해상도 갱신
	updateCurrentResolution();
	MAXLV = GetMaxLevel();
	SetBuilderPC();
	timer24Object = class'L2UITimer'.static.Inst()._AddNewTimerObject((((1000 * 60) * 60) * 12) + Rand(1000 * 60), -1);
	timer24Object._DelegateOnTime = DelegateOnTime24;
}

private function DelegateOnTime24(int t)
{
	API_SendWindowsInfo();
	Debug(" ------- 시간 저장." @ string(t) @ string(timer24Object._curCount) @ string(timer24Object._time));	
}

event OnRegisterEvent()
{
	RegisterEvent(EV_ResolutionChanged);
	RegisterEvent(EV_NeedResetUIData);

	RegisterEvent(EV_PCCafePointInfo);	
	RegisterEvent(EV_ClanInfo);	
	RegisterEvent(EV_PreUpdateUserInfo);	

	RegisterEvent(EV_NotifyBeforeStateChanged);

	// NEW 245
	RegisterEvent(EV_CurrentServerTime);
	RegisterEvent(EV_PacketID(class'UIPacket'.const.S_EX_CRAFT_INFO));
	RegisterEvent(EV_RESTART);
	RegisterEvent(EV_TeleportFreeLevel);
	RegisterEvent(EV_UpdateUserInfo);
	RegisterEvent(EV_SetMaxCount);
	RegisterEvent(EV_GameStart);
}

/** onEvent */
event OnEvent(int Event_ID, string param)
{
	local UserInfo UserInfo;

	switch(Event_ID)
	{
		case EV_ResolutionChanged:
			updateCurrentResolution();
			break;
		case EV_NeedResetUIData:
			MAXLV = GetMaxLevel();
			clanNameValue = 0;
			PcCafePoint = 0;
			break;
		case EV_PCCafePointInfo:
			pcCafePointInfoHandler(param);
			break;
		case EV_ClanInfo:
			updateClanInfoHandler(param);
			break;
		case EV_PreUpdateUserInfo:
			swapPrevUserInfo();
			break;
		case EV_NotifyBeforeStateChanged:
			preState = param;
			break;
		case EV_CurrentServerTime:
			Debug("============>========================================================================");
			Debug("============> EV_CurrentserverTime" @ param);
			ParseInt(param, "ServerTime", serverStartTime);
			ParseInt(param, "ServerTimeZone", serverTimeZone);
			ParseInt(param, "ServerDaylight", serverDaylight);
			ParseInt(param, "ClientTimeZone", clientTimeZone);
			ParseInt(param, "DaylightSeconds", daylightSeconds);
			clientStartSec = int(GetAppSeconds());
			break;
		case EV_PacketID(class'UIPacket'.const.S_EX_CRAFT_INFO):
			ParsePacket_S_EX_CRAFT_INFO();
			break;
		case EV_TeleportFreeLevel:
			ParseInt(param, "TeleportFreeLevel", teleportFreeLevel);
			break;
		case EV_Restart:
			handleOnRestart();
			break;
		case EV_SetMaxCount:
			SaveBuilderPCDatas();
			break;
		case EV_UpdateUserInfo:
			if(GetPlayerInfo(UserInfo))
			{
				nVitalityPoint = UserInfo.nVitality;
				nSP = UserInfo.nSP;
			}
			break;
		case EV_GameStart:
			HandleOnGameStart();
			break;
	}
}

private function handleOnRestart()
{
	bIsPcCafe = false;
	StopTimer24();
}

private function HandleOnGameStart()
{
	PlayTimer24();
}

event OnCallUCFunction(string Id, string param)
{
	switch(Id)
	{
		case "setRoleType":
			tmpDataInt = GetClassRoleType(int(param));
			break;
		case "setRoleTypeStr":
			setRoleTypeStr(int(param));
			break;
		case "GetClassDescription":
			classDescription = GetClassDescription(int(param));
			break;
		case "setUCData":
			tmpDataString = param;
			break;
		case "getUCData":
			getData(param);
			break;
	}
}

function SaveBuilderPCDatas()
{
	if(IsBuilderPC())
	{
		SetINIInt("UIData", "serverStartTime", serverStartTime, "UIDEV.ini");
		SetINIInt("UIData", "serverTimeZone", serverTimeZone, "UIDEV.ini");
		SetINIInt("UIData", "clientTimeZone", clientTimeZone, "UIDEV.ini");
		SetINIInt("UIData", "daylightSeconds", daylightSeconds, "UIDEV.ini");
		SetINIInt("UIData", "clientStartSec", clientStartSec, "UIDEV.ini");
		GetINIInt("UIData", "serverStartTime", serverStartTime, "UIDEV.ini");
		ChatWnd(GetScript("ChatWnd"))._HandleSystemMessageBuilderOnGameStart();
	}
}

function SetBuilderPC()
{
	if(! IsBuilderPC())
	{
		return;
	}
	GetINIInt("UIData", "serverStartTime", serverStartTime, "UIDEV.ini");
	GetINIInt("UIData", "serverTimeZone", serverTimeZone, "UIDEV.ini");
	GetINIInt("UIData", "clientTimeZone", clientTimeZone, "UIDEV.ini");
	GetINIInt("UIData", "daylightSeconds", daylightSeconds, "UIDEV.ini");
	GetINIInt("UIData", "clientStartSec", clientStartSec, "UIDEV.ini");
	resetUIData();
}

// UI 에서 UIRebuild 등 이후 초기화용으로 사용 
// 추가 할 것 있으면 계속 추가 해야함.
function resetUIData()
{
	ExecuteEvent(EV_NeedResetUIData, "");
	ExecuteEvent(EV_ResolutionChanged, "");
	ExecuteEvent(EV_GameStart, "");

	// 인벤 리스트
	RequestItemList();

	// 클래식만.. 라이브는 스케일폼 api
	if(getIsClassicServer())
		class'UIDATA_CLAN'.static.RequestClanInfo();
}

//  script 에서 인식하는 수는 int 까지 이므로, 999999999999을 쓰는 경우 int 로 변환 된다.
function INT64 getMaxAdena()
{
	return int64("999999999999"); // 9999억 대
}

// NEW/EDIT 245
function L2UITime GetCurrentRealLocalTime()
{
	local L2UITime currentRealLocalTimeStruct;

	GetTimeStruct(GetCurrentRealLocalTimeSec(), currentRealLocalTimeStruct);
	return currentRealLocalTimeStruct;
}

function int GetCurrentRealLocalTimeSec()
{
	return (((serverStartTime + (GameConnectTimeSec())) - clientTimeZone) + serverTimeZone) - daylightSeconds;	
}

function int GameConnectTimeSec()
{
	return int(GetAppSeconds()- clientStartSec);
}

function string gameConnectTimeString()
{
	return MakeTimeStr(GameConnectTimeSec());
}

function string getCurrentRealLocalTimeString()
{
	local L2UITime timeStruct;

	GetTimeStruct(GetCurrentRealLocalTimeSec(), timeStruct);
	return getMakeTimeString(timeStruct);
}

function string getCurrentServerTimeString()
{
	local L2UITime timeStruct;
	local int serverTime;
	local int currentUnixTime;

	serverTime = int(serverStartTime + GetAppSeconds()- clientStartSec);
	currentUnixTime = serverTime - serverTimeZone;
	GetTimeStructGMT(currentUnixTime,timeStruct);
	return getMakeTimeString(timeStruct);
}

function string getMakeTimeString(L2UITime timeStruct)
{
	local string Str;

	Str = timeStruct.nYear $ "/" $ Int2Str(timeStruct.nMonth) $ "/" $ Int2Str(timeStruct.nDay) $ " " $ Int2Str(timeStruct.nHour) $ ":" $ Int2Str(timeStruct.nMin);
	return Str;
}

function string _GetMakeTimeStringDHM(L2UITime timeStruct)
{
	local string Str;

	if(timeStruct.nDay > 0)
		Str = MakeFullSystemMsg(GetSystemMessage(7393),string(timeStruct.nDay))$ " ";

	if(timeStruct.nHour > 0)
		Str = Str $ MakeFullSystemMsg(GetSystemMessage(2204),string(timeStruct.nHour))$ " ";

	if((timeStruct.nDay == 0)&&(timeStruct.nHour == 0)&&(timeStruct.nMin == 0))
		Str = Str $ MakeFullSystemMsg(GetSystemMessage(4360),"1");
	else
		Str = Str $ MakeFullSystemMsg(GetSystemMessage(7395),string(timeStruct.nMin));

	return Str;
}

function bool getIsPcCafe()
{
	return bIsPcCafe;
}

//어떤 형식이 되던 나중에 한번에 바꿀 수 있도록 
function bool getIsLiveServer()
{
	return GetServerType() == 1;
}

//어떤 형식이 되던 나중에 한번에 바꿀 수 있도록 
function bool getIsClassicServer()
{
	// isClassicServer 이 삭제 되어 GetServer 로 교체 
	return GetServerType() == 2;
}

//어떤 형식이 되던 나중에 한번에 바꿀 수 있도록 
function bool getIsArenaServer()
{
	return GetServerType() == 3;
}

// 변신인지 아닌지 파악하는 함수 
function bool isPawnChanged()
{
	if(prevUserInfo.nID != currUserInfo.nID)
	{
		return false;
	}
	return prevUserInfo.m_bPawnChanged != currUserInfo.m_bPawnChanged;
}

// 탈 것 
function bool isMount()
{
	if(prevUserInfo.nID != currUserInfo.nID)
	{
		return false;
	}
	if(currUserInfo.m_bPawnChanged)
	{
		return false;
	}
	return(prevUserInfo.nTransformID == 0 && currUserInfo.nTransformID > 0);
}

// 내리는 경우
function bool isDismoust()
{
	if(prevUserInfo.nID != currUserInfo.nID)
	{
		return false;
	}
	if(currUserInfo.m_bPawnChanged)
	{
		return false;
	}
	return (prevUserInfo.nTransformID > 0) && currUserInfo.nTransformID == 0;
}

// 레벨업인지 아닌지 파악하는 함수.
function bool isLevelUP()
{
	if(prevUserInfo.nID != currUserInfo.nID)
	{
		return false;
	}
	return prevUserInfo.nLevel < currUserInfo.nLevel;
}

function bool IsLevelDown()
{
	if(prevUserInfo.nID != currUserInfo.nID)
	{
		return false;
	}
	return prevUserInfo.nLevel > currUserInfo.nLevel;
}

function bool _IsParty(string Name)
{
	if(getIsClassicServer())
	{
		return isPartyClassic(Name);
	}
	return isPartyLive(Name);	
}

private function bool isPartyClassic(string Name)
{
	local int i;
	local PartyWndClassic partyWndClassicScript;

	partyWndClassicScript = PartyWndClassic(GetScript("partyWndClassic"));
	Debug("클래식 일 때 랜스 몇????" @ string(partyWndClassicScript.const.MAX_ArrayNum));

	for(i = 0; i < partyWndClassicScript.const.MAX_ArrayNum; i++)
	{
		if(partyWndClassicScript.m_PlayerName[i].GetName() == Name)
		{
			return true;
		}
	}
	return false;	
}

private function bool isPartyLive(string Name)
{
	local int i;
	local PartyWnd partywndscript;

	partywndscript = PartyWnd(GetScript("partywnd"));
	Debug("라이브 일 때 랜스 몇????" @ string(partywndscript.const.MAX_ArrayNum));

	for(i = 0; i < partywndscript.const.MAX_ArrayNum; i++)
	{
		if(partywndscript.m_PlayerName[i].GetName() == Name)
		{
			return true;
		}
	}
	return false;	
}

// 친구 인지 
function bool isFriend(string Name)
{
	local PersonalConnectionsWnd personalConnectionsWndScript;
	local L2Util l2utilScript;

	personalConnectionsWndScript = PersonalConnectionsWnd(GetScript("PersonalConnectionsWnd"));
	l2utilScript = L2Util(GetScript("L2Util"));
	return l2utilScript.ctrlListSearchByName(personalConnectionsWndScript.FriendList, Name) != -1;
}

function bool _IsBlocked(string Name)
{
	local PersonalConnectionsWnd personalConnectionsWndScript;
	local L2Util l2utilScript;

	personalConnectionsWndScript = PersonalConnectionsWnd(GetScript("PersonalConnectionsWnd"));
	l2utilScript = L2Util(GetScript("L2Util"));
	return l2utilScript.ctrlListSearchByName(personalConnectionsWndScript.BlockList, Name) != -1;	
}

function int getMyNobless()
{
	local UserInfo Info;

	if(! GetPlayerInfo(Info))
	{
		return -1;
	}
	return Info.nNobless;
}

function bool getbHero()
{
	local UserInfo Info;

	if(! GetPlayerInfo(Info))
	{
		return false;
	}
	return Info.bHero;
}

function string getCurrentLocalTimeString()
{
	local L2UITime timeStruct;

	GetTimeStruct(int(serverStartTime + GetAppSeconds()- clientStartSec),timeStruct);
	return getMakeTimeString(timeStruct);
}

function bool IsTeleportFreeLevel()
{
	local UserInfo uInfo;

	if(! GetPlayerInfo(uInfo))
	{
		return false;
	}

	return uInfo.nLevel <= teleportFreeLevel;
}

function INT64 GetTeleportPriceByID(int Id)
{
	local TeleportListAPI.TeleportListData listData;

	if(IsTeleportFreeLevel())
		return 0;

	listData = Class'TeleportListAPI'.static.GetFirstTeleportListData();

	while("" != listData.Name)
	{
		if(listData.Id == Id)
		{
			return listData.Price[0].Amount;
		}

		listData = Class'TeleportListAPI'.static.GetNextTeleportListData();
	}
	return -1;
}

function string GetTeleportPlaceNameByID(int Id)
{
	local TeleportListAPI.TeleportListData listData;

	listData = class'TeleportListAPI'.static.GetFirstTeleportListData();

	while("" != listData.Name)
	{
		if(listData.Id == Id)
		{
			return listData.Name;
		}
		listData = class'TeleportListAPI'.static.GetNextTeleportListData();
	}
	return "";
}

function int GetTeleportIDByXYZ(int X, int Y, int Z, optional bool bOnlyTown)
{
	local TeleportListAPI.TeleportListData listData;
	local Vector Loc;
	local string locZoneName;

	Loc.X = float(X);
	Loc.Y = float(Y);
	Loc.Z = float(Z);
	locZoneName = GetZoneNameWithLocation(Loc);
	listData = class'TeleportListAPI'.static.GetFirstTeleportListData();

	while("" != listData.Name)
	{
		if(bOnlyTown)
		{
			if(listData.Priority == 1 || listData.Priority == 2)
			{
				if(listData.Name == locZoneName)
				{
					return listData.Id;
				}
			}			
		}
		else if(listData.Name == locZoneName)
		{
			return listData.Id;
		}
		listData = class'TeleportListAPI'.static.GetNextTeleportListData();
	}
	return -1;
}

function TeleportListAPI.TeleportListData GetTeleportListDataByID(int Id)
{
	local TeleportListAPI.TeleportListData listData, emptyData;

	listData = class'TeleportListAPI'.static.GetFirstTeleportListData();

	while("" != listData.Name)
	{
		if(listData.Id == Id)
		{
			return listData;
		}
		listData = class'TeleportListAPI'.static.GetNextTeleportListData();
	}
	return emptyData;
}

function ParsePacket_S_EX_CRAFT_INFO()
{
	local UIPacket._S_EX_CRAFT_INFO packet;

	if( !Class'UIPacket'.static.Decode_S_EX_CRAFT_INFO(packet))
	{
		return;
	}

	setCurrentCraftPoint(packet.nPoint);
	RandomCraftChargingWnd(GetScript("RandomCraftChargingWnd")).ParsePacket_S_EX_CRAFT_INFO(packet);
	RandomCraftWnd(GetScript("RandomCraftWnd")).ParsePacket_S_EX_CRAFT_INFO(packet);
	BottomBar(GetScript("BottomBar")).Nt_S_EX_CRAFT_INFO(packet);
}

// 이전 유저 정보와 지금 유저 정보를 교체 하는 함수
function swapPrevUserInfo()
{
	prevUserInfo = currUserInfo;
	GetPlayerInfo(currUserInfo);
}

function updateClanInfoHandler(string param)
{
	ParseInt(param, "ClanNameValue", clanNameValue);   // 혈맹포인트
}

function pcCafePointInfoHandler(string param)
{
	local int nShow;

	ParseInt(param, "TotalPoint", PcCafePoint);
	ParseInt(param, "Show", nShow);
	bIsPcCafe = true;
}

function setCurrentClanNameValue(int point)
{
	clanNameValue = point;
}

function int getCurrentClanNameValue()
{
	return clanNameValue;
}

function INT64 getCurrentVitalityPoint()
{
	return nVitalityPoint;	
}

function INT64 getCurrentSP()
{
	return nSP;	
}

function setCurrentVitalityPoint(int point)
{
	nVitalityPoint = point;	
}

function setPcCafePoint(int point)
{
	PcCafePoint = point;
}

function int getCurrentPcCafePoint()
{
	return PcCafePoint;
}

function setCurrentCraftPoint(int point)
{
	craftPoint = point;
}

function int getCurrentCraftPoint()
{
	return craftPoint;
}

/** 해상도 */
function updateCurrentResolution()
{
	GetCurrentResolution(currentScreenWidth, currentScreenHeight);
}

function int getScreenWidth()
{
	// 값이 제대로 안넣어진 상태인걸로 간주 하고 업데이트 
	if(currentScreenWidth <= 0)
	{
		updateCurrentResolution();
	}

	return currentScreenWidth;
}

function int getScreenHeight()
{
	// 값이 제대로 안넣어진 상태인걸로 간주 하고 업데이트 
	if(currentScreenWidth <= 0)
	{
		updateCurrentResolution();
	}

	return currentScreenHeight;
}

function setRoleTypeStr(int ClassID)
{
	roleTypeStr = GetClassRoleName(ClassID);
}

function getData(string DataName)
{
	switch(DataName)
	{
		case "GameStateName":
			tmpDataString = GetGameStateName();
			break;
		case "nNobless":
			tmpDataInt = getMyNobless();
			break;
		case "bHero":
			tmpDataBoolean = getbHero();
			break;
		case "roleIconName":
			tmpDataString = GetClassRoleIconName(int(tmpDataString));
			break;
		case "roleBigIconName":
			tmpDataString = GetClassRoleIconNameBig(int(tmpDataString));
			break;
		case "arenaRoleIconName":
			tmpDataString = GetClassArenaRoleIconName(int(tmpDataString));
			break;
		case "ClassRoleNameByRole":
			tmpDataString = GetClassRoleNameByRole(EClassRoleType(int(tmpDataString)));
			break;
		case "GetUserName":
			tmpDataString = class'UIDATA_USER'.static.GetUserName(int(tmpDataString));
			break;
		case "GetPartyMemberLocationWithID":
			setGetPartyMemberLocationWithID(int(tmpDataString));
			break;
		case "GetItemNameAllBySeverID":
			tmpDataString = GetItemNameAllBySeverID(int(tmpDataString));
			break;
		case "GetItemGradeTextureName":
			tmpDataString = GetItemGradeTextureName(int(tmpDataString));
			break;
		case "GetIsFriend":
			tmpDataBoolean = IsFriend(tmpDataString);
			break;
		case "GetUIUserPremiumLevel":
			tmpDataInt = GetUIUserPremiumLevel();
			break;
		case "GetServerTimeString":
			tmpDataString = getCurrentServerTimeString();
			break;
		case "GetLocalTimeString":
			tmpDataString = getCurrentLocalTimeString();
			break;
		case "IsStackableItemByClassID":
			tmpDataBoolean = IsStackableItemByClassID(int(tmpDataString));
			break;
		case "GetAdditionalName":
			tmpDataString = GetAdditionalName(int(tmpDataString));
			break;
	}
}

function bool IsStackableItemByClassID(int ClassID)
{
	local ItemInfo Info;

	Info = GetItemInfoByClassID(ClassID);
	if(IsStackableItem(Info.ConsumeType))
	{
		return true;
	}
	return false;
}

function string GetAdditionalName(int ClassID)
{
	local ItemInfo Info;

	Info = GetItemInfoByClassID(ClassID);
	return Info.AdditionalName;
}

// 바로 파티를 맺자 마자 정보 값을 받을 수 없다. 
function setGetPartyMemberLocationWithID(int a_PartyMemberSID)
{
	local Vector a_Location;

	if(GetPartyMemberLocationWithID(int(tmpDataString), a_Location))
	{
		tmpDataString = "";
		ParamAdd(tmpDataString, "x", string(a_Location.X));
		ParamAdd(tmpDataString, "y", string(a_Location.Y));
		ParamAdd(tmpDataString, "z", string(a_Location.Z));
	}
}

function string Int2Str(int Num)
{
	if(Num < 10)
	{
		return "0" $ string(Num);
	}
	return string(Num);
}

function bool IsPeaceZoneType(int zonetype)
{
	return zonetype == 11;
}

private function StopTimer24()
{
	bTimer24Set = false;
	timer24Object._Stop();	
}

private function PlayTimer24()
{
	if(bTimer24Set)
	{
		return;
	}
	bTimer24Set = true;
	timer24Object._Reset();	
}

private function API_SendWindowsInfo()
{
	SendWindowsInfo();	
}
