/*jslint plusplus: true, white: true, indent: 2, maxlen: 90 */
/**
* @author Wolfgang Kowarschick
* @copyright 2013, Wolfgang Kowarschick
* <br/>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted under the terms of the
* Creative Commons License Attribution-NonCommercial-ShareAlike 3.0 Unported
* (CC BY-NC-SA 3.0: http://creativecommons.org/licenses/by-nc-sa/3.0/).
*/
(function($wk$, document)
{ "use strict";
var Controller, Scrollbar, Terminal;
/** @private */
Controller =
function(p_terminal, p_init)
{ var l_up = (p_init && p_init.up) || 38,
l_down = (p_init && p_init.down) || 40;
document.onkeypress =
function(p_event)
{ if (p_event.keyCode === l_up)
{ p_terminal.up(); }
else if (p_event.keyCode === l_down)
{ p_terminal.down(); }
};
};
/** @private */
Scrollbar =
function(p_terminal, p_init)
{ var l_key = null;
this.width = 10;
this.padding = 0;
this.color = "#888888";
// Override defaults if wished
/*jslint forin: true*/
for (l_key in p_init)
{ this[l_key] = p_init[l_key]; }
this.v_terminal = p_terminal;
this.v_x = p_terminal.width - this.width - this.padding;
this.v_y = this.padding;
this.height = p_terminal.height-2*this.padding;
};
Scrollbar.prototype =
{ draw:
function()
{ var l_terminal = this.v_terminal,
l_context = l_terminal.v_context,
l_terminal_height = l_terminal.height,
l_print_height = l_terminal_height - l_terminal.marginTop
- l_terminal.marginBottom,
l_text_length = l_terminal.lineHeight*l_terminal.v_lines.length,
l_ratio = l_print_height/l_text_length;
if (l_text_length > l_print_height)
{ this.height = l_print_height*l_ratio - 2*this.padding;
this.v_y = this.padding
+ l_terminal.v_line_first*l_terminal.lineHeight*l_ratio;
l_context.beginPath();
l_context.fillStyle = this.color;
l_context.rect (this.v_x, this.v_y, this.width, this.height);
l_context.fill();
}
}
};
/**
* @class
* @name $wk$.Terminal2
* @param {String} p_terminal_id
* The identifier of the canvas element where the lines are to be
* printed.
* @param {JSON} p_init
* A JSON object that contains initial values for the
* terminal (i.e. canvas), scrollbar, and the (keyboard) controller.
*/
Terminal =
function(p_terminal_id, p_init)
{ var l_key = null,
l_terminal = document.getElementById(p_terminal_id);
// Default values
this.width = 500;
this.height = 500;
this.fontFamily = "'Times New Roman', Times, serif";
this.fontSize = 10;
this.fontWeight = "bold";
this.fontColor = "#000000";
this.lineHeight = 15;
this.marginTop = 0;
this.marginBottom = 0;
this.marginLeft = 10;
this.scrollbar = {};
// Override defaults if wished
/*jslint forin: true*/
for (l_key in p_init)
{ this[l_key] = p_init[l_key]; }
// All lines of text to be printed onto the canvas.
this.v_lines = [];
// The number of the first line to be printed.
this.v_line_first = 0;
// The number of lines fitting on the canvas.
this.v_canvas_length =
Math.floor((this.height-this.marginTop-this.marginBottom)/this.lineHeight);
l_terminal.width = this.width;
l_terminal.height = this.height;
this.v_context = l_terminal.getContext("2d");
// The initialization object this.scrollbar
// is replaced by a real scrollbar object,
this.scrollbar = new Scrollbar(this, this.scrollbar);
this.controller = new Controller(this, this.controller);
};
Terminal.prototype =
{ /** @private */
m_draw:
function()
{ var i, n, l,
l_lines = this.v_lines,
l_canvas_length = this.v_canvas_length,
l_context = this.v_context;
l_context.clearRect(0, 0, this.width, this.height);
l_context.font
= this.fontWeight + " " + this.fontSize + "px" + " " + this.fontFamily;
l_context.fillStyle = this.fontColor;
for (i = this.v_line_first, n = l_lines.length, l = 0;
i < n && l < l_canvas_length;
i++, l++
)
{ l_context.fillText(l_lines[i],
this.marginLeft,
this.marginTop + (l+1)*this.lineHeight
);
}
this.scrollbar.draw();
},
/**
* Prints a line on the terminal.
* @method
* @name $wk$.Terminal2#println
* @param {String[]} arguments The strings to be printed.
*/
println:
function()
{ var i, n,
l_text = "",
l_sep = "",
l_lines = this.v_lines,
l_canvas_length = this.v_canvas_length;
for (i = 0, n = arguments.length; i < n; i++)
{ l_text += l_sep + arguments[i];
l_sep = ", ";
}
l_lines.push(l_text);
if (l_lines.length > l_canvas_length)
{ this.v_line_first = l_lines.length - l_canvas_length; }
this.m_draw();
},
/**
* Moves content of the terminal one line up (if possible).
* @method
* @name $wk$.Terminal2#up
*/
up:
function()
{ if (this.v_line_first > 0)
{ this.v_line_first--;
this.m_draw();
}
},
/**
* Moves content of the terminal one line down (if possible).
* @method
* @name $wk$.Terminal2#down
*/
down:
function()
{ if (this.v_line_first < this.v_lines.length - this.v_canvas_length)
{ this.v_line_first++;
this.m_draw();
}
}
};
$wk$.Terminal2 = Terminal;
}(this.$wk$, this.document));