// Fill out your copyright notice in the Description page of Project Settings.

#include "Components/EditableTextBox.h"
#include "MyGameInstance.h"

UMyGameInstance::UMyGameInstance()
{

}

void UMyGameInstance::Init()
{
    Super::Init();

    static const TCHAR LogCharArray[] = TEXT("Hellow Unreal"); // TCHAR 문자 자료형의 연속공간을 선언. 문자열로 사용할 수 있다. 
    // static const 는 5.2 버전부터 UE_LOG 매크로 인수가 달라져서 임시로 붙임.
    UE_LOG(LogTemp, Log, LogCharArray);

    FString LogCharString = LogCharArray;
    UE_LOG(LogTemp, Log, TEXT("%s"), *LogCharString); // TCHAR 문자열을 가지고있는 문자열 클래스임 클래스 내부에서 제공되는 유용한 기능들이 탑재 되어있다. 

    // TEXT("HELLO") -> TCHAR[5]{'H','E','L','L','O'} <*=> FString <=> FCString

    // FString 문자열을 TCHAR* 문자열로 받고자할 때
    const TCHAR* LongCharPtr = *LogCharString; // * Operator를 보면 const TCHAR* 로만 받을 수 있기때문에 const TCHAR*로 받는다. 변경 불가능
    TCHAR* LogCharDataPtr = LogCharString.GetCharArray().GetData(); // TArray<*CHAR> 로 변환 뒤 포인터 배열의 시작주소를 넘겨준다.
    
    // TCHAR Array로 받아야한다면
    //TArray<TCHAR> bb(LogCharString.GetCharArray(),LogCharString.GetCharArray().GetSlack());
    
    TCHAR LogCharArrayWithSize[100];
    FCString::Strcpy(LogCharArrayWithSize, LogCharString.Len(), *LogCharString); // 저수준 복사

    // LogCharString 문자열에서 "unreal" 문자열이 포함되는지 확인할 수 있음
    if(LogCharString.Contains(TEXT("unreal"), ESearchCase::IgnoreCase)) // ESearchCase::IgnoreCase = 대소문자 구별 X, ESearchCase::CaseSensitive = 구별 O
    {
         //문자열 인덱스 찾기
         int32 Index = LogCharString.Find(TEXT("unreal"), ESearchCase::IgnoreCase);
         // 자르기
         FString EndString = LogCharString.Mid(Index);
         UE_LOG(LogTemp, Log, TEXT("Find Test %s"), *EndString);
    }

    FString Left, Right;
    if(LogCharString.Split(TEXT(" "), &Left, &Right)) // Hellow Unreal => Left = Hellow, Right = Unreal
    {
        UE_LOG(LogTemp, Log, TEXT("Split Test : %s 와 %s"), *Left, *Right); 
        // Window 환경에서 코드작성시 파일인코딩이 CP949형식의 멀티바이트로 되어있음 이걸 유니코드로 바꿔줘야한다. 
        // 파일 저장시 인코딩 형식을 변경할 때 UTF-8 형태로 저장하면 된다. BOM 은 3바이트 정보가 들어있는 인코딩 형태 Linux는 BOM 지원 X
    }

    int32 IntValue = 32;
    float FloatValue = 3.141592;

    FString FloatString = FString::SanitizeFloat(FloatValue); // float -> FString
    FString IntString = FString::FromInt(IntValue); // int -> FString
    FString FloatIntString = FString::Printf(TEXT("%f%d"),FloatValue, IntValue); // Float + Int -> FString

    UE_LOG(LogTemp, Log, TEXT("FloatString : %s"), *FloatString); 
    UE_LOG(LogTemp, Log, TEXT("IntString : %s"), *IntString); 
    UE_LOG(LogTemp, Log, TEXT("FloatIntString : %s"), *FloatIntString);

    int32 IntValueFromString = FCString::Atoi(*IntString); // ASCII to int          // 안전성 주의
    float FloatValueFromString = FCString::Atof(*FloatString); // ASCII to float    // 안전성 주의

    //FString은 언리얼에서 사용되는 다양한 문자열에 변환 주체가 됨 FString -> FName, FString -> FText

    //FName Class
    //FName은 애셋 관리를 위해 사용되는 문자열 체계임, 대소문자 구분 X, 선언 후 수정 X, 가볍고 빠르다
    //Global FName Pool 자료구조를 가지고있다.
    //FName 문자열을 Instance로 만들면 Global Pool에서 값을 저장한다. 이때 Global Pool 에서 해시 값을 추출하여 Key값으로 사용 결과적으로 Key(해쉬) : Value(FName) 이 된다.
    //가볍고 빠른 이유는 이러한 구조를 가지고있기 때문이다.

    
    for(int i = 0; i < 10000; ++i)
    {
        FName SearchInNamePool = FName(TEXT("pelvis")); 
        // 주의할점은 앞서 FName Global Pool에서 관리 되고있다고 했는데, FName 생성자에 지속적으로 같은 문자열을 넣고 반복작업을 할 때
        // Global Pool에서 문자열을 검사하는 작업을 반복 수행 하기 때문에 많은 오버헤드가 발생 할 수 있다.
        // 따라서 이렇게 계속 생성하는 것 보다 한번만 생성 후 참조해서 쓰는게 좋을것 같다.
    }
}
