<?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="interviewVideoChooseUser" extends="guiPresenter" resizeable="false"
    width="220" height="100" closable="true" labelid="910" y="10" minimizable="false">
    
    <attribute name="refObj" value="null" />
    
    <handler name="oninit">
        this.getClientListScope.doCall();
    </handler>
    
    <!--
    public synchronized HashMap<String,RoomClient> getClientListScope()
     -->
    <netRemoteCallHib name="getClientListScope" funcname="getClientListScope" 
                      remotecontext="$once{ canvas.thishib }" >   
        <handler name="ondata" args="value">
            <![CDATA[
                if ($debug) Debug.write("+++++++++++++++++ getClientListScope : ",value);
                
                for (var i in value) {
                    parent._users.addItem(value[i].firstname+','+value[i].lastname+' ['+value[i].username+']',value[i].publicSID);
                }
                
                parent._users.selectItemAt(0);
            
            ]]>
        </handler>  
    </netRemoteCallHib>
    
    <labelText labelid="911" x="2" y="22"/>
    
    <resetCombobox name="_users" x="2" y="42" width="$once{ parent.width-4 }"/>
    
    <simpleLabelButton labelid="61" width="100" x="$once{ parent.width - 105 }" y="$once{ parent.height - 26 }">
        <handler name="onclick">
            this.parent.close();
        </handler>
    </simpleLabelButton>    
    
    <simpleLabelButton labelid="60" width="100" x="$once{ parent.width - 210 }" y="$once{ parent.height - 26 }">
        <handler name="onclick">
            var valueCombobox = parent._users.getValue();
            if (this.parent.refObj.sendConfirmation(valueCombobox)) {
                this.parent.close();
            }
        </handler>
    </simpleLabelButton>   
    
</class>
 
<class name="interviewVideoBox" extends="view" width="322" height="281" bgcolor="0x000000">

    <attribute name="interviewPodId" value="0" type="number" />

    <method name="startInterView">
        if ($debug) Debug.write("startInterView :: ");
        var tx = this.getAttributeRelative("x",canvas);
        var ty = this.getAttributeRelative("y",canvas);
        canvas._videocontainer._videoviewcontent.showDevicePopUpInterview(false,this.interviewPodId,tx,ty,this.width,this.height);
    </method>

    <method name="sendConfirmation" args="publicSID">
        if ($debug) Debug.write("sendConfirmation :: ",publicSID);
        
        canvas.thishib.setBroadCastingFlag.publicSIDOfNewModerator = publicSID;
        canvas.thishib.setBroadCastingFlag.isAllowedToBroadCastAV = true;
        canvas.thishib.setBroadCastingFlag.interviewPodId = this.interviewPodId;
        canvas.thishib.setBroadCastingFlag.doCall(); 
        
        //this.sendMessageWithClientByPublicSID.publicSID = publicSID;
        //this.sendMessageWithClientByPublicSID.messageObject = new Object();
        //this.sendMessageWithClientByPublicSID.messageObject["message"] = "allowInterview";
        //this.sendMessageWithClientByPublicSID.messageObject["action"] = "showVideoDeviceSettings";
        //this.sendMessageWithClientByPublicSID.messageObject["interviewPodId"] = this.interviewPodId;
        //this.sendMessageWithClientByPublicSID.doCall();
        
        return true;
    </method>
    
    <!--
    public synchronized void sendMessageWithClientByPublicSID(Object message, String publicSID) 
     -->
    <netRemoteCallHib name="sendMessageWithClientByPublicSID" funcname="sendMessageWithClientByPublicSID" 
                      remotecontext="$once{ canvas.thishib }" >  
        <attribute name="messageObject" value="null" />
        <attribute name="publicSID" value="" type="string" />
        <netparam><method name="getValue">return parent.messageObject;</method></netparam>
        <netparam><method name="getValue">return parent.publicSID;</method></netparam>
        <handler name="ondata" args="value">
            <![CDATA[
                if ($debug) Debug.write("+sendMessageWithClientByPublicSID : ",value);
                
            ]]>
        </handler>  
    </netRemoteCallHib>
    
    <simpleLabelButton labelid="910" height="30" valign="middle" align="center"
               visible="${ ((canvas.ismoderator) ? true : ((canvas.isAllowedToDraw) ? true : false )) }">
        <handler name="onclick" args="refObj">
            new lz.interviewVideoChooseUser(canvas,{
                           isInterview:true,
                           x:this.getAttributeRelative("x",canvas)-10,
                           y:this.getAttributeRelative("y",canvas)-20,
                           width:this.width+20,
                           refObj:parent
                        });
        </handler>
    </simpleLabelButton>
        
    <!--
    <videoObjectPlayBroadcast name="_videoPlay" isInterview="true" visibility="hidden" 
                              width="$once{ parent.width }" height="$once{ parent.height }" />
     -->
    
</class>


</library>
