///
///
module Elements.CurrentTurnHandler {
export var currentTurnTab = document.getElementById("currentTurnTab");
export var currentTurn = document.getElementById("currentTurn");
export var turnHr = document.createElement("p");
export var lastReadOffset = currentTurnTab.clientHeight / 2;
turnHr.classList.add("turnStart");
turnHr.appendChild(document.createTextNode("Start of Turn"));
/**
* Creates the "Start of Turn" elements and scrolls the content panel until the start of the new turn.
*/
export function startTurn (action? : Action) {
let oldContent = new Array(...currentTurnTab.getElementsByClassName("content"));
for (let i = oldContent.length - 1; i >= 0; i--) {
oldContent[i].classList.add("contentOld");
oldContent[i].classList.remove("content");
}
currentTurnTab.appendChild(turnHr);
Elements.startTurn();
scrollToNewTurn();
}
/**
* Are we in the middle of a turn?
*/
export function isTurn () {
return Elements.isInTurn();
}
/**
* Removes the blur effect around the turn panel
*/
export function endTurn () {
Elements.endTurn();
}
export function getSayElementsAsContent (say : Say) : Promise> {
return say.getHTML("p", ["content"]);
}
/**
* Prints given Say directly
* @param say
*/
export function printAsContent (say : Say) {
let node = getMarker();
getSayElementsAsContent(say).then(value => {
insertBefore(value, node);
unprint(node);
});
}
/**
* Creates a say for sayValues and then prints it as content.
* @param sayValues
*/
export function simplePrint (...sayValues : Array) {
printAsContent(new Say(...sayValues));
}
export function printAsError (msg : Say | string) {
if (msg instanceof Say) {
msg.getHTML("div", ["error"], true).then(value => {
print(...value);
});
} else {
let div = document.createElement("div");
div.classList.add("error");
div.appendChild(document.createTextNode(msg));
print(div);
}
}
export function clear () {
while (currentTurnTab.firstChild != undefined) {
currentTurnTab.removeChild(currentTurnTab.firstChild);
}
Controls.KeyHandler.reset();
}
/**
* Includes the given elements as content.
* This is the only correct way of printing elements.
* @param elements
*/
export function print (...elements : Array) {
if(elements.length > 0) {
elements.forEach((element) => {
currentTurnTab.appendChild(element);
});
scrollTo(lastReadOffset);
}
}
export function getMarker () {
let node = document.createTextNode("");
currentTurnTab.appendChild(node);
return node;
}
export function insertBefore (newChilds : Array, oldChild) {
newChilds.forEach((newChild) => {
currentTurnTab.insertBefore(newChild, oldChild);
});
scrollTo(lastReadOffset);
}
/**
* Removes elements that have been printed in the past.
* @param elements
*/
export function unprint (...elements : Array) {
elements.forEach((element) => {
if (element.parentElement == currentTurnTab) {
currentTurnTab.removeChild(element);
}
});
}
/**
* Scrolls to the first current turn element. (Or rather, to just after the Start of Turn element)
* This is used internally as a new turn begins.
*/
export function scrollToNewTurn () {
let target = turnHr.offsetTop + turnHr.offsetHeight;
lastReadOffset = target;
//turnHr.scrollIntoView({behavior : "smooth", block : "start"});
if (target < currentTurn.scrollTop) {
return; // We don't want to scroll UP.
}
scrollTo(target);
}
/**
* Scrolls to the very bottom of the content panel.
*/
export function scrollToBottom () {
scrollTo(currentTurn.scrollHeight - currentTurn.clientHeight);
}
/**
* Scroll half a screen forward
*/
export function scrollSpace () {
scrollTo(currentTurn.scrollTop + (currentTurn.clientHeight / 2));
}
/**
* Update text that was read as player scrolls
*/
currentTurn.addEventListener("scroll", () => {
let currentRead = currentTurn.scrollTop + currentTurn.clientHeight;
if (currentRead > lastReadOffset) {
lastReadOffset = currentRead;
}
});
/**
* Animation... removing jquery
*/
var startOffset : number;
var targetOffset : number;
var startTime : number;
var finishTime : number;
var totalTime : number;
var animationRequest : number;
export function scrollTo (offset : number) {
if (offset <= lastReadOffset) {
startOffset = currentTurn.scrollTop;
targetOffset = offset;
startTime = new Date().getTime();
finishTime = startTime + Elements.animationTime;
totalTime = finishTime - startTime;
startScrolling();
}
}
export function startScrolling () {
if (animationRequest == undefined) {
animationRequest = requestAnimationFrame(updateFrame);
}
}
export let updateFrame = () => {
animationRequest = undefined;
let movingOffset = (targetOffset - startOffset);
let timePassed = new Date().getTime() - startTime;
let idealOffset = movingOffset * (timePassed / totalTime);
let maxScroll = currentTurn.scrollHeight - currentTurn.clientHeight;
currentTurn.scrollTop = startOffset + idealOffset;
if (currentTurn.scrollTop < targetOffset && currentTurn.scrollTop < maxScroll) {
startScrolling();
}
}
}