<?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.
  
-->

<!-- methods for main.lzx -->

<library>
    
    <method name="onError" args="errorEvent">
		canvas.videoComp_lc.send(canvas.videoComp_lc_name, 'remoteLogWrite', "error " + errorEvent);
	</method>
    
    <method name="myinit">
        <![CDATA[
        // Add listener to all uncaught flash errors
        this.getDisplayObject().loaderInfo.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onError);
        
        canvas.mediaerrortimeout = 30000;
        canvas.medialoadtimeout = 30000;
        
        if($debug) Debug.write("main.lzx/config.xml ondata",this);
        
        //Audio-Video-Settings
        this.setAttribute('loudnessAcitviation',canvas.myConfigSet.getPointer().xpathQuery('config/loudnessAcitviation/text()'));
        this.setAttribute('codecType',canvas.myConfigSet.getPointer().xpathQuery('config/codecType/text()'));
        this.setAttribute('framesPerSecond',Number(canvas.myConfigSet.getPointer().xpathQuery('config/framesPerSecond/text()')));  
        this.setAttribute('bandwidthNeededNormal',Number(canvas.myConfigSet.getPointer().xpathQuery('config/bandwidthNeededNormal/text()')));  
        this.setAttribute('bandwidthNeededBest',Number(canvas.myConfigSet.getPointer().xpathQuery('config/bandwidthNeededBest/text()')));  
        this.setAttribute('camQualityNormal',Number(canvas.myConfigSet.getPointer().xpathQuery('config/camQualityNormal/text()')));  
        this.setAttribute('camQualityBest',Number(canvas.myConfigSet.getPointer().xpathQuery('config/camQualityBest/text()')));  
        this.setAttribute('microphoneRateBest',Number(canvas.myConfigSet.getPointer().xpathQuery('config/microphoneRateBest/text()')));  
        this.setAttribute('echoPath',Number(canvas.myConfigSet.getPointer().xpathQuery('config/echoPath/text()')));
        this.setAttribute('echoSuppression',canvas.myConfigSet.getPointer().xpathQuery('config/echoSuppression/text()'));
        
        //httphostlocal variable is loaded from the SWF8 application, cause it needs value, SWF10 app
        //knows nothing about the rtmphostlocal, and we don't want to parse the URL from the browser
        //in both applications to find out where the user loaded the SWF from and extract the domain/ip 
        //from it
        
        this.setAttribute('httpRootKey',canvas.myConfigSet.getPointer().xpathQuery('config/httpRootKey/text()'));
        this.setAttribute('protocol',canvas.myConfigSet.getPointer().xpathQuery('config/protocol/text()')); 
        this.setAttribute('proxyType',canvas.myConfigSet.getPointer().xpathQuery('config/proxyType/text()'));  

        var _url = this.getDisplayObject().loaderInfo.url;
        if($debug) Debug.write("_url: ",_url);
        
        ]]>
    </method>
    
    <method name="getLabelName" args="id">
    	// return "label "+id;
        //if($debug) Debug.write("main.lzx/getLabelName()",id);
        return getLabelTag(id);
    </method>
    
    <method name="getThemeImage" args="tName">
		if ($debug) Debug.write("load Image by Name SWF10: ",tName);
		var tPath = canvas.mainTheme.getPointer().xpathQuery("theme/resource[@name='"+tName+"']/@src");
		if ($debug) Debug.write("tPath SWF10 "+tPath);
		return tPath;
	</method>
	
	<method name="getThemeColor" args="tColor">
		if ($debug) Debug.write("load Color by Name SWF10: ",tColor);
		var tColor = canvas.mainTheme.getPointer().xpathQuery("theme/color[@name='"+tColor+"']/@value");
		if ($debug) Debug.write("tColor SWF10 "+tColor);
		return tColor;
	</method>
	
	<!-- 
		httphostlocal is synced from the SWF8 application, it will always point to the master
	 -->
	<method name="getHttpHost">
		return canvas.httphostlocal;
    </method>
	
	<method name="getUrl">
		<![CDATA[
			return canvas.protocol + '://' + getHttpHost()
				+ ':' + canvas.red5httpport + canvas.httpRootKey;
		]]>
	</method>
    
	<method name="getPictureUrl" args="pictureuri,extraParams">
	<![CDATA[
		var pUri = (pictureuri == null || pictureuri.length == 0) ? "d.jpg" : pictureuri;
		var downloadurl = pUri;
		if (!pUri.startsWith("http://") && !pUri.startsWith("https://")) {
			pUri = "_profile_" + pUri;
			
			downloadurl = canvas.getUrl() + 'DownloadHandler?fileName=' + pUri
				+ '&room_id=&r=' + (new Date()).getTime()
				+ extraParams + '&sid='+canvas.sessionId;
		}
		if($debug) Debug.write("getPictureUrl/downloadurl ", downloadurl);
		return downloadurl;
	]]>
	</method>
		
</library>
