<?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="userContactsCalendarItem" extends="view" width="$once{ parent.width }" height="40" bgcolor="$once{ canvas.getThemeColor('mainBorderColor') }">
		
		<attribute name="tUserName" value="" type="string" />
		
		<attribute name="tUserId" value="-1" type="number" />
		
		<text text="$once{ parent.tUserName }" 
			width="$once{ parent.width - 60 }" multiline="true" height="40" />
		
	
		<miniIcons name="private_message_add" resource="private_message_add_rsc" width="16" height="16" 
                   y="20" x="$once{ parent.width - 60 }" showhandcursor="true">
	        <handler name="onclick">
	            new lz.newPrivateMessage(canvas,{
	                                x:200,y:120,
	                                refObj:null,
	                                minimizable:true,
	                                maximizable:true,
	                                userObject:null,
	                                isdragable:true,
	                                user_id:parent.tUserId,
	                                width:canvas.width-300,
	                                height:canvas.height-130,
	                                saveRefObj:this
	                            });
	        </handler>
	        <method name="saveNotification" args="roomBooked">
	        	parent.parent.parent.parent.onSaveNewMessage.sendEvent(roomBooked);
	        </method>
	        <labelTooltip labelid="1253" />
	    </miniIcons>
		
		<miniIcons resource="user_profile_rsc" width="16" height="16" 
	               y="20" x="$once{ parent.width - 40 }" showhandcursor="true">
	        <handler name="onclick">
	            new lz.viewUserProfileWindow(canvas,{
	                                userId:parent.tUserId
	                            });
	        </handler>
	        <labelTooltip labelid="1236" />
	    </miniIcons>
	    
	    <miniIcons resource="calendar_contact_calendar_rsc" width="16" height="16" 
	               y="20" x="$once{ parent.width - 20 }" showhandcursor="true">
	        <handler name="onclick">
	            parent.parent.parent.parent.selectContact(parent);
	        </handler>
	        <labelTooltip labelid="1449" />
	    </miniIcons>
	    
	</class>

	<class name="userContactsCalendar" extends="view" 
						bgcolor="$once{ canvas.getThemeColor('secondBorderColor') }">
		
		<event name="onSaveNewMessage" />
		
		<attribute name="selectedItem" value="null" />
		
		<handler name="oninit">
			this.getUserContactsWithShareCalendar.doCall();
		</handler>
		
		<netRemoteCallHib name="getUserContactsWithShareCalendar" funcname="userservice.getUserContactsWithShareCalendar" 
                          remotecontext="$once{ canvas.thishib }" >
            <netparam><method name="getValue">return canvas.sessionId;</method></netparam>
            <handler name="ondata" args="valueList">
                <![CDATA[
                    if ($debug) Debug.write("getUserContactsWithShareCalendar ",valueList);
                    for (var i=0;i<valueList.length;i++) {
                    	parent.addItem(valueList[i].owner.firstname + ' ' + valueList[i].owner.lastname,valueList[i].owner.user_id);
                    }
                ]]>
            </handler>
        </netRemoteCallHib>
        
        <method name="addItem" args="tUserName,tUserId">
        	new lz.userContactsCalendarItem(this._list.scrollContent,{
        						tUserName:tUserName,
        						tUserId:tUserId
        					});
        </method>
		
		<method name="selectContact" args="tSel">
			this.setAttribute("selectedItem",tSel);
		</method>
		
		<view name="_list" x="1" y="1" width="$once{ parent.width-1 }" height="${ parent.height-1 }" bgcolor="0xFFFFFF">
		
			<view name="scrollContent" layout="axis:y;spacing:1"  width="$once{ parent.width-10 }"/>
			
			<om_vscrollbar />
		
		</view>
		
	</class>

</library>