<?xml version="1.0" encoding="UTF-8"?>
<!--
  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.
  
-->

<canvas debug="true" width="100%" height="100%" fontsize="14" title="OpenMeetings - Computer testing">
	
	<debug fontsize="14" oninit="Debug.showInternalProperties = true"/>
	
<!--
	Tests for calculating the linewidth in a multinline Textbox for each line
	the meaning of several vars can be seen here:
	http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/js/html/wwhelp.htm
 -->	
    
<script>
<![CDATA[

	var maxsize = 220;
	var textFieldtext = "";
	var startIndex = 0;
	var currentLine = 0;
	var textObject = null;
	var myTextFormat = null;
	var lineHeight = 0;
	
	function calcLineWidthByTextField(maxsizeText,textForCalcing,fontsize, fontname){
		
		maxsize = maxsizeText;
		startIndex = 0;
		textObject = new Array();
		
		textFieldtext = textForCalcing;
		myTextFormat = new TextFormat();
		myTextFormat.size = fontsize;
		myTextFormat.font = fontname;
		
		var metrics = myTextFormat.getTextExtent(textFieldtext, 100000);
		Debug.write(metrics);
		lineHeight = metrics.ascent+metrics.descent;
		Debug.write(lineHeight);		
		
		measureLine();
		
		for (var k = 0;k<textObject.length;k++){
			var metrics = myTextFormat.getTextExtent(textObject[k]["text"], 100000);
			textObject[k]["lineWidth"] = metrics.width;
			//Debug.write("text: ",metrics,k,textObject[k]["lineWidth"],textObject[k]["text"]);
		}
		
		return textObject;
	}
	
	function measureLine(){		
		//Debug.write("restString: ",textFieldtext);
		for (var i=textFieldtext.length;i>0;i--){
			var testTxt = textFieldtext.slice(startIndex, i);
			var metrics = myTextFormat.getTextExtent(testTxt, 100000);
			//Debug.write("metrics: ",testTxt,startIndex,metrics.width);
			if (metrics.width<=maxsize){

				testTxt = textFieldtext.slice(startIndex, i-1);
				textObject[currentLine] = new Array();
				textObject[currentLine]["text"] = testTxt;
				textFieldtext = textFieldtext.slice(i-1, textFieldtext.length);
				
				if (textFieldtext.length==1){
					textObject[currentLine]["text"]+=textFieldtext;
					return;
				} else {
					currentLine+=1;
					return measureLine();
				}
			}
		}		
	}
	
	
	
	//function getLineWidth()
]]>
</script>

<text multiline="true" x="40" y="20" width="220" selectable="true" >
	<handler name="oninit">
		<![CDATA[
			this.sprite.__LZtextclip.wordWrap = false;
			Debug.write(this.sprite.__LZtextclip);
			var items = new Array();
			var t = "";
			//items[0] = ["text","hello your are the hero lets check accomodation today i need some input"];
			items[0] = ["text","hello "];
			items[0] = ["text","der hat drei ecken      und warum ist meni hut der knut      ?? warumST"]; 
			for (var i=0;i<items.length;i++) {
				if (items[i][0]=="text"){
					t += items[i][1];
				} else {
					var tempString = calcLineWidthByTextField(this.width, t,this.fontsize,"Verdana");
					tempString[tempString.length-1]["lineWidth"];
				}
			}
			var tString = calcLineWidthByTextField(this.width, t,this.fontsize,"Verdana");
			for (var k = 0;k<tString.length;k++){
				this.setAttribute('text',this.getText()+textObject[k]["text"]+"\r");
				Debug.write("line,width,text: ",k,textObject[k]["lineWidth"],textObject[k]["text"]);
			}			
			
		]]>
	</handler>
</text>
  
    
</canvas>
