/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

//
// Callback handlers for AJAX viewer
// Author
//		Kelven Yang
//		11/18/2009
//
function onKickoff() {
	ajaxViewer.stop();
	$('#toolbar').remove();
	$('#main_panel').html('<p>This session is terminated because a session for the same VM has been created elsewhere.</p>');
}

function onDisconnect() {
	ajaxViewer.stop();
	$('#toolbar').remove();
	$('#main_panel').html('<p>This session is terminated as the machine you are accessing has terminated the connection.</p>');
}

function onClientError() {
	ajaxViewer.stop();
	$('#toolbar').remove();
	$('#main_panel').html('<p>Client communication error, please retry later.</p>');
}

function onCanvasSizeChange(width, height) {
	$('#toolbar').width(width);
}

function onStatusNotify(status) {
	if(status == ajaxViewer.STATUS_SENDING || status == ajaxViewer.STATUS_RECEIVING)
		$('#light').removeClass('dark').addClass('bright');
	else
		$('#light').removeClass('bright').addClass('dark');
}

function sendCtrlAltDel() {
	ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 45, ajaxViewer.CTRL_KEY | ajaxViewer.ALT_KEY);
	ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 45, ajaxViewer.CTRL_KEY | ajaxViewer.ALT_KEY);
}

function sendCtrlEsc() {
	ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 17, 0);
	ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 27, ajaxViewer.CTRL_KEY);
	ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 27, ajaxViewer.CTRL_KEY);
	ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 17, 0);
}

function sendAltTab() {
	ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 18, 0);
	ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 9, ajaxViewer.ALT_KEY);
	ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 9, ajaxViewer.ALT_KEY);
	ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 18, 0);
}
