<?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 width="100%" height="100%" title="OpenMeetings">
	
	<switch>
        <when property="$as3">
            <passthrough>
                import flash.net.*;
                import flash.display.*;
                import flash.events.*;
            </passthrough>
        </when>
    </switch>
	<switch>
		<when property="$debug">
			<method name="doDebugInit">
				canvas.setAttribute('debug', true);
			</method>
			<debug fontsize="11" oninit="Debug.showInternalProperties = true" width="40%" y="50%" x="60%" height="50%" />
		</when>
		<otherwise>
			<method name="doDebugInit">
			</method>
		</otherwise>
    </switch>
    
    <include href="testVideoObject.lzx" />

    <silverstyle name="componentStyle" basecolor="0xFFFFFF" textcolor="0x000000" />

    <attribute name="lc_SID"/>

    <attribute name="vid_lc_name" />

    <attribute name="lc"/>

    <attribute name="rtmp_lc_name" />

    <attribute name="rtmp_lc"/>

    <attribute name="videoComp_lc_name" />

    <attribute name="videoComp_lc_callback_name" />

    <attribute name="videoComp_lc" />

    <include href="base/" />

    <include href="modules/" />

    <include href="video/" />
    
    <include href="screensharing/" />
    
    <include href="audioVideoTest/" />
    
    <include href="lzrecorder/" />
    
    <include href="whiteboard/" />

    <include href="commonVideoViewContentSWF10.lzx" />

    <include href="hibAdapter.lzx" />

    <include href="miniIcons.lzx" />

    <include href="dragHelper.lzx" />

    <view name="mainComponent" width="${canvas.width}" height="${canvas.height}">
        <text id="mainBaseText"> </text>
    </view>

    <method name="getLCSID">
        //TODO: fixme
        return "" + Math.floor(999999*Math.random());
    </method>

    <handler name="oninit"><![CDATA[
		doDebugInit();
    
        var tInitArgsArry = new Array('secureHash','invitationHash','sid','roomid','directRoomId'
        	,'language','hash','cuser','tAccept','moodleRoom','becomemoderator','wwwroot','user_id'
        	,'picture','scopeRoomId', 'wicketsid', 'wicketroomid', 'protocol', 'host', 'port', 'context');
    
        this.setAttribute('lc_SID', this.getLCSID());
        this.setAttribute('vid_lc_name', lc_SID + '__videoLC');
        this.setAttribute('rtmp_lc_name', lc_SID + '__rtmpLC');
        this.setAttribute('videoComp_lc_name', lc_SID + '__streamLC');
        this.setAttribute('videoComp_lc_callback_name', lc_SID + '__streamLC_cback');

        var videoComp_lc_cback:LocalConnection = new LocalConnection();
        videoComp_lc_cback.connect(this.videoComp_lc_callback_name);
        this.setAttribute('videoComp_lc',videoComp_lc_cback);
        
        var tqueryString = "";
        for (var i = 0; i < tInitArgsArry.length; ++i) {
            // if ($debug) Debug.write(tInitArgsArry[i],lz.Browser.getInitArg(tInitArgsArry[i]));
            var tValue = lz.Browser.getInitArg(tInitArgsArry[i]);
            if (tValue != undefined) {
                tqueryString += "&" + tInitArgsArry[i] + "=" + tValue;
                if (tInitArgsArry[i].startsWith('wicket')) {
                	canvas.setAttribute(tInitArgsArry[i], tValue);
                }
            }
        }
        
        var tSWFURL = canvas.getLocalBaseUrl() + "main" + ($debug ? "debug" : "") + ".swf8.swf?lzproxied=solo&lc_SID="+lc_SID+tqueryString;
        
        if ($debug) Debug.write("tSWFURL :: ",tSWFURL);
        
        var request:URLRequest = new URLRequest(tSWFURL);
        var loader:Loader = new Loader();
        loader.load(request);
        this.mainComponent.sprite.addChild(loader);

        new lz.commonVideoViewContentSWF10(this, {name:'_videoComponent'});
        new lz.hibAdapter(this);

        if ($debug) Debug.write("main::init DONE");
    ]]></handler>

    <view name="inner"></view>
    
</canvas>
