import*as SDK from'../sdk/sdk.js';export class InputModel extends SDK.SDKModel.SDKModel{constructor(target){super(target);this._inputAgent=target.inputAgent();this._eventDispatchTimer=null;this._dispatchEventDataList=[];this._finishCallback=null;this._reset();}
_reset(){this._lastEventTime=null;this._replayPaused=false;this._dispatchingIndex=0;clearTimeout(this._eventDispatchTimer);}
setEvents(tracingModel){this._dispatchEventDataList=[];for(const process of tracingModel.sortedProcesses()){for(const thread of process.sortedThreads()){this._processThreadEvents(tracingModel,thread);}}
function compareTimestamp(a,b){return a.timestamp-b.timestamp;}
this._dispatchEventDataList.sort(compareTimestamp);}
startReplay(finishCallback){this._reset();this._finishCallback=finishCallback;if(this._dispatchEventDataList.length){this._dispatchNextEvent();}else{this._replayStopped();}}
pause(){clearTimeout(this._eventDispatchTimer);if(this._dispatchingIndex>=this._dispatchEventDataList.length){this._replayStopped();}else{this._replayPaused=true;}}
resume(){this._replayPaused=false;if(this._dispatchingIndex<this._dispatchEventDataList.length){this._dispatchNextEvent();}}
_processThreadEvents(tracingModel,thread){for(const event of thread.events()){if(event.name==='EventDispatch'&&this._isValidInputEvent(event.args.data)){this._dispatchEventDataList.push(event.args.data);}}}
_isValidInputEvent(eventData){return this._isMouseEvent((eventData))||this._isKeyboardEvent((eventData));}
_isMouseEvent(eventData){if(!InputModel.MouseEventTypes.has(eventData.type)){return false;}
if(!('x'in eventData&&'y'in eventData)){return false;}
return true;}
_isKeyboardEvent(eventData){if(!InputModel.KeyboardEventTypes.has(eventData.type)){return false;}
if(!('code'in eventData&&'key'in eventData)){return false;}
return true;}
_dispatchNextEvent(){const eventData=this._dispatchEventDataList[this._dispatchingIndex];this._lastEventTime=eventData.timestamp;if(InputModel.MouseEventTypes.has(eventData.type)){this._dispatchMouseEvent((eventData));}else if(InputModel.KeyboardEventTypes.has(eventData.type)){this._dispatchKeyEvent((eventData));}
++this._dispatchingIndex;if(this._dispatchingIndex<this._dispatchEventDataList.length){const waitTime=(this._dispatchEventDataList[this._dispatchingIndex].timestamp-this._lastEventTime)/1000;this._eventDispatchTimer=setTimeout(this._dispatchNextEvent.bind(this),waitTime);}else{this._replayStopped();}}
async _dispatchMouseEvent(eventData){console.assert(InputModel.MouseEventTypes.has(eventData.type));const buttons={0:'left',1:'middle',2:'right',3:'back',4:'forward'};const params={type:InputModel.MouseEventTypes.get(eventData.type),x:eventData.x,y:eventData.y,modifiers:eventData.modifiers,button:(eventData.type==='mousedown'||eventData.type==='mouseup')?buttons[eventData.button]:'none',buttons:eventData.buttons,clickCount:eventData.clickCount,deltaX:eventData.deltaX,deltaY:eventData.deltaY};await this._inputAgent.invoke_dispatchMouseEvent(params);}
async _dispatchKeyEvent(eventData){console.assert(InputModel.KeyboardEventTypes.has(eventData.type));const text=eventData.type==='keypress'?eventData.key[0]:undefined;const params={type:InputModel.KeyboardEventTypes.get(eventData.type),modifiers:eventData.modifiers,text:text,unmodifiedText:text?text.toLowerCase():undefined,code:eventData.code,key:eventData.key};await this._inputAgent.invoke_dispatchKeyEvent(params);}
_replayStopped(){clearTimeout(this._eventDispatchTimer);this._reset();this._finishCallback();}}
InputModel.MouseEventTypes=new Map([['mousedown','mousePressed'],['mouseup','mouseReleased'],['mousemove','mouseMoved'],['wheel','mouseWheel']]);InputModel.KeyboardEventTypes=new Map([['keydown','keyDown'],['keyup','keyUp'],['keypress','char']]);SDK.SDKModel.SDKModel.register(InputModel,SDK.SDKModel.Capability.Input,false);