<?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="restrictedConferenceRoom" extends="baseConferenceRoom">

    <handler name="oninit">
        new lz.restrictedConferenceMenubar(canvas._conferencemenu);
        
        new lz.moderationPanel(canvas._conferencemenu,{
                    name:'_moderationPanel',align:'right',
                    allowUserQuestions:this.roomobj.allowUserQuestions
                });  
                
        canvas._conferencemenu.setAttribute('visibility','visible');
        
        if ($debug) Debug.write("this.roomobj ",this.roomobj);
        
        if(this.roomobj.appointment){
            canvas.appointmentNotificationPopUp =
                new lz.appointmentNotificationPopUp(canvas.conferenceView,{ 
                        name:'appDetail', roomobj:this.roomobj });   
        } else{
            if ($debug) Debug.write("no appointed meeting");
        }
        
        if (this.roomobj.isDemoRoom) {
            if (this.roomobj.demoTime != null) {
                if ($debug) Debug.warn("THIS IS A DEMO ROOM THAT SHOULD CLOSE AFTER SEC: ",this.roomobj.demoTime);
                this.meetingTimer = new lz.meetingTimer(canvas,{refObj:this,roomobj:this.roomobj});
            }
        }
        
        this._chatPanelStrict.toggleopen();
        
        canvas.currentBaseConferenceRoom = this;
        
        canvas._videocontainer.setAttribute("allowUserQuestions",this.roomobj.allowUserQuestions);
        
    </handler>
    
    <handler name="ontabcontentleave">
        if ($debug) Debug.write("################# ontabcontentleave:",this);
        
        this._screenSharingAdapter.closeAllScreenSharings();
        
        canvas.currentBaseConferenceRoom = null;
        
        //reset the right to draw on WHiteboard as the RoomClient Object will be destroyed also
        //on server-Side the canDraw status will be false again when you relogin the same room
        canvas.isAllowedToDraw = true;
        
        _mainScrollBar.setAttribute("visibility","visible");
        
        //reset rights
        canvas.isAllowedToGiveExclusiveAudio = false;
        
        if (canvas._videocontainer!=null){
            canvas._videocontainer.resetAllValues();
            canvas._videocontainer = null;
        }
        if (canvas._chatcontent!=null){
            canvas._chatcontent = null;
        }
        if (canvas._mymod!=null){
            canvas._mymod = null;
        }
        
        if (this.meetingTimer != null) {
            this.meetingTimer.close();
        }
        
        if (canvas._drawarea.letterObjectIsActive){
            canvas._drawarea.currentletterObj.destroy();
        }
        
        if (canvas.currentFileExplorer != null) {
            canvas.currentFileExplorer = null;
        }
        
        if (canvas.currentActivityList != null) {
            canvas.currentActivityList = null;
        }
        
        //@deprecated we will not use old screen sharing implementation
        //canvas._screens.clearAllSessions();
        this.logicalRoomLeave.doCall();
        if ($debug) Debug.write("############ this.logicalRoomLeave ",this.logicalRoomLeave);
    </handler>

    <netRemoteCallHib name="logicalRoomLeave" funcname="logicalRoomLeave" remotecontext="$once{ canvas.thishib }" >
        <handler name="ondata" args="value">
            if ($debug) Debug.write("############# logicalRoomLeave: ",value);
            //this.parent.destroy();
            canvas.thishib.reconnectAfterRoomleft = true;
            canvas.thishib.reconnectedRoomInstance = this.parent;
            
            // Reconnect User to default Scope
            canvas.thishib.userScope = "hibernate";
            var src = hib.getUrl();
            canvas.thishib.setAttribute('src',src);
            canvas.thishib.disconnect();
            canvas._mainbgcontentNavi.setAttribute('height',canvas.naviHeight);
            canvas.setAttribute('naviHeightDelta',canvas.naviHeight);
            canvas._conferencemenu.removeAll();
            canvas._conferencemenu.setAttribute('visibility','hidden');
        </handler>
    </netRemoteCallHib>
    
    <restrictedRoomSidebar name="_sidePanel" restricted="true" 
                      listType="eventUserListTableWithNames" />
    
    <view name="_videoviewcontent_hideWhiteboard" y="0" x="${ parent._sidePanel.width }"
		  width="${canvas.width-parent._sidePanel.width}" height="${canvas.height-(parent._chatPanelStrict.height) - 
        ((parent._chatPanelStrict.visibility == 'hidden') ? 5:28)}" clip="true" 
		  visibility="${((canvas.currentRoomObj.hideWhiteboard) ? 'visible':'hidden')}">
			<view name="_inn" width="${parent.width-10}">				
				<wrappinglayout axis="x" spacing="10"/>
			</view>
			<om_vscrollbar name="_attenddeescrollbar" visibility="visible"></om_vscrollbar>
	</view>
    
    <baseTabChatPanel name="_chatPanelStrict" labelid="616"
       height="200" x="${ parent._sidePanel.width }"  
       y="${ canvas.height - (this.height) - 28 }" 
       width="${ canvas.width - parent._sidePanel.width }" />
       
    <fixedFileExplorerWhiteboardPanel name="_whiteboard" labelid="615"
        y="0" x="${ parent._sidePanel.width }" 
        width="${ canvas.width - parent._sidePanel.width }"
        height="${ canvas.height - (parent._chatPanelStrict.height) - ((parent._chatPanelStrict.visibility == 'hidden') ? 0:28) }" />
        
    <!--
        ###############################
        This is the container for all Videos
     -->
    <commonVideoViewContent name="_videoviewcontent" />
    
</class>

</library>
