function addTextElement(sceneElem, elemClass) {
	if (sceneElem.text) {
		console.log("sceneElem already textified!");
		var blah = null;
		blah.crash();
		return;
	}
	
	var elem = sceneElem.div.appendChild(document.createElement("span"));
	elem.innerHTML = "<br>";
	elem.className = elemClass;
	sceneElem.text = elem;
}

function initializeCall() {
	/* Replace single-color background image by actual background color ^^ */
	scenes.call.background.div.childNodes[0].remove();
	scenes.call.background.div.style.backgroundColor = "#AAE2E4";
	
	addTextElement(scenes.call.thought_bubble, "spire-bubble-text spire-thought");
	addTextElement(scenes.call.phone.bubble.up, "phone-bubble-text");
	addTextElement(scenes.call.phone.bubble.down, "phone-bubble-text");
	addTextElement(scenes.call.spirou_bubble, "spire-bubble-text spire-call");
}

function setBubbleText(bubble, newText) {
	bubble.text.innerHTML = newText;
}

function createCallTimeline(callee, events) {
	var call = scenes.call, background = call.background, spirou = call.spirou, phone = call.phone.phone, flash = background.flash,
		show = { opacity: 1, immediateRender: false }, hide = { opacity: 0, immediateRender: false },
		farout = { x: "+=1500", immediateRender: false }, backin = { x: "-=1500", ease: Power2.easeIn, immediateRender: false };
	
	var callTimeline = new TimelineMax({ paused: true});
	
	for (var name of phone.children) {
			callTimeline.add(phone[name].set(callee == name ? show : hide));
	}
	
	callTimeline
		.add([ call.spirou_bubble.set(hide), call.phone.bubble.down.set(hide), call.phone.bubble.up.set(hide), call.thought_bubble.set(hide),
			   flash.set(farout), phone.set(farout), background.set(show), spirou.set(show) ])
		.add( call.fromTo(1, hide, show) );
		
	for (var event of events) {
		if (event.delay)
			callTimeline.set({}, {}, "+=" + event.delay);
		if (event.label)
			callTimeline.addLabel(event.label);
		
		if (event.enterPhone) {
			callTimeline.add([ 
				flash.to(0.5, backin), 
				phone.to(0.6, backin)
			]);
		} else if (event.fadeToScene) {
			callTimeline.add([
				background.to(1, hide),
				spirou.to(1, hide)
			]);
		} else {
			bubble = event.spirou ? call.spirou_bubble : (event.thought ? call.thought_bubble : call.phone.bubble.up);
			/*tween = event.spirou ?
				call.spirou.spirou.head.to(0.5, { rotation: 20,  ease: function(x) { return Math.sin(x*2*Math.PI); } } ) :
				call.phone.phone.to(0.5, { x: "+=50",  ease: function(x) { return -10; Math.sin(x*2*Math.PI); } } );*/
			callTimeline
				.call( setBubbleText, [ bubble, event.text ] )
				.add( bubble.to(0.3, show) )
				.add( bubble.to(0.3, hide) , "+=" + event.time);
		}			
	}
	
	callTimeline
		.add(phone.to(0.5, farout))
		.add([call.set(hide), phone.set(backin)]);
	
	return callTimeline.play();
};
		
function findLabelTime(timeline, label) {
	/* from https://greensock.com/forums/topic/9304-interacting-with-labels-in-nested-timelines/ */
  var time = timeline.getLabelTime(label),
      i = 0,
      children, tl;
  if (time !== -1) { //if the label is in the main timeline, just return the time (performance optimization)
    return time;
  }
  children = timeline.getChildren(true, false, true); //if the label wasn't found, we need to seach all the child timelines.
  while (time === -1 && i < children.length) {
    tl = children[i];
    time = tl.getLabelTime(label);
    i++;
  }
  if (time === -1) { //the label doesn't exist
    return -1;
  }
  time = tl.startTime() + time / tl.timeScale();
  tl = tl.timeline;
  while (tl && tl !== timeline) {
    time = tl.startTime() + time / tl.timeScale();
    tl = tl.timeline;
  }
  return time;
}