<?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="restrictedUserList" extends="view" width="$once{ parent.width }" 
       height="${ parent.height-34 }">

    <!--- holds a references to the videoview which is broadcasting -->
    <attribute name="broadCastViewRef" value="null" />
    
    <!--- colors for each user -->
    <attribute name="colorArray" value="null" />
    
    <attribute name="allowUserQuestions" value="true" type="boolean" />

    <attribute name="showsVideoInSeparateComponent" value="true" type="boolean" />
    
    <handler name="onallowUserQuestions" args="bool">
        if (bool != null) {
            if (!bool) {
                this._participents._applyAndStatusIcons.destroy();
            }
        }
    </handler>
    
    <handler name="oninit">
        //set modus
        canvas.thishib.modus = "audience";
        
        //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>

    <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>

    <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;
                this.parent.setRoomValues.doCall();
            
            ]]>
        </handler>
    </netRemoteCallHib>     

    <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("setRoomValues1: ",value);
            //if ($debug) Debug.write("setRoomValues2: ",hib.currentroomid);
            
            //if ($debug) Debug.write("+++++++++++++++++ getClientListScope : ",value);
            
            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 ) {
                    value[i].selfItem = true;
                    canvas.isAllowedToDraw = value[i].canDraw;
                } else {
                    value[i].selfItem = false;
                }

                //value[i].lastname = value[i].lastname + "T: " + t;
                
                //if ($debug) Debug.write("getClientListScope value: ",value[i]);
                this.parent.addItemInitial(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(); 
            //FIXME Issue-1076
            canvas.thishib.checkLzRecording.doCall();
            
            //Render and Show User-List
            parent._participents.sortAndRenderList();
            
            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="addItemInitial" args="connectedSince,isMod,streamid,username,userroom,formatedDate,position,color,object">
        <![CDATA[
            //if ($debug) Debug.write("initializeStreams addItem: ",connectedSince,isMod,streamid,username,formatedDate);
            
            //Do init only in case this stream is NOT the same as we are
            if (streamid!=canvas.streamid){
                
                //do add others
                this._participents.initialAddItem(object);
                
                //if ($debug) Debug.write("???????? object.isBroadcasting :: ",object.isBroadcasting);
                
                if (object.isBroadcasting) {
                    this._videoviewcontent.createVideo(object.publicSID, object.firstname+' '+object.lastname, object.broadCastID, object.avsettings, -1, object);
                } else {
                    this._videoviewcontent.createVideoObject(object.publicSID, false, -1, object);
                }
                
            } else {
                //do add self too
                this._participents.initialAddItem(object);
            }
           
        ]]>
    </method>

    <method name="receiveExclusiveAudioFlag" args="publicSID">
    <![CDATA[
        var vList = this._participents._table.renderList;
        for (var i=0;i<vList.length;i++) {
            var item = vList[i];
            var rcl = new Object();

            rcl.publicSID = item.publicSID;
            rcl.micMuted = !(publicSID == item.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,isMod,streamid,username,formatedDate);
            
            //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 others
                this._participents.addItem(object);

                //return myvideocontainer;
            } else {
                //do add self too
                this._participents.addItem(object);
            }
           
        ]]>
    </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._participents.addItem(object);
        ]]>
    </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="setSpeakingByPos" args="publicSID,bool">
        this._videoviewcontent.setSpeakingByPos(publicSID, bool);
    </method>

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

    <method name="resetAllValues">
        this._videoviewcontent.resetAllValues();
    </method>
    
    <method name="removeVideoByUser" args="userObject">
        this._videoviewcontent.removeVideoByUser(userObject.publicSID);
    </method>
    
    <!--- 
        stops the streaming but and destroys the view
        @param int broadcastId broadcastId
     -->
    <method name="disconnectclient" args="publicSID">
        this._videoviewcontent.disconnectclient(publicSID);
        this._participents.disconnectclient(publicSID);
    </method>

    <method name="updateMuteStatusVideoView" args="roomClient">
        this._videoviewcontent.updateMuteStatusVideoView(roomClient);
    </method>
    
    <restrictedUserListInner name="_participents" />
    
</class>

</library>
