<?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.
  
-->
<library>
    
<class name="participants" extends="baseRoomInnerList" 
       height="$once{ parent.height-34 }">

    <!--- holds a references to the videoview which is broadcasting -->
    <attribute name="broadCastViewRef" value="null" />
    
    <handler name="oninit">
        //set modus
        canvas.thishib.modus = "conference";
       
        //set reference, this reference will be cleared at *ontabcontenctleave* event
        canvas._videocontainer=this;
        
        // Reconnect User to its Room Id
        canvas.thishib.userScope = canvas.thishib.currentroomid;
        var src = hib.getUrl();
        
        if( $debug ) Debug.write("videoContainer: canvas.thishib: ",canvas.thishib.src,canvas.thishib);
        
        if (canvas.thishib.src != src) {
            canvas.thishib.setAttribute('src',src);
            
            canvas.thishib.reconnectionAction = true;
            canvas.thishib.reconnectObjRef = this;
            canvas.thishib.disconnect();
        } else {
            //The user is already in the correct Scope
            this.reconnectSuccess();
        }
    </handler>
    
    <method name="initList">
    	//
    </method>

    <commonVideoComponentAdapter name="_videoviewcontent" />

    <method name="reconnectSuccess">
        if ($debug) Debug.write("User Reloged In");
        //Send to SWF10 video-container to connect on the conference room url
        //and wait for the as3ConnectionSuccess-Event
        this._videoviewcontent.reconnectSuccess(false);
    </method>

    <!---
        We need to wait till the video-container / as3 app has the connection established
        otherwise it can happen that the video tries to start playing before the rtmp-connection
        was established
     -->
    <method name="as3ConnectionSuccess">
    	if ($debug) Debug.write("as3ConnectionSuccess continue loading");
    	//set default values and get already availible streams
    	//it can happen that if you click to exit the room the views are not
    	//not cleaned up yet and you receive this event from the LocalConnection
    	if (this["getRoomModeratorsByRoomId"]) {
            this.getRoomModeratorsByRoomId.doCall();
    	}
    </method>



    <!---
        Returns a list of all moderators of the current room and parses 
        if the current user should receive the supermoderator flag or not
     -->
    <netRemoteCallHib name="getRoomModeratorsByRoomId" funcname="conferenceservice.getRoomModeratorsByRoomId" 
                      remotecontext="$once{ canvas.thishib }" >  
        <netparam><method name="getValue">return canvas.sessionId;</method></netparam>    
        <netparam><method name="getValue">return hib.currentroomid;</method></netparam>
        <handler name="ondata" args="value">
            <![CDATA[
                if ($debug) Debug.write("getRoomModeratorsByRoomId: ",value);
                canvas.becomeSuperModerator = false;
                
                parent.setRoomValues.applyDefaultModeration = canvas.becomemoderator;
                canvas.becomeSuperModerator = canvas.becomemoderator;
                
                if (!canvas.becomeSuperModerator) {
    	            for (var i=0;i<value.length;i++) {
                        
                        if (value[i].user.user_id == canvas.user_id) {
                            parent.setRoomValues.applyDefaultModeration = true;
                            canvas.becomeSuperModerator = value[i].isSuperModerator;
                            if ($debug) Debug.info("Make this User to an Moderator");
                            break;
                        }
                        
                    }
                }
	            
                if ($debug) Debug.write("canvas.becomemoderator: ",canvas.becomemoderator);
                if ($debug) Debug.write("canvas.becomeSuperModerator: ",canvas.becomeSuperModerator);
                
                canvas.currentusercolor = canvas.getColorForUser();
                
                var organisation_id = 1;
            
                if ($debug) Debug.write(hib.userobject); 
                if ($debug) Debug.write(hib.currentdomainObj); 
                
                if (hib.currentdomainObj != null) {
                    organisation_id = hib.currentdomainObj.organisation_id
                }
                
                this.parent.setRoomValues.organisation_id = organisation_id;
                
                if ($debug) Debug.write("setRoomValues CALL: ");
                this.parent.setRoomValues.doCall();
            
            ]]>
        </handler>
    </netRemoteCallHib>     

    <!---
        Returns a list of all users currently in the conference room
     -->
    <netRemoteCallHib name="setRoomValues" funcname="setRoomValues" remotecontext="$once{ canvas.thishib }" >   
        <attribute name="applyDefaultModeration" value="false" type="boolean" />
        <attribute name="organisation_id" value="0" type="number" />
        <netparam><method name="getValue">return hib.currentroomid;</method></netparam>
        <netparam><method name="getValue">return parent.applyDefaultModeration;</method></netparam>
        <netparam><method name="getValue">return canvas.becomeSuperModerator;</method></netparam>
        <netparam><method name="getValue">return parent.organisation_id;</method></netparam>
        <netparam><method name="getValue">return canvas.currentusercolor;</method></netparam>
        <handler name="ondata" args="roomStatus">
            <![CDATA[
            //The onResult-Handler will be called be the rtmpconnection
            if ($debug) Debug.write("+++++++++++++++++");
            if ($debug) Debug.write("+++++++++++++++++ setRoomValues1: ",roomStatus);
            
            if (roomStatus.roomFull) {
                canvas.thishib.showFullMessage = true;
                canvas.thishib.disconnect();
            }
            
            if (roomStatus.browserStatus.browserInited) {
                var tObj = new Object();
                tObj[0] = "newBrowserURL";
                tObj[1] = roomStatus.browserStatus.currentURL;
                canvas.startBrowser(tObj);
            }
            
            var value = roomStatus.clientMap;
            
            for (var i in value){
                if ( value[i].streamid == canvas.streamid ) {
                    canvas.isAllowedToDraw = value[i].canDraw;
                }
                //if ($debug) Debug.write("getClientListScope value: ",value[i]);
                this.parent.addItem(value[i].connectedSince,value[i].isMod,value[i].streamid,value[i].username,
                              '',value[i].formatedDate,value[i].userpos,value[i].usercolor,value[i]);
            }
            
            //this content must be inited _after_ setting the default values
            canvas.thishib.getCurrentModeratorList.doCall(); 
            
            canvas.thishib.checkLzRecording.doCall();
            canvas._chatcontent.doInit();   
            ]]>
        </handler>  
    </netRemoteCallHib>

    <!---
        invoked if another client logs into the room 
        after choosing devices
     -->     
    <method name="setAVSettingsToClient" args="rcl">
        this._videoviewcontent.setAVSettingsToClient(rcl);
    </method>

    <method name="receiveExclusiveAudioFlag" args="publicSID">
    <![CDATA[
    	if ($debug) Debug.write("receiveExclusiveAudioFlag: ",publicSID);
        var obj = this._participants.getVideoObjectByPublicSID(publicSID);

        for (var i=0; i<obj.parent.subviews.length; i++) {
            var item = obj.parent.subviews[i];
            var rcl = new Object();

            rcl.publicSID = item.refObj.publicSID;
            rcl.micMuted = !(publicSID == item.refObj.publicSID);
            canvas.setMuteStatus(rcl);
        }
    ]]>
    </method>
    
    <method name="addItem" args="connectedSince,isMod,streamid,username,userroom,formatedDate,position,color,object">
        <![CDATA[
            if ($debug) Debug.write("initializeStreams addItem: ",connectedSince,object);
            
            //Do init only in case this stream is NOT the same as we are
            if (streamid!=canvas.streamid){
            	//if ($debug) Debug.write("???????? object.isBroadcasting :: ",object.isBroadcasting);
                this._videoviewcontent.createVideo(object.publicSID, object.firstname+' '+object.lastname, object.broadCastID, object.avsettings, -1, object);
            }
           
            //do add self too
            this._participants.addItem(object);
        ]]>
    </method>

    <method name="setSpeakingByPos" args="publicSID,bool">
    	var tObj = this._participants.getVideoObjectByPublicSID(publicSID);
    	if (tObj != null) {
	    	if (bool){
	            tObj._miniIcons._loudness.loudness.setAttribute('opacity',1);
	        } else {
	            tObj._miniIcons._loudness.loudness.setAttribute('opacity',0.2);
	        }
        }
        this._videoviewcontent.setSpeakingByPos(publicSID, bool);
    </method>

    <method name="closeStreamClient" args="publicSID">
        this._videoviewcontent.closeStreamClient(publicSID);
    </method>

    <method name="updateMuteStatusVideoView" args="roomClient">
        this._videoviewcontent.updateMuteStatusVideoView(roomClient);
    </method>
    
    <method name="disconnectclient" args="publicSID">
        this._videoviewcontent.disconnectclient(publicSID);
        this._participants.disconnectclient(publicSID);
    </method>

    <method name="resetAllValues">
        this._videoviewcontent.resetAllValues();
    </method>
    
    <!--
        invoked whenever a User starts to Stream Video in this Room,
        interviewPodId has only a meaning in the Room Type Interview
     -->
    <method name="startStream" args="publicSID,broadcastId,firstname,lastname,interviewPodId,VWidth,VHeight">
        this._videoviewcontent.startStream(publicSID,broadcastId,firstname,lastname,interviewPodId,VWidth,VHeight);
    </method>
    
    <method name="addClientItem" args="connectedSince,isMod,streamid,username,room_id,formatedDate,position,color,object">
        <![CDATA[
        if ($debug) Debug.write("### initializeStreams addClientItem: ",connectedSince,isMod,streamid,username,room_id,formatedDate);

        if (canvas.publicSID != object.publicSID){
            this._videoviewcontent.createVideoObject(object.publicSID, false, -1, object);
        }

        //Do Add it anyway
        this._participants.addItem(object);
        ]]>
    </method>
    
    <moderationMiniIconsEventUserList name="_applyAndStatusIcons" x="2" y="2" >
        <handler name="onismoderator" reference="canvas" args="m">
            this.updateIcons();
        </handler>
        <handler name="ondrawAllowStatus" reference="canvas" args="drawObject">
            this.updateIcons();
        </handler>
        <handler name="onexclusiveAudioAllowStatus" reference="canvas" args="rclObject">
            this.updateIcons();
        </handler>
        <handler name="onlastBroadCastingUser" reference="canvas" args="userObject">
            this.updateIcons();
        </handler>
        <handler name="onmicMutedStatusChangedItem" reference="canvas" args="userObject">
            this.updateIcons();
        </handler>
    </moderationMiniIconsEventUserList>
    
    <participantList name="_participants" />
    
</class>

</library>
