var bricks = window.bricks || {};
/*
dependent on xterm.js
*/
bricks.Wterm = class extends bricks.JsWidget {
	/*
	{
		ws_url:
		ping_timeout:19
	}
	*/
	constructor(opts){
		super(opts);
		this.socket = null;
		this.ping_timeout = opts.ping_timeout || 19;
		schedule_once(this.open.bind(this), 1);
		this.bind('domon', this.send_term_size.bind(this));
		this.bind('domoff', this.destroy.bind(this));
	}
	close_websocket(){
		try {
			console.log('socket alive, destroy it');
			// this.socket.send(JSON.stringify({ type: "close"}));
			this.socket.close(1000,'close now');
			this.socket.onopen = null;
			this.socket.onmessage = null;
			this.socket.onerror = null;
			this.socket.onclose = null;
			this.socket = null;
		} catch(e) {
			this.socket = null;
			console.log('e=', e);
		}
	}
	close_terminal(){
		try {
			this.fitAddon.dispose();
			this.term.dispose();
			this.term = null;
		} catch(e){
			this.term = null;
			console.log('e=', e);
		}
	}
	destroy(){
		console.debug('------domoff event, destory this widget');
		try {
			this.unbind('element_resize', this.term_resize.bind(this))
		} catch(e) {
			console.log('error ', e);
		}
		console.debug('---1--domoff event, destory this widget');
		if (this.socket){
			this.close_websocket();
		}
		console.debug('---2--domoff event, destory this widget');
		if (this.term){
			this.close_terminal();
		}
		console.debug('---3--domoff event, destory this widget');
	}
	charsize_sizing(){
		var cs = bricks.app.charsize;
		this.term.setOption('fontSize', cs);
	}
	send_term_size(){
		console.debug('------domon event, send the terminal size to server');
		try {
			console.log('resize():rows=', this.term.rows, this.term.cols);
			this.socket.send(JSON.stringify({ type: "resize", 
						width:this.get_width(),
						height: this.get_height(),
						rows: this.term.rows, 
						cols: this.term.cols }));
		} catch (e) {
			console.log('ws not ready');
		}
	}
	send_data(d){
		this.socket.send(JSON.stringify({type: "input", "data":d}));
	}
	async open(){
		var term_options = bricks.extend({width: "100%", height: "100%"}, this.term_options);
		var term = new Terminal(term_options);
		this.term = term;
		term.open(this.dom_element);
		// var sessdata = bricks.app.get_session();
		// var ws = new WebSocket(this.opts.ws_url, sessdata);
		var ws = new WebSocket(this.opts.ws_url);
		this.socket = ws;

		this.fitAddon = new FitAddon.FitAddon()
		term.loadAddon(this.fitAddon)
		this.fitAddon.fit();
		this.charsize_sizing();
		ws.onmessage = event => {
			var msg = JSON.parse(event.data);
			console.log('ws msg=', msg);
			if (msg.data.type  == 'heartbeat'){
				console.log('connection alive');
			} else if (msg.data.type == 'data') {
				term.write(msg.data.data);
			} else {
				console.log('get server data = ', msg.data);
			}
		};
		ws.onclose = (event) => {
			console.log('websocket closed:', event.code, '--', event.reason);
		};
		ws.onopen = () => {
			this.send_term_size();
			this.bind('element_resize', this.term_resize.bind(this))
		};
		term.onData((key) => {
			console.log('key=', key);
			this.send_data(key);
		});
		term.onResize(({cols, rows}) =>{
			this.send_term_size();
		});
		this.send_term_size();
		term.focus();
	}
	term_resize(){
		try {
			console.log('widget resize event fired');
			this.fitAddon.fit();
			// this.send_term_size();
		} catch(e){
			console.log('resize error', e);
		}
	}
}

bricks.Factory.register('Wterm', bricks.Wterm);

