// Include Many js files-----------------------------------------

let theWebSocket = null	

function include(file) { 
  
  var script  = document.createElement('script'); 
  script.src  = file; 
  script.type = 'text/javascript'; 
  script.defer = true; 
  
  document.getElementsByTagName('head').item(0).appendChild(script);
  
} 
  



//(some web loading timing problem,sometimes not defined function happen,so at the sametime with web.html)
include('shakedata.h'); 
include('sock.h'); 
include('chat_control.h'); 




function onLoadWebPage()//(only once called)
{
	//G1_OnLoad_ALL_AddEventPage();
	//G3_StartGame();

}


function writeIntToScreen(para)
{
	//document.getElementById("display1").innerText=para.toString();
}
const AudioContextClass = window.AudioContext || window.webkitAudioContext;
const chatAudioCtx = AudioContextClass ? new AudioContextClass() : null;

function playChatNotificationSound() {
    //only sound when not foreground
    if (document.hasFocus()) {
        return; 
    }

    
    if (chatAudioCtx) {
        try {
            if (chatAudioCtx.state === 'suspended') {
                chatAudioCtx.resume();
            }
            const oscillator = chatAudioCtx.createOscillator();
            const gainNode = chatAudioCtx.createGain();
            
            oscillator.connect(gainNode);
            gainNode.connect(chatAudioCtx.destination);
            
            oscillator.type = 'sine'; 
            const now = chatAudioCtx.currentTime;
            
            oscillator.frequency.setValueAtTime(587.33, now); 
            oscillator.frequency.setValueAtTime(880.00, now + 0.08); 
            
            gainNode.gain.setValueAtTime(0.3, now); 
            gainNode.gain.exponentialRampToValueAtTime(0.001, now + 0.4); 
            
            oscillator.start(now);
            oscillator.stop(now + 0.4);
        } catch (e) {
            console.log("Web Audio API play fail:", e);
        }
    }
}






function openPopupCenter(url, title, w, h) {

    const availWidth = window.screen.availWidth;
    const availHeight = window.screen.availHeight;

    const chromeBorderWidth = 15;
    const chromeCaptionHeight = 28;

    const finalWindowWidth = w + chromeBorderWidth;
    const finalWindowHeight = h + chromeCaptionHeight;

    const left = (availWidth - finalWindowWidth) / 2;
    const top = (availHeight - finalWindowHeight) / 2 -30;

    const finalLeft = left > 0 ? Math.floor(left) : 0;
    const finalTop = top > 0 ? Math.floor(top) : 0;

    const newWindow = window.open(url, title, 
        `width=${w}, height=${h}, top=${finalTop}, left=${finalLeft}, scrollbars=yes, resizable=yes, status=no, location=no`
    );

    if (window.focus && newWindow) {
        newWindow.focus();
    }
    
    return newWindow;
}


var chatCallBlinkTimer = null;
var chatCallBlinkStart = 0;

function setChatCallBlink(flag)
{
    var btn = document.querySelector(".chat-call-btn");
    if (!btn) return;

    var svg = btn.getElementsByTagName("svg")[0];
    if (!svg) return;

    if (flag == 0)
    {
        if (chatCallBlinkTimer !== null)
        {
            cancelAnimationFrame(chatCallBlinkTimer);
            chatCallBlinkTimer = null;
        }

        svg.style.fill = "green";
        svg.style.transform = "scale(1)";
        svg.style.filter = "none";
        btn.style.boxShadow = "none";

        return;
    }

    if (chatCallBlinkTimer !== null) return;

    chatCallBlinkStart = performance.now();

    function animateCall(now)
    {
        var elapsed = now - chatCallBlinkStart;
        var t = (elapsed % 1200) / 1200;
        var pulse = (1 - Math.cos(t * Math.PI * 2)) / 2;

        var scale = 1 + pulse * 0.15;
        svg.style.transform = "scale(" + scale + ")";

        var r = Math.round(pulse * 255);
        var g = Math.round(128 - pulse * 128);
        svg.style.fill = "rgb(" + r + "," + g + ",0)";

        var glow = Math.round(pulse * 8);

        btn.style.boxShadow =
            glow > 0 ?
            "0 0 " + glow + "px rgba(255,60,60,0.6)" :
            "none";

        chatCallBlinkTimer =
            requestAnimationFrame(animateCall);
    }

    chatCallBlinkTimer =
        requestAnimationFrame(animateCall);
}

/*
function PlaySoundLoop(id, flag)
{
    var sound = document.getElementById(id);
    if (!sound) return;

    if (flag == 1)
    {
        sound.currentTime = 0;
        sound.loop = true;
        sound.play();
    }
    else
    {
        sound.pause();
        sound.currentTime = 0;
    }
}
function PlaySound(id)
{
    var sound = document.getElementById(id);
    if (!sound) return;

    sound.loop = false;
    sound.currentTime = 0;
	try{
		sound.play();
	}
	catch(e){
	}
}
*/

//사운드관련 함수들 오디오 컨텍스트 사용--------------------------------------
var audioCtx = null;
var audioBuffers = {};       // 일괄 로드된 음원 데이터(AudioBuffer) 저장소
var activeAudioNodes = {};   // 현재 재생 중인 루프 노드 제어용 (id 매핑)

// 제공해주신 사운드 태그 리스트를 매니페스트로 등록
var SOUND_MANIFEST = {
    "call_recv": "call_recv.mp3",
    "call_send": "call_send.mp3",
    "call_busy": "call_busy.opus"
};


//(페이지가 로드될 때 이 함수를 단 한 번 꼭 호출해 주세요!)
function PreloadAllSounds() {
    if (!audioCtx) {
        audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    }

    var loadPromises = Object.keys(SOUND_MANIFEST).map(function(key) {
        var url = SOUND_MANIFEST[key];
        
        return fetch(url)
            .then(function(response) {
                if (!response.ok) throw new Error("네트워크 응답 에러");
                return response.arrayBuffer();
            })
            .then(function(arrayBuffer) {
                return audioCtx.decodeAudioData(arrayBuffer);
            })
            .then(function(decodedBuffer) {
                audioBuffers[key] = decodedBuffer; // 메모리에 버퍼 캐싱
                console.log("사운드 로드 성공: " + key);
            })
            .catch(function(error) {
                console.error("사운드 로드 실패 (" + key + "):", error);
            });
    });

    Promise.all(loadPromises).then(function() {
        console.log("?? 모든 통화 관련 사운드가 메모리에 일괄 로드되었습니다.");
    });
}

function UnlockAudioContext() {
    if (!audioCtx) {
        audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    }
    if (audioCtx.state === 'suspended') {
        audioCtx.resume().then(function() {
            RemoveUnlockListeners();
        });
    } else {
        RemoveUnlockListeners();
    }
}

function RemoveUnlockListeners() {
    document.removeEventListener('click', UnlockAudioContext);
    document.removeEventListener('touchstart', UnlockAudioContext);
}

// 최초 1회 사용자 조작 시 시스템 언락 등록
document.addEventListener('click', UnlockAudioContext);
document.addEventListener('touchstart', UnlockAudioContext);


// ==========================================
// [재생 함수] 기존 인터페이스 및 인자 완벽 유지
// ==========================================

function PlaySoundLoop(id, flag) {
    if (flag == 1) {
        // 이미 재생 중인 동일 사운드가 있다면 중복 겹침 방지를 위해 정지
        if (activeAudioNodes[id]) {
            try { activeAudioNodes[id].stop(); } catch(e) {}
        }

        var buffer = audioBuffers[id];
        if (!buffer) {
            console.warn("사운드 버퍼가 아직 준비되지 않았습니다: " + id);
            return;
        }

        var source = audioCtx.createBufferSource();
        source.buffer = buffer;
        source.loop = true; // 반복 재생 활성화
        
        source.connect(audioCtx.destination);
        source.start(0);
        
        // 정지 제어를 위해 전역 변수에 소스 노드 보관
        activeAudioNodes[id] = source;
    } else {
        // flag가 1이 아니면 해당 루프 사운드 정지
        if (activeAudioNodes[id]) {
            try {
                activeAudioNodes[id].stop();
            } catch(e) {}
            delete activeAudioNodes[id];
        }
    }
}


function PlaySound(id) {
    var buffer = audioBuffers[id];
    if (!buffer) {
        console.warn("사운드 버퍼가 아직 준비되지 않았습니다: " + id);
        return;
    }

    // 단발성 효과음은 즉시 독립 노드로 생성하여 재생 (레이턴시 0ms)
    var source = audioCtx.createBufferSource();
    source.buffer = buffer;
    source.loop = false;
    
    source.connect(audioCtx.destination);
    try {
        source.start(0);
    } catch(e) {
        console.error("PlaySound 재생 오류:", e);
    }
}

//사운드관련 함수들 오디오 컨텍스트 사용--------------------------------------


function CCHAT_CALL_REQ_F(msg,flag)
{
	let pr = new CCHAT_CALL_REQ();pr.Recv(msg);
	console.log(pr.mSendID,pr.mRecvID,pr.mFlag,pr.mResult);

	let issender=0;
	if(pr.mSendID==G1the.mChatLogin.mUserID) issender=1;

	let step_flag=0;
	if(G1the.mCallStart==0)
	{
		if	   (pr.mFlag==0 && (pr.mSendID==G1the.mChatLogin.mUserID || pr.mRecvID==G1the.mChatLogin.mUserID) ){
			
			if(pr.mResult==1){
				G1the.Call_Start(pr,1,0);//when call engaged setting
				
				if(issender==1){
					SetCaller(1);
					PlaySoundLoop("call_send",1);
					step_flag=1;
					
				}
				else{
					SetCaller(0);
					setChatCallBlink(1);
					PlaySoundLoop("call_recv",1);
					step_flag=2;

					if(flag==1){
						if (thePopupH && !thePopupH.closed) thePopupH.setOtherSideID(pr.mSendID);
					}
				}

			}
			else
				step_flag=1;

			if (thePopupH && !thePopupH.closed){
					thePopupH.Run(pr,step_flag,issender);
			}

			return 1;
		}
		else if(pr.mFlag<10){//end of if	   (pr.mFlag==0)
			pr.mFlag=10;let send_msg=pr.Send();doSend(send_msg);
		}
		else{ // in case of pr.mFlag>10,then abort
			//just passing because before call-start
		}
	}
	else{
		//alert(G1the.mCallReq.mSendID +"," +pr.mSendID +"," +G1the.mCallReq.mRecvID +","+pr.mRecvID);

		if( (G1the.mCallReq.mSendID==pr.mSendID && G1the.mCallReq.mRecvID==pr.mRecvID) )
		{
		
			if	   (G1the.mCallPrevFlag==0 && pr.mFlag==1)
			{
				G1the.Call_Start(G1the.mCallReq,1,1);//when call engaged setting
				
				if(pr.mResult==1){//call accept------
					setChatCallBlink(0);
					step_flag=4;
				}
				else{// call decline------
					
					G1the.Call_Initialize();
					step_flag=3;
				}
			}
			/*
			else if(G1the.mCallReq.mFlag==1 && pr.mFlag==2)//talk start from agora
			{
				step_flag=5;
				G1the.mCallReq.mFlag=2;
			}
			else if(pr.mFlag==3)//talk end from agora
			{
				step_flag=6;
				G1the.mCallReq.mFlag=3;
			}
			else if(pr.mFlag==4)//talke end from user button-click(talk-end button)
			{
				step_flag=7;
				G1the.mCallReq.mFlag=4;
			}
			*/
			else if(pr.mFlag<10)//send abort to server
			{
				pr.mFlag=12;let send_msg=pr.Send();doSend(send_msg);
				return 0;
			}
			else{//received abort from server
				step_flag=10;
				G1the.Call_Initialize();
				//abort routine need
			}

			if (thePopupH && !thePopupH.closed){
				thePopupH.Run(pr,step_flag,issender);
			}
			
			return 1;
		}
		else{
			if(pr.mFlag<10){
				if(pr.mFlag==0  && pr.mRecvID==G1the.mChatLogin.mUserID) pr.mFlag=11;//busy(just-other call try while call-process)
				else			pr.mFlag=13;

				let send_msg=pr.Send();doSend(send_msg);
			}
			else{//received abort from the just-other
				//just passing because not-related
			}
		}
	}//end of if(G1the.mCallReady==1)
}
