<?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="dtmfButton" extends="button" width="20" height="20" >
    <attribute name="dtmf" value="" type="string"/>
    <handler name="onclick">
        callDTMFButton(this,this.text);
    </handler>
    <method name="doNextSipNumber">
        if ($debug) Debug.write("doNextSipNumber ",this.text);
    </method>
</class>
    
<class name="debugPinCode" extends="labelExplorerBox" title="Enter PIN Code"
    docking="true" resizeable="false" closable="true" width="100" x="14" height="120">
    
    
    <view y="24">
        
        <dtmfButton text="1" x="20" dtmf="1"/> 
            <dtmfButton text="2" x="40" dtmf="2"/> 
                <dtmfButton text="3" x="60" dtmf="3"/>
                
        <dtmfButton text="4" x="20" y="20" dtmf="4"/> 
            <dtmfButton text="5" x="40" y="20" dtmf="5"/> 
                <dtmfButton text="6" x="60" y="20" dtmf="6"/>
                
        <dtmfButton text="7" x="20" y="40" dtmf="7"/> 
            <dtmfButton text="8" x="40" y="40" dtmf="8"/> 
                <dtmfButton text="9" x="60" y="40" dtmf="9"/>
                
        <dtmfButton text="10" x="20" y="60" dtmf="10"/>
        
    </view>
    
    
</class>

<class name="baseConferenceRoom" extends="baseContentView" destroyByMethod="true" >
    
    <attribute name="roomobj" value="null" />
    
    <attribute name="meetingTimer" value="null" />
    
	<handler name="oninit">
	<![CDATA[
		_mainScrollBar.setAttribute("visibility","hidden");
		
		if ($debug) Debug.write("roomobj: ",this.roomobj);
		
		canvas.currentRoomObject = this.roomobj;
		var r = this.roomobj;
		r.currentusers = ''; //this might be huge list
		canvas.sendViaLocalConnection(canvas.rtmp_lc_name,"setRoomValues", [this.roomobj.roomtype.roomtypes_id,this.roomobj.rooms_id,r]);
		
		if (this.roomobj.isClosed) {
			canvas.roomClosed();
		}
		
		if (this.roomobj.waitForRecording) {
			new lz.labelerrorPopup(canvas, {labelid: 1316, errorlabelid: 1315});
		}
		
		canvas._mainbgcontentNavi.setAttribute('height',0);
		canvas.setAttribute('naviHeightDelta',28);
		
		if (this._chatPanelStrict) {
			var hideChat = this.roomobj.hideChat != null && this.roomobj.hideChat;
			this._chatPanelStrict.setAttribute('visible', !hideChat);
			if (hideChat) {
				this._chatPanelStrict.setAttribute('height', 28);
			}
		}
		
		if (this.roomobj.hideTopBar == null || !this.roomobj.hideTopBar) {
			createMenu();
			canvas._conferencemenu.setAttribute('visibility','visible');
		} else {
			canvas.setAttribute('naviHeight',0);
			canvas._conferencemenu.setAttribute('visibility','hidden');
			canvas._mainbgcontentNavi.setAttribute('visibility','hidden');
		}
		
		if ($debug) Debug.write("this.roomobj ",this.roomobj);

		new lz.moderationPanel(canvas._moderatormenu,{
				name:'_moderationPanel',align:'right',
				allowUserQuestions:this.roomobj.allowUserQuestions,
				roomName:this.roomobj.name
			});
		if (roomobj.appointment) {
			canvas.appointmentNotificationPopUp = new lz.appointmentNotificationPopUp(this,{name:'appDetail', roomobj:this.roomobj });
		} else {
			if ($debug) Debug.write("no appointed meeting");
		}
		
		if (this.roomobj.isDemoRoom && 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});
		}
		
		canvas.currentBaseConferenceRoom = this;
		canvas._videocontainer.setAttribute("allowUserQuestions",this.roomobj.allowUserQuestions);
	]]>
	</handler>
    
	<handler name="onkeydown" reference="lz.Keys" args="keyCode">
	<![CDATA[
		if ($debug) Debug.write("onkeydown:: keyCode = ", keyCode);
		// common keys are processed firstly
		if (canvas.ARRANGE_WINDOWS_KEY == keyCode) {
			canvas.sendViaLocalConnection(canvas.vid_lc_name, "arrangeWindows", null);
			return;
		}
		if (canvas.GIVE_EXCLUSIVE_AUDIO_KEY == keyCode) {
			if (canvas.ismoderator || canvas.isAllowedToGiveExclusiveAudio) {
				canvas.thishib.giveExclusiveAudio.setExclusiveAudio(canvas.publicSID);
			} else {
				new lz.rpcErrorDialog(canvas.main_content._content.inner,{errorid:-54});
			}
			return;
		}
		if (canvas.MUTE_AUDIO_KEY == keyCode) {
			canvas._videocontainer._videoviewcontent.muteSound(canvas.publicSID, !canvas.micMuted);
			return;
		}
	]]>
	</handler>

    <screenSharingAdapter name="_screenSharingAdapter" />
    
    <baseTabChatPanel name="_chatPanelStrict" labelid="616"
       height="200" x="${ parent._sidePanel.width }"  
       y="${ canvas.height - (this.height) - ((canvas.currentRoomObj.hideTopBar) ? 0 : 28) }" 
       width="${ canvas.width - parent._sidePanel.width }" isopen="${ !canvas.currentRoomObj.chatOpened }" />
       <!-- isopen need to be reverted, will be toggled -->
       
	<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>
</class>

</library>