<!--
  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="addExternalAttendee" extends="labelExplorerBox" width="420" height="240"
	   closable="true" labelid="629" x="$once{ parent.width/2-this.width/2 + 10 }">
	
	<attribute name="refObj" value="null"/>
	<attribute name="parentSearch" value="null"/>
	
	<handler name="oninit">
		this._timeZone.selectItem(canvas.jNameTimeZone);
	</handler>
		
	<labelText labelid="630" y="24" x="2" />
	<customEdittext name="firstname" x="120" width="270" y="24" />
	
	<labelText labelid="631" y="54" x="2" />
	<customEdittext name="lastname" x="120" width="270" y="54" />
	
	<labelText labelid="632" y="84" x="2" />
	<customEdittext name="email" x="120" width="270" y="84">
		<handler name="ontext" args="t">
		<![CDATA[
			var singleAddress = t.indexOf(",") < 0;
			
			if (parent.firstname.enabled != singleAddress) {
				parent.firstname.setAttribute('enabled', singleAddress);
				parent.lastname.setAttribute('enabled', singleAddress);
			}
		]]>
		</handler>
	</customEdittext>
	
	<view resource="messagebox_info_rsc" x="6" y="114" 
		width="16" height="16" stretches="both" />
	<labelText labelid="1510" x="24" y="110" multiline="true" width="350" />
	
	<labelText labelid="1143" width="200" y="170" x="2" />
     <resetCombobox name="_timeZone" editable="false" y="170" width="270" x="120"
     			   fontsize="11" style="componentStyle">
     	<attribute name="selectionActive" value="false" type="boolean"/>
     	<labeldTextListItem datapath="timeZoneSet:/item" text="$path{ 'frontEndLabel/text()' }" 
            value="$path{ 'jname/text()' }" />
     </resetCombobox>  	
	
	<simpleLabelButton name="_ok" labelid="333" x="$once{ parent.width-220 }"
					   width="100" y="$once{ parent.height - 30 }" >
		<handler name="onclick">
		<![CDATA[
			var eml = parent.email["text"];
			//if ($debug) Debug.write("eml: ", eml);
			if (eml.indexOf(",") > -1) {
				var addresses = eml.split(",");
				for (var i = 0; i < addresses.length; ++i) {
					var first = "", email = "", last = "", addr = parent.replaceAll(parent.replaceAll(addresses[i], "'", ""), "\"", "");
					//if ($debug) Debug.write("addr: ", addr);
					var idx1 = addr.indexOf("<"), idx2 = addr.indexOf(">");
					if (idx1 > -1 && idx2 > -1 && idx2 > idx1) {
						email = parent.trim(addr.substring(idx1 + 1, idx2));
						var s = parent.trim(addr.substring(0, idx1));
						var idx = s.indexOf(" ");
						if (idx > -1) {
							first = s.substring(0, idx); 
							last = s.substring(idx + 1);
						} else {
							first = s;
						}
						//if ($debug) Debug.write("s, idx: ", s, idx);
					} else {
						email = addr;
					}
					parent.refObj.addListItem(0, first, last, email, 0, parent._timeZone.getValue());
					//if ($debug) Debug.write("[first, last, email]: ", addresses[i], idx1, idx2, first, last, email);
				}
			} else {
				parent.refObj.addListItem(
					0, 
					parent.firstname["text"], 
					parent.lastname["text"], 
					eml,
					0,
					parent._timeZone.getValue()
				);
				//if ($debug) Debug.write("_innerlist: ", parent.parent.parent.refObj.terminObjRef._liste._innerlist);
			}
			parent.firstname="";
			parent.lastname="";
			parent.email="";
			parent.close();
			if (parent.parentSearch != null) {
				parent.parentSearch.close();
			}
			//parent.parent.parent.refObj.close();
			//if ($debug) Debug.write("userId  search: ",parent.parent.parent.userId);
		]]>
		</handler>
	</simpleLabelButton>
	
	<simpleLabelButton  name="_cancel" labelid="25" x="$once{ parent.width-110 }"
					   width="100" y="$once{ parent.height - 30 }">
		<handler name="onclick">
			parent.close();
		</handler>
	</simpleLabelButton>
	
	<method name="trim" args="s">
	<![CDATA[
		var str = "" + s, begin = 0, end = str.length - 1;
		while (begin <= end && str.charCodeAt(begin) == 32) { ++begin; }
		while (end > begin && str.charCodeAt(end) == 32) { --end; }
		return str.substr(begin, end - begin + 1);
	]]>
	</method>
	
	<method name="replaceAll" args="s,f,r">
	<![CDATA[
		var str = s;
		while (str.indexOf(f) > -1) { str = str.replace(f, r); }
		return str;
	]]>
	</method>
	
</class>

</library>
