(function() {
 	var orig_onClick = Ext.Button.prototype.onClick;

	Ext.override(Ext.Button, {
		/*
		 * Fix issue that when the Button is pressed the focus is not moved
		 * away from the current input field. This is an issue which exists
		 * on some browsers (at least Firefox), while other browsers (Chrome)
		 * are safe.
		 */
		onClick : function(e)
		{
			// Copy the original event, during focus() and blur() the
			// 'e' will be changed to the input element that is being
			// blurred. Hence we create a copy which we will pass to
			// the original function.
			var origEvent = new Ext.EventObjectImpl(e);
			this.focus();

			orig_onClick.call(this, origEvent);

			// Ensure that we have remove the focus again to prevent
			// the button from remaining blurred. Note that the event
			// handler for the button might have destroyed the button
			// (e.g. the Ok or cancel button in a dialog which closes
			// the dialog).
			if (!this.isDestroyed) {
				this.blur();
			}
		},

		/* Override default ext.js template, which uses tables for buttons.
		 * This way buttons are easier to handle, and the code is much cleaner and leaner.
		 * The scheme is <div><div><em><button>
		 * The two containers are needed because Ext.JS applies various classes for icons, etc.
		 * The em element is used for applying the arrow of split buttons, and for making buttons unselectable.
		 */
		template:new Ext.Template(
			'<div id="{4}" class="x-btn {3}"><div class="{1}">',
			'<em class="{2}" class="x-unselectable" unselectable="on"><button type="{0}"></button></em>',
			'</div></div>')
	});
})();
(function() {
	/**
	 * @class Ext.Component
	 * @extends Ext.util.Observable
	 * <p>Base class for all Ext components.  All subclasses of Component may participate in the automated
	 * Ext component lifecycle of creation, rendering and destruction which is provided by the {@link Ext.Container Container} class.
	 * Components may be added to a Container through the {@link Ext.Container#items items} config option at the time the Container is created,
	 * or they may be added dynamically via the {@link Ext.Container#add add} method.</p>
	 * <p>The Component base class has built-in support for basic hide/show and enable/disable behavior.</p>
	 * <p>All Components are registered with the {@link Ext.ComponentMgr} on construction so that they can be referenced at any time via
	 * {@link Ext#getCmp}, passing the {@link #id}.</p>
	 * <p>All user-developed visual widgets that are required to participate in automated lifecycle and size management should subclass Component (or
	 * {@link Ext.BoxComponent} if managed box model handling is required, ie height and width management).</p>
	 * <p>See the <a href="http://extjs.com/learn/Tutorial:Creating_new_UI_controls">Creating new UI controls</a> tutorial for details on how
	 * and to either extend or augment ExtJs base classes to create custom Components.</p>
	 * <p>Every component has a specific xtype, which is its Ext-specific type name, along with methods for checking the
	 * xtype like {@link #getXType} and {@link #isXType}. This is the list of all valid xtypes:</p>
	 * <pre>
	xtype            Class
	-------------    ------------------
	box              {@link Ext.BoxComponent}
	button           {@link Ext.Button}
	buttongroup      {@link Ext.ButtonGroup}
	colorpalette     {@link Ext.ColorPalette}
	component        {@link Ext.Component}
	container        {@link Ext.Container}
	cycle            {@link Ext.CycleButton}
	dataview         {@link Ext.DataView}
	datepicker       {@link Ext.DatePicker}
	editor           {@link Ext.Editor}
	editorgrid       {@link Ext.grid.EditorGridPanel}
	flash            {@link Ext.FlashComponent}
	grid             {@link Ext.grid.GridPanel}
	listview         {@link Ext.ListView}
	multislider      {@link Ext.slider.MultiSlider}
	panel            {@link Ext.Panel}
	progress         {@link Ext.ProgressBar}
	propertygrid     {@link Ext.grid.PropertyGrid}
	slider           {@link Ext.slider.SingleSlider}
	spacer           {@link Ext.Spacer}
	splitbutton      {@link Ext.SplitButton}
	tabpanel         {@link Ext.TabPanel}
	treepanel        {@link Ext.tree.TreePanel}
	viewport         {@link Ext.ViewPort}
	window           {@link Ext.Window}

	Toolbar components
	---------------------------------------
	paging           {@link Ext.PagingToolbar}
	toolbar          {@link Ext.Toolbar}
	tbbutton         {@link Ext.Toolbar.Button}        (deprecated; use button)
	tbfill           {@link Ext.Toolbar.Fill}
	tbitem           {@link Ext.Toolbar.Item}
	tbseparator      {@link Ext.Toolbar.Separator}
	tbspacer         {@link Ext.Toolbar.Spacer}
	tbsplit          {@link Ext.Toolbar.SplitButton}   (deprecated; use splitbutton)
	tbtext           {@link Ext.Toolbar.TextItem}

	Menu components
	---------------------------------------
	menu             {@link Ext.menu.Menu}
	colormenu        {@link Ext.menu.ColorMenu}
	datemenu         {@link Ext.menu.DateMenu}
	menubaseitem     {@link Ext.menu.BaseItem}
	menucheckitem    {@link Ext.menu.CheckItem}
	menuitem         {@link Ext.menu.Item}
	menuseparator    {@link Ext.menu.Separator}
	menutextitem     {@link Ext.menu.TextItem}

	Form components
	---------------------------------------
	form             {@link Ext.form.FormPanel}
	checkbox         {@link Ext.form.Checkbox}
	checkboxgroup    {@link Ext.form.CheckboxGroup}
	combo            {@link Ext.form.ComboBox}
	compositefield   {@link Ext.form.CompositeField}
	datefield        {@link Ext.form.DateField}
	displayfield     {@link Ext.form.DisplayField}
	field            {@link Ext.form.Field}
	fieldset         {@link Ext.form.FieldSet}
	hidden           {@link Ext.form.Hidden}
	htmleditor       {@link Ext.form.HtmlEditor}
	label            {@link Ext.form.Label}
	numberfield      {@link Ext.form.NumberField}
	radio            {@link Ext.form.Radio}
	radiogroup       {@link Ext.form.RadioGroup}
	textarea         {@link Ext.form.TextArea}
	textfield        {@link Ext.form.TextField}
	timefield        {@link Ext.form.TimeField}
	trigger          {@link Ext.form.TriggerField}

	Chart components
	---------------------------------------
	chart            {@link Ext.chart.Chart}
	barchart         {@link Ext.chart.BarChart}
	cartesianchart   {@link Ext.chart.CartesianChart}
	columnchart      {@link Ext.chart.ColumnChart}
	linechart        {@link Ext.chart.LineChart}
	piechart         {@link Ext.chart.PieChart}

	Store xtypes
	---------------------------------------
	arraystore       {@link Ext.data.ArrayStore}
	directstore      {@link Ext.data.DirectStore}
	groupingstore    {@link Ext.data.GroupingStore}
	jsonstore        {@link Ext.data.JsonStore}
	simplestore      {@link Ext.data.SimpleStore}      (deprecated; use arraystore)
	store            {@link Ext.data.Store}
	xmlstore         {@link Ext.data.XmlStore}
	</pre>
	* @constructor
	* @param {Ext.Element/String/Object} config The configuration options may be specified as either:
	* <div class="mdetail-params"><ul>
	* <li><b>an element</b> :
	* <p class="sub-desc">it is set as the internal element and its id used as the component id</p></li>
	* <li><b>a string</b> :
	* <p class="sub-desc">it is assumed to be the id of an existing element and is used as the component id</p></li>
	* <li><b>anything else</b> :
	* <p class="sub-desc">it is assumed to be a standard config object and is applied to the component</p></li>
	* </ul></div>
	*/
	var orig_initComponent = Ext.Component.prototype.initComponent;
	var orig_destroy = Ext.Component.prototype.destroy;
	Ext.override(Ext.Component, {
		// By default stateful is 'undefined' however a component
		// is stateful when this property !== false. Hence we have
		// to force-disable the statefulness of components.
		stateful : false,

		/**
		 * @cfg {Boolean} statefulRelativeDimensions True if the 'width' and 'height' of the {@link #field} must be
		 * converted to relative values before saving it to the settings. This will ensure the dimensions
		 * of the field will always depend on the current size of the {@link Ext#getBody body}.
		 * This option is only used when the {@link Zarafa.core.data.SettingsStateProvider SettingsStateProvider} is
		 * used in the {@link Ext.state.Manager}.
		 */
		statefulRelativeDimensions : true,

		/**
		 * @cfg {String} statefulName The unique name for this component by which the {@link #getState state}
		 * must be saved into the {@link Zarafa.settings.SettingsModel settings}.
		 * This option is only used when the {@link Zarafa.core.data.SettingsStateProvider SettingsStateProvider} is
		 * used in the {@link Ext.state.Manager}.
		 */
		statefulName : undefined,

		// Override to generate a stateId and register the Component to the Ext.state.Manager
		initComponent : function()
		{
			if (this.stateful !== false) {
				if (!this.stateId) {
					this.stateId = Ext.id(null, 'state-');
				}

				Ext.state.Manager.register(this);
			}

			orig_initComponent.apply(this, arguments);
		},

		/**
		 * Obtain the path in which the {@link #getState state} must be saved.
		 * This option is only used when the {@link Zarafa.core.data.SettingsStateProvider SettingsStateProvider} is
		 * used in the {@link Ext.state.Manager}. This returns {@link #statefulName} if provided, or else generates
		 * a custom name.
		 * @return {String} The unique name for this component by which the {@link #getState state} must be saved. 
		 */
		getStateName : function()
		{
			var name = this.statefulName;
			if (!name) {
				name = this.getXType().match(/(?:zarafa\.)?(.*)/)[1];
			}

			return name;
		},

		// Override the destroy function of the Ext.Component,
		// each component might have plugins installed on it.
		// Those plugins might be Ext.util.Observables and thus
		// need to be properly destroyed when the component is
		// destroyed. Otherwise references to the plugin will
		// remain and will still refer to the destroyed field.
		destroy : function()
		{
			if (this.plugins) {
				for (var key in this.plugins) {
					var plugin = this.plugins[key];
					if (plugin instanceof Ext.util.Observable) {
						plugin.purgeListeners();
					}
				}
			}

			if (this.stateful !== false) {
				Ext.state.Manager.unregister(this);
			}

			orig_destroy.apply(this, arguments);
		}
	});
})();
(function() {
	/*
	 * We must set the default value of the bufferResize property
	 * to something more appropriate to our needs.
	 */
	Ext.override(Ext.Container, {
		bufferResize : false
	});
})();
(function() {
	/*
	 * Override Ext.DataView to provide the ability to insert extra item in dropdown-ist.
	 * This extra item can be another HTML element for which we can listen click event.
	 */
	var orig_onClick = Ext.DataView.prototype.onClick;
	var orig_initComponent = Ext.DataView.prototype.initComponent;

	Ext.override(Ext.DataView, {
		/*
		 * Override to add events for {@link Zarafa.common.ui.BoxField#extraItemSelector extraItemSelector} element.
		 * @override
		 */
		initComponent : function()
		{
			orig_initComponent.apply(this, arguments);

			this.addEvents(
				/**
				 * @event extraitemclick
				 * Fires when an extra template node is clicked.
				 * @param {Ext.DataView} Current {@link Ext.DataView} instance.
				 * @param {Number} index The index of the target node
				 * @param {HTMLElement} node The target node
				 * @param {Ext.EventObject} e The raw event object
				 */
				"extraitemclick",
				/**
				 * @event beforeextraitemclick
				 * Fires before a click is processed. Returns false to cancel the default action.
				 * @param {Ext.DataView} this
				 * @param {Number} index The index of the target node
				 * @param {HTMLElement} node The target node
				 * @param {Ext.EventObject} e The raw event object
				 */
				"beforeextraitemclick"
			);
		},

		/*
		 * Override to fire {@link #extraitemclick} event while click is performed
		 * on {@link Zarafa.common.ui.BoxField#extraItemSelector extraItemSelector} element.
		 * @param {Ext.EventObject} e The event object
		 * @private
		 * @override
		 */
		onClick : function(e)
		{
			var extraItem = false;
			var index;

			if (this.extraItemSelector) {
				extraItem = e.getTarget(this.extraItemSelector, this.getTemplateTarget());
			}

			if (extraItem){
				index = this.indexOf(extraItem);
				if (this.onExtraItemClick(extraItem, index, e) !== false) {
					this.fireEvent("extraitemclick", this, index, extraItem, e);
				}
			} else {
				orig_onClick.apply(this, arguments);
			}
		},

		/*
		 * Fires {@link #beforeextraitemclick} event for
		 * {@link Zarafa.common.ui.BoxField#extraItemSelector extraItemSelector} element.
		 * @param {HTMLElement} node The target node
		 * @param {Number} index The index of the target node
		 * @param {Ext.EventObject} e The event object
		 * @return {Boolean} True if action is a success, false to cancel the default action.
		 * @private
		 * @override
		 */
		onExtraItemClick : function(item, index, e)
		{
			if(this.fireEvent("beforeextraitemclick", this, index, item, e) === false){
				return false;
			}

			return true;
		}
	});
})();
(function() {
	/**
	 * @class Ext.Element
	 * <p>Encapsulates a DOM element, adding simple DOM manipulation facilities, normalizing for browser differences.</p>
	 * <p>All instances of this class inherit the methods of {@link Ext.Fx} making visual effects easily available to all DOM elements.</p>
	 * <p>Note that the events documented in this class are not Ext events, they encapsulate browser events. To
	 * access the underlying browser event, see {@link Ext.EventObject#browserEvent}. Some older
	 * browsers may not support the full range of events. Which events are supported is beyond the control of ExtJs.</p>
	 * Usage:<br>
	<pre><code>
	// by id
	var el = Ext.get('my-div');

	// by DOM element reference
	var el = Ext.get(myDivElement);
	</code></pre>
	 * <b>Animations</b><br />
	 * <p>When an element is manipulated, by default there is no animation.</p>
	 * <pre><code>
	var el = Ext.get('my-div');

	// no animation
	el.setWidth(100);
	 * </code></pre>
	 * <p>Many of the functions for manipulating an element have an optional 'animate' parameter.  This
	 * parameter can be specified as boolean (<tt>true</tt>) for default animation effects.</p>
	 * <pre><code>
	// default animation
	el.setWidth(100, true);
	 * </code></pre>
	 *
	 * <p>To configure the effects, an object literal with animation options to use as the Element animation
	 * configuration object can also be specified. Note that the supported Element animation configuration
	 * options are a subset of the {@link Ext.Fx} animation options specific to Fx effects.  The supported
	 * Element animation configuration options are:</p>
	<pre>
	Option    Default   Description
	--------- --------  ---------------------------------------------
	{@link Ext.Fx#duration duration}  .35       The duration of the animation in seconds
	{@link Ext.Fx#easing easing}    easeOut   The easing method
	{@link Ext.Fx#callback callback}  none      A function to execute when the anim completes
	{@link Ext.Fx#scope scope}     this      The scope (this) of the callback function
	</pre>
	 *
	 * <pre><code>
	// Element animation options object
	var opt = {
		{@link Ext.Fx#duration duration}: 1,
		{@link Ext.Fx#easing easing}: 'elasticIn',
		{@link Ext.Fx#callback callback}: this.foo,
		{@link Ext.Fx#scope scope}: this
	};
	// animation with some options set
	el.setWidth(100, opt);
	 * </code></pre>
	 * <p>The Element animation object being used for the animation will be set on the options
	 * object as 'anim', which allows you to stop or manipulate the animation. Here is an example:</p>
	 * <pre><code>
	// using the 'anim' property to get the Anim object
	if(opt.anim.isAnimated()){
		opt.anim.stop();
	}
	 * </code></pre>
	 * <p>Also see the <tt>{@link #animate}</tt> method for another animation technique.</p>
	 * <p><b> Composite (Collections of) Elements</b></p>
	 * <p>For working with collections of Elements, see {@link Ext.CompositeElement}</p>
	 * @constructor Create a new Element directly.
	 * @param {String/HTMLElement} element
	 * @param {Boolean} forceNew (optional) By default the constructor checks to see if there is already an instance of this element in the cache and if there is it returns the same instance. This will skip that check (useful for extending this class).
	 */
	Ext.Element.addMethods({

		/**
		 * Test if size has a unit, otherwise appends the default
		 *
		 * FIX: Overridden Ext.Element to fix an issue that calling
		 * Element.addUnits(0/0) would return the string 'NaNpx'
		 * instead we return an empty string (which ExtJs already
		 * did when size was an empty string or undefined.
		 *
		 * @param {String} size The size where the units will be postfixed
		 * @return {String} The size plus the optional size unit postfixed
		 * @private
		 */
		addUnits : function(size)
		{
			if (Ext.isEmpty(size) || size == 'auto') {
				size = size || '';
			} else if (isNaN(size)) {
				size = '';
			} else if (!/\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i.test(size)) {
				size = size + (this.defaultUnit || 'px');
			}

			return size;
		},

		/**
		 * Stops the specified event(s) from bubbling and optionally prevents the default action
		 * @param {String/Array} eventName an event / array of events to stop from bubbling
		 * @param {Boolean} preventDefault (optional) true to prevent the default action too
		 * @return {Ext.Element} this
		 * @override
		 */
		swallowEvent : function(eventName, preventDefault)
		{
			var me = this;
			var fn = (preventDefault === true) ? this.swallowEventHandlerPreventDefault : this.swallowEventHandler;

			if(Ext.isArray(eventName)){
				Ext.each(eventName, function(e) {
					me.on(e, fn, this);
				});
				return me;
			}
			me.on(eventName, fn, this);
			return me;
		},

		/**
		 * Event handler for {@link #swallowEvent} which is used
		 * to swallow a particular event. This will only call
		 * {@link Ext.EventObject#stopPropagation}. For preventing
		 * the {@link Ext.EventObject#preventDefault} then
		 * {@link #swallowEventHandlerPreventDefault} should be used instead.
		 * @param {Ext.EventObject} e The event object
		 * @private
		 */
		swallowEventHandler : function(e)
		{
			e.stopPropagation();
		},

		/**
		 * Event handler for {@link #swallowEvent} which is used
		 * to swallow a particular event. This will call
		 * {@link Ext.EventObject#stopPropagation} and
		 * {@link Ext.EventObject#preventDefault}. If the latter
		 * call is unwanted, the {@link #swallowEventHandler} should be
		 * used instead.
		 * @param {Ext.EventObject} e The event object
		 * @private
		 */
		swallowEventHandlerPreventDefault : function(e)
		{
			e.stopPropagation();
			e.preventDefault();
		},

		/**
		 * Opposite of {@link #swallowEvent}, this will re-enable the
		 * given event (or events).
		 * @param {String/Array} eventName an event / array of events to start bubbling
		 * @param {Boolean} preventDefault (optional) true if the default action was also prevented
		 * @return {Ext.Element} this
		 */
		spitOutEvent : function(eventName, preventDefault)
		{
			var me = this;
			var fn = (preventDefault === true) ? this.swallowEventHandlerPreventDefault : this.swallowEventHandler;
			if(Ext.isArray(eventName)){
				Ext.each(eventName, function(e) {
					me.un(e, fn, this);
				});
				return me;
			}
			me.un(eventName, fn, this);
			return me;
		},

		/**
		 * Opposite of {@link #unselectable}, enables text selection for this element (normalized across browsers)
		 * @return {Ext.Element} this
		 */
		selectable : function()
		{
			this.dom.unselectable = 'off';
			return this.spitOutEvent('selectstart', true).
					removeClass('x-unselectable');
		},

		/**
		 * Clear all CSS classes which were applied to the DOM tree
		 */
		clearClass : function()
		{
			this.dom.className = '';
		},

		/**
		 * Fires specified event for {@link Ext.Element element}.
		 * @param {String} e The event name
		 */
		fireEvent : function(eventName, originalEvent)
		{
			var HTMLEvts = /^(scroll|resize|load|unload|abort|error)$/,
				mouseEvts = /^(click|dblclick|mousedown|mouseup|mouseover|mouseout|contextmenu)$/,
				UIEvts = /^(focus|blur|select|change|reset|keypress|keydown|keyup)$/,
				WheelEvts = /^(wheel)$/,
				onPref = /^on/;

			eventName = eventName.toLowerCase();
			eventName.replace(onPref, '');
			var evt;
			if (mouseEvts.test(eventName)) {
				evt = document.createEvent("MouseEvents");
				evt.initMouseEvent(eventName, true, true, window, (eventName=='dblclick')?2:1, originalEvent.screenX, originalEvent.screenY, originalEvent.clientX, originalEvent.clientY, originalEvent.ctrlKey, originalEvent.altKey, originalEvent.shiftKey, originalEvent.metaKey, 0, null);
			} else if (UIEvts.test(eventName)) {
				evt = document.createEvent("UIEvents");
				evt.initUIEvent(eventName, true, true, window, 0);
			} else if (HTMLEvts.test(eventName)) {
				evt = document.createEvent("HTMLEvents");
				evt.initEvent(eventName, true, true);
			} else if (WheelEvts.test(eventName)) {
				evt = new WheelEvent('wheel', originalEvent);
			}
			if (evt) {
				this.dom.dispatchEvent(evt);
			}
		},

		/**
		 * Gets the x,y coordinates to align this element with another element. See {@link #alignTo} for more info on the
		 * supported position values.
		 * @param {Mixed} element The element to align to.
		 * @param {String} position (optional, defaults to "tl-bl?") The position to align to.
		 * @param {Array} offsets (optional) Offset the positioning by [x, y]
		 * @return {Array} [x, y]
		 */
		getAlignToXY : function(el, p, o){
			el = Ext.get(el);

			if(!el || !el.dom){
				throw "Element.alignToXY with an element that doesn't exist";
			}

			o = o || [0,0];
			p = (!p || p == "?" ? "tl-bl?" : (!(/-/).test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();
			// Get document belongs to respective browser window to calculate positions of menu to prevent the overflow
			var browserWindow = Zarafa.core.BrowserWindowMgr.getOwnerWindow(el);
			var me = this,
					d = me.dom,
					a1,
					a2,
					x,
					y,
			//constrain the aligned el to viewport if necessary
					w,
					h,
					r,
					dw = browserWindow.innerWidth -10, // 10px of margin for ie
					dh = browserWindow.innerHeight - 10, // 10px of margin for ie
					p1y,
					p1x,
					p2y,
					p2x,
					swapY,
					swapX,
					doc = browserWindow.document,
					docElement = doc.documentElement,
					docBody = doc.body,
					scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,
					scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,
					c = false, //constrain to viewport
					p1 = "",
					p2 = "",
					m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);

			if(!m){
				throw "Element.alignTo with an invalid alignment " + p;
			}

			p1 = m[1];
			p2 = m[2];
			c = !!m[3];

			//Subtract the aligned el's internal xy from the target's offset xy
			//plus custom offset to get the aligned el's new offset xy
			a1 = me.getAnchorXY(p1, true);
			a2 = el.getAnchorXY(p2, false);

			x = a2[0] - a1[0] + o[0];
			y = a2[1] - a1[1] + o[1];

			if(c){
				w = me.getWidth();
				h = me.getHeight();
				r = el.getRegion();
				//If we are at a viewport boundary and the aligned el is anchored on a target border that is
				//perpendicular to the vp border, allow the aligned el to slide on that border,
				//otherwise swap the aligned el to the opposite border of the target.
				p1y = p1.charAt(0);
				p1x = p1.charAt(p1.length-1);
				p2y = p2.charAt(0);
				p2x = p2.charAt(p2.length-1);
				swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
				swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));


				if (x + w > dw + scrollX) {
					x = swapX ? r.left-w : dw+scrollX-w;
				}
				if (x < scrollX) {
					x = swapX ? r.right : scrollX;
				}
				if (y + h > dh + scrollY) {
					y = swapY ? r.top-h : dh+scrollY-h;
				}
				if (y < scrollY){
					y = swapY ? r.bottom : scrollY;
				}
			}
			return [x,y];
		},

		// private ==>  used outside of core
		adjustForConstraints : function(xy, parent, offsets){
			// Using currently active browser window in case if parent is undefined
			var browserWindow = Zarafa.core.BrowserWindowMgr.getActive();
			return this.getConstrainToXY(parent || browserWindow.document, false, offsets, xy) ||  xy;
		},

		// private ==>  used outside of core
		getConstrainToXY : function(el, local, offsets, proposedXY){
			var os = {top:0, left:0, bottom:0, right: 0};

			return function(el, local, offsets, proposedXY){
				// Using currently active browser window for size and position related calculations
				var browserWindow = Zarafa.core.BrowserWindowMgr.getActive();
				el = Ext.get(el);
				offsets = offsets ? Ext.applyIf(offsets, os) : os;

				var vw, vh, vx = 0, vy = 0;
				if(el.dom == browserWindow.document.body || el.dom == browserWindow.document){
					vw = browserWindow.innerWidth;
					vh = browserWindow.innerHeight;
				}else{
					vw = el.dom.clientWidth;
					vh = el.dom.clientHeight;
					if(!local){
						var vxy = el.getXY();
						vx = vxy[0];
						vy = vxy[1];
					}
				}

				var s = el.getScroll();

				vx += offsets.left + s.left ? s.left : 0;
				vy += offsets.top + s.top ? s.top : 0 ;

				vw -= offsets.right ? offsets.right : 0;
				vh -= offsets.bottom ? offsets.bottom : 0;

				var vr = vx + vw,
						vb = vy + vh,
						xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]),
						x = xy[0], y = xy[1],
						offset = this.getConstrainOffset(),
						w = this.dom.offsetWidth + offset,
						h = this.dom.offsetHeight + offset;

				// only move it if it needs it
				var moved = false;

				// first validate right/bottom
				if((x + w) > vr){
					x = vr - w;
					moved = true;
				}
				if((y + h) > vb){
					y = vb - h;
					moved = true;
				}
				// then make sure top/left isn't negative
				if(x < vx){
					x = vx;
					moved = true;
				}
				if(y < vy){
					y = vy;
					moved = true;
				}
				return moved ? [x, y] : false;
			};
		}()
	});

	var orig_get = Ext.Element.get;

	Ext.override(Ext.Element, {
		/**
		 * Override get to consider the active browser window while retrieving {@link Ext.Element} objects from the given HTMLElement.
		 * @param {HTMLElement} el The HTMLElement which needs to be wrapped into {@link Ext.Element}
		 * @return {Ext.Element} The Element object (or null if no matching element was found)
		 */
		get : function(el) {
			var getResult = null;
			var activeBrowserWindow = Zarafa.core.BrowserWindowMgr.getActive();

			// First, find the element in active browser window if the active window is not the main webapp window
			if (Ext.isDefined(activeBrowserWindow) && activeBrowserWindow.name !== 'mainBrowserWindow' && typeof el === "string") {
				var respectiveElement = activeBrowserWindow.document.getElementById(el);
				// Wrap the element only if it is found
				getResult = respectiveElement ? new Ext.Element(respectiveElement) : respectiveElement;
			}

			// Find the element in webapp main window
			if(getResult === null) {
				getResult = orig_get.apply(this, arguments);
			}

			// If the element is still not found, Try to find the same in all the available browser windows
			if (getResult === null && typeof el === "string") {
				var browserWindows = Zarafa.core.BrowserWindowMgr.browserWindows;
				browserWindows.each(function(browserWindow){
					if(Ext.isDefined(browserWindow) && browserWindow.name !== 'mainBrowserWindow' && browserWindow !== activeBrowserWindow) {
						// If element is found in browser window then return ext element
						var element = browserWindow.document.getElementById(el);
						if (element) {
							getResult = new Ext.Element(element);
							return false;
						}
					}
				});
			} else {
				var browserWindows = Zarafa.core.BrowserWindowMgr.browserWindows;
				if(Ext.isDefined(browserWindows)) {
					browserWindows.each(function(browserWindow) {
						if(browserWindow.document === el) {
							// create a bogus element object representing the document object
							var f = function(){};
							f.prototype = Ext.Element.prototype;
							getResult = new f();
							getResult.dom = browserWindow.document;
							return;
						}
					});
				}
			}

			return getResult;
		}
	});

	// Expose overridden method to Ext global object
	Ext.get = Ext.Element.prototype.get;


	// Overriding this method because 
	// While mousedown event handler call it will get XY posstion of clickable area 
	// and then it will get style of particular posstion.
	// So, getStyle method will use active browser window instead of main window.
	Ext.Element.addMethods(function() {
		// local style camelizing for speed
		var supports = Ext.supports,
			propCache = {},
			camelRe = /(-[a-z])/gi,
			view = document.defaultView,
			opacityRe = /alpha\(opacity=(.*)\)/i;

		// private
		function camelFn(m, a) {
			return a.charAt(1).toUpperCase();
		}

		function chkCache(prop) {
			return propCache[prop] || (propCache[prop] = prop == 'float' ? (supports.cssFloat ? 'cssFloat' : 'styleFloat') : prop.replace(camelRe, camelFn));
		}

		return {
			/**
			 * Normalizes currentStyle and computedStyle.
			 * @param {String} property The style property whose value is returned.
			 * @return {String} The current value of the style property for this element.
			 */
			getStyle: function () {
				return view && view.getComputedStyle ?
						function (prop) {
							var el = this.dom,
									v,
									cs,
									out,
									display;

							if (el == Zarafa.core.BrowserWindowMgr.getActive().document) {
								return null;
							}
							prop = chkCache(prop);
							out = (v = el.style[prop]) ? v :
									(cs = view.getComputedStyle(el, "")) ? cs[prop] : null;

							// Ignore cases when the margin is correctly reported as 0, the bug only shows
							// numbers larger.
							if (prop == 'marginRight' && out != '0px' && !supports.correctRightMargin) {
								display = el.style.display;
								el.style.display = 'inline-block';
								out = view.getComputedStyle(el, '').marginRight;
								el.style.display = display;
							}

							if (prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.correctTransparentColor) {
								out = 'transparent';
							}
							return out;
						} :
						function (prop) {
							var el = this.dom,
									m,
									cs;

							if (el == document) return null;
							if (prop == 'opacity') {
								if (el.style.filter.match) {
									if (m = el.style.filter.match(opacityRe)) {
										var fv = parseFloat(m[1]);
										if (!isNaN(fv)) {
											return fv ? fv / 100 : 0;
										}
									}
								}
								return 1;
							}
							prop = chkCache(prop);
							return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
						};
			}(),

			/**
			 * Wrapper for setting style properties, also takes single object parameter of multiple styles.
			 * @param {String/Object} property The style property to be set, or an object of multiple styles.
			 * @param {String} value (optional) The value to apply to the given property, or null if an object was passed.
			 * @return {Ext.Element} this
			 */
			setStyle: function (prop, value) {
				var tmp, style;

				if (typeof prop != 'object') {
					tmp = {};
					tmp[prop] = value;
					prop = tmp;
				}
				for (style in prop) {
					value = prop[style];
					style == 'opacity' ?
							this.setOpacity(value) :
							this.dom.style[chkCache(style)] = value;
				}
				return this;
			}
		}
	}());
})();
(function() {
	/*
	 * Extend the EventObjectImp with additional keycodes.
	 */
	Ext.apply(Ext.EventObjectImpl.prototype, {
		SEMI_COLON : 186,
		EQUAL_SIGN : 187,
		COMMA : 188,
		DASH : 189,
		PERIOD : 190,
		FORWARD_SLASH : 191,
		OPEN_BRACKET : 219,
		BACK_SLASH : 220,
		CLOSE_BRACKET : 221,
		SINGLE_QUOTE : 222
	});

	var orig_setEvent = Ext.EventObject.setEvent;

	/*
	 * We override this function because we want different behavior for the
	 * metaKey than Ext. Ext sets the ctrlKey to true when the metaKey is
	 * pressed. On OSX we want the CMD key (metaKey) to act as the ctrlKey
	 * and the real ctrlKey not. On Windows/Linux we don't want the metaKey to
	 * behave like the ctrlKey.
	 *
	 * @param {Event} e The Browser event object
	 *
	 * @return {Ext.EventObject} The normalized event object
	 */
	Ext.EventObject.setEvent = function(e)
	{
		e = orig_setEvent.call(this, e);

		if ( Ext.isMac && e.ctrlKey && !e.browserEvent.metaKey ){
			e.ctrlKey = false;
		}
		if ( !Ext.isMac ){
			e.ctrlKey = e.browserEvent.ctrlKey || false;
		}

		return e;
	};
})();
Ext.namespace('Ext.MessageBox');
 /**
 * Override the MessageBox singleton provided by ExtJS library to
 * avoid using static/local variables.
 * Making this as a proper class with converting all the local
 * variables into properties and config options.
 * 
 * @class Ext.MessageBox
 * <p>Utility class for generating different styles of message boxes.  The alias Ext.Msg can also be used.<p/>
 * <p>Note that the MessageBox is asynchronous.  Unlike a regular JavaScript <code>alert</code> (which will halt
 * browser execution), showing a MessageBox will not cause the code to stop.  For this reason, if you have code
 * that should only run <em>after</em> some user feedback from the MessageBox, you must use a callback function
 * (see the <code>function</code> parameter for {@link #show} for more details).</p>
 * <p>Example usage:</p>
 *<pre><code>
// Basic alert:
Ext.Msg.alert('Status', 'Changes saved successfully.');

// Prompt for user data and process the result using a callback:
Ext.Msg.prompt('Name', 'Please enter your name:', function(btn, text){
	if (btn == 'ok'){
		// process text value and close...
	}
});

// Show a dialog using config this.options:
Ext.Msg.show({
   title:'Save Changes?',
   msg: 'You are closing a tab that has unsaved changes. Would you like to save your changes?',
   buttons: Ext.Msg.YESNOCANCEL,
   fn: processResult,
   animEl: 'elId',
   icon: Ext.MessageBox.QUESTION
});
</code></pre>
 * 
 */
Ext.MessageBox = Ext.extend(Object, {
	/**
	 * Button config that displays a single OK button
	 * @type Object
	 */
	OK : undefined,
	/**
	 * Button config that displays a single Cancel button
	 * @type Object
	 */
	CANCEL : undefined,
	/**
	 * Button config that displays OK and Cancel buttons
	 * @type Object
	 */
	OKCANCEL : undefined,
	/**
	 * Button config that displays Yes and No buttons
	 * @type Object
	 */
	YESNO : undefined,
	/**
	 * Button config that displays Yes, No and Cancel buttons
	 * @type Object
	 */
	YESNOCANCEL : undefined,
	/**
	 * The CSS class that provides the INFO icon image
	 * @type String
	 */
	INFO : 'ext-mb-info',
	/**
	 * The CSS class that provides the WARNING icon image
	 * @type String
	 */
	WARNING : 'ext-mb-warning',
	/**
	 * The CSS class that provides the QUESTION icon image
	 * @type String
	 */
	QUESTION : 'ext-mb-question',
	/**
	 * The CSS class that provides the ERROR icon image
	 * @type String
	 */
	ERROR : 'ext-mb-error',

	/**
	 * The default height in pixels of the message box's multiline textarea if displayed (defaults to 75)
	 * @type Number
	 */
	defaultTextHeight : 75,
	/**
	 * The maximum width in pixels of the message box (defaults to 600)
	 * @type Number
	 */
	maxWidth : 600,
	/**
	 * The minimum width in pixels of the message box (defaults to 100)
	 * @type Number
	 */
	minWidth : 100,
	/**
	 * The minimum width in pixels of the message box if it is a progress-style dialog.  This is useful
	 * for setting a different minimum width than text-only dialogs may need (defaults to 250).
	 * @type Number
	 */
	minProgressWidth : 250,
	/**
	 * The minimum width in pixels of the message box if it is a prompt dialog.  This is useful
	 * for setting a different minimum width than text-only dialogs may need (defaults to 250).
	 * @type Number
	 */
	minPromptWidth: 250,
	/**
	 * An object containing the default button text strings that can be overriden for localized language support.
	 * Supported properties are: ok, cancel, yes and no.  Generally you should include a locale-specific
	 * resource file for handling language support across the framework.
	 * Customize the default text like so: Ext.MessageBox.buttonText.yes = "oui"; //french
	 * @type Object
	 */
	buttonText : undefined,

	/**
	 * Array which have list of {@Link Ext.MessageBox} properties which should be unique for all browser window
	 * @type Array
	 */
	browserWindowsMessageBoxProps : [
		'dlg',
		'opt',
		'mask',
		'msgEl',
		'buttons',
		'textboxEl',
		'textareaEl',
		'progressBar',
		'iconEl',
		'iconCls'
	],

	/**
	 * The list of registered browser window. It contains object which will hold {@Link Ext.MessageBox.browserWindowsMessageBoxProps props}
	 * which should be unique for all browser window
	 * @property
	 * @type Ext.util.MixedCollection
	 * @private
	 */
	browserWindowsMessageBox : undefined,

	dlg : undefined,
	opt : undefined,
	mask : undefined,
	waitTimer : undefined,
	bodyEl : undefined,
	msgEl : undefined,
	textboxEl : undefined,
	textareaEl : undefined,
	progressBar : undefined,
	pp : undefined, 
	iconEl : undefined,
	spacerEl : undefined,
	buttons : undefined,
	activeTextEl : undefined,
	bwidth : undefined,
	bufferIcon : '',
	iconCls : '',
	buttonNames : ['ok', 'yes', 'no', 'cancel'],
	activeWindowName : undefined,

	constructor : function(config)
	{
		config = config || {};
		this.OK = {ok:true};
		this.CANCEL = {cancel:true};
		this.OKCANCEL = {ok:true, cancel:true};
		this.YESNO = {yes:true, no:true};
		this.YESNOCANCEL = {yes:true, no:true, cancel:true};
		this.buttonText = {
			ok : "OK",
			cancel : "Cancel",
			yes : "Yes",
			no : "No"
		};
		this.browserWindowsMessageBox = new Ext.util.MixedCollection();
	},

	// private
	handleButton : function(button){
		var activeWindow = Zarafa.core.BrowserWindowMgr.getActive();
		this.buttons[button].blur();
		if(this.dlg.isVisible()){
			this.dlg.hide();
			this.handleHide();
			Ext.callback(this.opt.fn, this.opt.scope || activeWindow, [button, this.activeTextEl.dom.value, this.opt], 1);
		}
	},

	// private
	handleHide : function(){
		if(this.opt && this.opt.cls){
			this.dlg.el.removeClass(this.opt.cls);
		}
		this.progressBar.reset();        
	},

	// private
	handleEsc : function(d, k, e){
		if(this.opt && this.opt.closable !== false){
			this.dlg.hide();
			this.handleHide();
		}
		if(e){
			e.stopEvent();
		}
	},

	// private
	updateButtons : function(b){
		var width = 0,
			cfg;
		if(!b){
			Ext.each(this.buttonNames, function(name){
				this.buttons[name].hide();
			}, this);
			return width;
		}
		this.dlg.footer.dom.style.display = '';
		Ext.iterate(this.buttons, function(name, btn){
			cfg = b[name];
			if(cfg){
				btn.show();
				btn.setText(Ext.isString(cfg) ? cfg : Ext.MessageBox.buttonText[name]);
				width += btn.getEl().getWidth() + 15;
			}else{
				btn.hide();
			}
		});
		return width;
	},


	/**
	 * Returns a reference to the underlying {@link Ext.Window} element
	 * @return {Ext.Window} The window
	 */
	getDialog : function(titleText){
		if(!this.dlg){
			var btns = [];
			
			this.buttons = {};
			Ext.each(this.buttonNames, function(name){
				btns.push(this.buttons[name] = new Ext.Button({
					text: this.buttonText[name],
					handler: this.handleButton.createDelegate(this, [name]),
					hideMode: 'offsets'
				}));
			}, this);
			this.dlg = new Ext.Window({
				autoCreate : true,
				title:titleText,
				resizable:false,
				constrain:true,
				constrainHeader:true,
				minimizable : false,
				maximizable : false,
				stateful: false,
				modal: true,
				shim:true,
				buttonAlign:"center",
				width:400,
				height:100,
				minHeight: 80,
				plain:true,
				footer:true,
				closable:true,
				close : function(){
					if(this.opt && this.opt.buttons && this.opt.buttons.no && !this.opt.buttons.cancel){
						this.handleButton("no");
					}else{
						this.handleButton("cancel");
					}
				}.createDelegate(this),
				fbar: new Ext.Toolbar({
					items: btns,
					enableOverflow: false
				})
			});
			// Get proper browser window to render the message box into body element of the same.
			var activeWindow = Zarafa.core.BrowserWindowMgr.getActive();
			this.dlg.render(activeWindow.document.body);
			this.dlg.getEl().addClass('x-window-dlg');
			this.mask = this.dlg.mask;
			this.bodyEl = this.dlg.body.createChild({
				html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><div class="ext-mb-fix-cursor"><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div></div>'
			});
			this.iconEl = Ext.get(this.bodyEl.dom.firstChild);
			var contentEl = this.bodyEl.dom.childNodes[1];
			this.msgEl = Ext.get(contentEl.firstChild);
			this.textboxEl = Ext.get(contentEl.childNodes[2].firstChild);
			this.textboxEl.enableDisplayMode();
			this.textboxEl.addKeyListener([10,13], function(){
				if(this.dlg.isVisible() && this.opt && this.opt.buttons){
					if(this.opt.buttons.ok){
						this.handleButton("ok");
					}else if(this.opt.buttons.yes){
						this.handleButton("yes");
					}
				}
			}, this);
			this.textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);
			this.textareaEl.enableDisplayMode();
			this.progressBar = new Ext.ProgressBar({
				renderTo:this.bodyEl
			});
			this.bodyEl.createChild({cls:'x-clear'});

			/**
			 * register browser window with the object of {@Link Ext.MessageBox.browserWindowsMessageBoxProps props}
			 * which should be unique for all browser window.
			 */
			this.browserWindowsMessageBox.add(activeWindow.name,Ext.copyTo({}, this,this.browserWindowsMessageBoxProps ));
			this.activeWindowName = activeWindow.name;
		} else {
			this.textboxEl.enableDisplayMode();
			this.textareaEl.enableDisplayMode();
			this.browserWindowsMessageBox.replace(this.activeWindowName, Ext.copyTo({}, this, this.browserWindowsMessageBoxProps));
		}
		return this.dlg;
	},

	/**
	 * Updates the message box body text
	 * @param {String} text (this.optional) Replaces the message box element's innerHTML with the specified string (defaults to
	 * the XHTML-compliant non-breaking space character '&amp;#160;')
	 * @return {Ext.MessageBox} this
	 */
	updateText : function(text){
		if(!this.dlg.isVisible() && !this.opt.width){
			this.dlg.setSize(this.maxWidth, 100); // resize first so content is never clipped from previous shows
		}
		// Append a space here for sizing. In IE, for some reason, it wraps text incorrectly without one in some cases
		this.msgEl.update(text ? text + ' ' : '&#160;');

		var iw = this.iconCls != '' ? (this.iconEl.getWidth() + this.iconEl.getMargins('lr')) : 0,
			mw = this.msgEl.getWidth() + this.msgEl.getMargins('lr'),
			fw = this.dlg.getFrameWidth('lr'),
			bw = this.dlg.body.getFrameWidth('lr'),
			w;
			
		w = Math.max(Math.min(this.opt.width || iw+mw+fw+bw, this.opt.maxWidth || this.maxWidth),
				Math.max(this.opt.minWidth || this.minWidth, this.bwidth || 0));

		if(this.opt.prompt === true){
			this.activeTextEl.setWidth(w-iw-fw-bw);
		}
		if(this.opt.progress === true || this.opt.wait === true){
			this.progressBar.setSize(w-iw-fw-bw);
		}
		if(Ext.isIE9m && w == this.bwidth){
			w += 4; //Add offset when the content width is smaller than the buttons.    
		}
		this.msgEl.update(text || '&#160;');
		this.dlg.setSize(w, 'auto').center();
		return this;
	},

	/**
	 * Updates a progress-style message box's text and progress bar. Only relevant on message boxes
	 * initiated via {@link Ext.MessageBox#progress} or {@link Ext.MessageBox#wait},
	 * or by calling {@link Ext.MessageBox#show} with progress: true.
	 * @param {Number} value Any number between 0 and 1 (e.g., .5, defaults to 0)
	 * @param {String} progressText The progress text to display inside the progress bar (defaults to '')
	 * @param {String} msg The message box's body text is replaced with the specified string (defaults to undefined
	 * so that any existing body text will not get overwritten by default unless a new value is passed in)
	 * @return {Ext.MessageBox} this
	 */
	updateProgress : function(value, progressText, msg){
		this.progressBar.updateProgress(value, progressText);
		if(msg){
			this.updateText(msg);
		}
		return this;
	},

	/**
	 * Returns true if the message box is currently displayed
	 * @return {Boolean} True if the message box is visible, else false
	 */
	isVisible : function(){
		return this.dlg && this.dlg.isVisible();
	},

	/**
	 * Hides the message box if it is displayed
	 * @return {Ext.MessageBox} this
	 */
	hide : function(){
		var proxy = this.dlg ? this.dlg.activeGhost : null;
		if(this.isVisible() || proxy){
			this.dlg.hide();
			this.handleHide();
			if (proxy){
				// unghost is a private function, but i saw no better solution
				// to fix the locking problem when dragging while it closes
				this.dlg.unghost(false, false);
			} 
		}
		return this;
	},

	/**
	 * Displays a new message box, or reinitializes an existing message box, based on the config this.options
	 * passed in. All display functions (e.g. prompt, alert, etc.) on MessageBox call this function internally,
	 * although those calls are basic shortcuts and do not support all of the config this.options allowed here.
	 * @param {Object} config The following config this.options are supported: <ul>
	 * <li><b>animEl</b> : String/Element<div class="sub-desc">An id or Element from which the message box should animate as it
	 * opens and closes (defaults to undefined)</div></li>
	 * <li><b>buttons</b> : Object/Boolean<div class="sub-desc">A button config object (e.g., Ext.MessageBox.OKCANCEL or {ok:'Foo',
	 * cancel:'Bar'}), or false to not show any buttons (defaults to false)</div></li>
	 * <li><b>closable</b> : Boolean<div class="sub-desc">False to hide the top-right close button (defaults to true). Note that
	 * progress and wait dialogs will ignore this property and always hide the close button as they can only
	 * be closed programmatically.</div></li>
	 * <li><b>cls</b> : String<div class="sub-desc">A custom CSS class to apply to the message box's container element</div></li>
	 * <li><b>defaultTextHeight</b> : Number<div class="sub-desc">The default height in pixels of the message box's multiline textarea
	 * if displayed (defaults to 75)</div></li>
	 * <li><b>fn</b> : Function<div class="sub-desc">A callback function which is called when the dialog is dismissed either
	 * by clicking on the configured buttons, or on the dialog close button, or by pressing
	 * the return button to enter input.
	 * <p>Progress and wait dialogs will ignore this this.option since they do not respond to user
	 * actions and can only be closed programmatically, so any required function should be called
	 * by the same code after it closes the dialog. Parameters passed:<ul>
	 * <li><b>buttonId</b> : String<div class="sub-desc">The ID of the button pressed, one of:<div class="sub-desc"><ul>
	 * <li><tt>ok</tt></li>
	 * <li><tt>yes</tt></li>
	 * <li><tt>no</tt></li>
	 * <li><tt>cancel</tt></li>
	 * </ul></div></div></li>
	 * <li><b>text</b> : String<div class="sub-desc">Value of the input field if either <tt><a href="#show-this.option-prompt" ext:member="show-this.option-prompt" ext:cls="Ext.MessageBox">prompt</a></tt>
	 * or <tt><a href="#show-this.option-multiline" ext:member="show-this.option-multiline" ext:cls="Ext.MessageBox">multiline</a></tt> is true</div></li>
	 * <li><b>this.opt</b> : Object<div class="sub-desc">The config object passed to show.</div></li>
	 * </ul></p></div></li>
	 * <li><b>scope</b> : Object<div class="sub-desc">The scope of the callback function</div></li>
	 * <li><b>icon</b> : String<div class="sub-desc">A CSS class that provides a background image to be used as the body icon for the
	 * dialog (e.g. Ext.MessageBox.WARNING or 'custom-class') (defaults to '')</div></li>
	 * <li><b>iconCls</b> : String<div class="sub-desc">The standard {@link Ext.Window#iconCls} to
	 * add an this.optional header icon (defaults to '')</div></li>
	 * <li><b>maxWidth</b> : Number<div class="sub-desc">The maximum width in pixels of the message box (defaults to 600)</div></li>
	 * <li><b>minWidth</b> : Number<div class="sub-desc">The minimum width in pixels of the message box (defaults to 100)</div></li>
	 * <li><b>modal</b> : Boolean<div class="sub-desc">False to allow user interaction with the page while the message box is
	 * displayed (defaults to true)</div></li>
	 * <li><b>msg</b> : String<div class="sub-desc">A string that will replace the existing message box body text (defaults to the
	 * XHTML-compliant non-breaking space character '&amp;#160;')</div></li>
	 * <li><a id="show-this.option-multiline"></a><b>multiline</b> : Boolean<div class="sub-desc">
	 * True to prompt the user to enter multi-line text (defaults to false)</div></li>
	 * <li><b>progress</b> : Boolean<div class="sub-desc">True to display a progress bar (defaults to false)</div></li>
	 * <li><b>progressText</b> : String<div class="sub-desc">The text to display inside the progress bar if progress = true (defaults to '')</div></li>
	 * <li><a id="show-this.option-prompt"></a><b>prompt</b> : Boolean<div class="sub-desc">True to prompt the user to enter single-line text (defaults to false)</div></li>
	 * <li><b>proxyDrag</b> : Boolean<div class="sub-desc">True to display a lightweight proxy while dragging (defaults to false)</div></li>
	 * <li><b>title</b> : String<div class="sub-desc">The title text</div></li>
	 * <li><b>value</b> : String<div class="sub-desc">The string value to set into the active textbox element if displayed</div></li>
	 * <li><b>wait</b> : Boolean<div class="sub-desc">True to display a progress bar (defaults to false)</div></li>
	 * <li><b>waitConfig</b> : Object<div class="sub-desc">A {@link Ext.ProgressBar#waitConfig} object (applies only if wait = true)</div></li>
	 * <li><b>width</b> : Number<div class="sub-desc">The width of the dialog in pixels</div></li>
	 * </ul>
	 * Example usage:
	 * <pre><code>
Ext.Msg.show({
title: 'Address',
msg: 'Please enter your address:',
width: 300,
buttons: Ext.MessageBox.OKCANCEL,
multiline: true,
fn: saveAddress,
animEl: 'addAddressBtn',
icon: Ext.MessageBox.INFO
});
</code></pre>
	 * @return {Ext.MessageBox} this
	 */
	show : function(options){
		if(this.isVisible()){
			this.hide();
		}
		this.opt = options;
		var d = this.getDialog(this.opt.title || "&#160;");

		d.setTitle(this.opt.title || "&#160;");
		var allowClose = (this.opt.closable !== false && this.opt.progress !== true && this.opt.wait !== true);
		d.tools.close.setDisplayed(allowClose);
		this.activeTextEl = this.textboxEl;
		this.opt.prompt = this.opt.prompt || (this.opt.multiline ? true : false);
		if(this.opt.prompt){
			if(this.opt.multiline){
				this.textboxEl.hide();
				this.textareaEl.show();
				this.textareaEl.setHeight(Ext.isNumber(this.opt.multiline) ? this.opt.multiline : this.defaultTextHeight);
				this.activeTextEl = this.textareaEl;
			}else{
				this.textboxEl.show();
				this.textareaEl.hide();
			}
		}else{
			this.textboxEl.hide();
			this.textareaEl.hide();
		}
		this.activeTextEl.dom.value = this.opt.value || "";
		if(this.opt.prompt){
			d.focusEl = this.activeTextEl;
		}else{
			var bs = this.opt.buttons;
			var db = null;
			if(bs && bs.ok){
				db = this.buttons["ok"];
			}else if(bs && bs.yes){
				db = this.buttons["yes"];
			}
			if (db){
				d.focusEl = db;
			}
		}
		if(Ext.isDefined(this.opt.iconCls)){
		  d.setIconClass(this.opt.iconCls);
		}
		this.setIcon(Ext.isDefined(this.opt.icon) ? this.opt.icon : this.bufferIcon);
		this.bwidth = this.updateButtons(this.opt.buttons);
		this.progressBar.setVisible(this.opt.progress === true || this.opt.wait === true);
		this.updateProgress(0, this.opt.progressText);
		this.updateText(this.opt.msg);
		if(this.opt.cls){
			d.el.addClass(this.opt.cls);
		}
		d.proxyDrag = this.opt.proxyDrag === true;
		d.modal = this.opt.modal !== false;
		d.mask = this.opt.modal !== false ? this.mask : false;
		if(!d.isVisible()){
			// force it to the end of the z-index stack so it gets a cursor in FF
			// Get proper browser window to render the message box into body element of the same.
			var activeWindow = Zarafa.core.BrowserWindowMgr.getActive();
			activeWindow.document.body.appendChild(this.dlg.el.dom);
			d.setAnimateTarget(this.opt.animEl);
			//workaround for window internally enabling keymap in afterShow
			d.on('show', function(){
				if(allowClose === true){
					d.keyMap.enable();
				}else{
					d.keyMap.disable();
				}
			}, this, {single:true});
			d.show(this.opt.animEl);
		}
		if(this.opt.wait === true){
			this.progressBar.wait(this.opt.waitConfig);
		}
		return this;
	},

	/**
	 * Adds the specified icon to the dialog.  By default, the class 'ext-mb-icon' is applied for default
	 * styling, and the class passed in is expected to supply the background image url. Pass in empty string ('')
	 * to clear any existing icon. This method must be called before the MessageBox is shown.
	 * The following built-in icon classes are supported, but you can also pass in a custom class name:
	 * <pre>
Ext.MessageBox.INFO
Ext.MessageBox.WARNING
Ext.MessageBox.QUESTION
Ext.MessageBox.ERROR
	 *</pre>
	 * @param {String} icon A CSS classname specifying the icon's background image url, or empty string to clear the icon
	 * @return {Ext.MessageBox} this
	 */
	setIcon : function(icon){
		if(!this.dlg){
			this.bufferIcon = icon;
			return;
		}
		this.bufferIcon = undefined;
		if(icon && icon != ''){
			this.iconEl.removeClass('x-hidden');
			this.iconEl.replaceClass(this.iconCls, icon);
			this.bodyEl.addClass('x-dlg-icon');
			this.iconCls = icon;
		}else{
			this.iconEl.replaceClass(this.iconCls, 'x-hidden');
			this.bodyEl.removeClass('x-dlg-icon');
			this.iconCls = '';
		}
		return this;
	},

	/**
	 * Displays a message box with a progress bar.  This message box has no buttons and is not closeable by
	 * the user.  You are responsible for updating the progress bar as needed via {@link Ext.MessageBox#updateProgress}
	 * and closing the message box when the process is complete.
	 * @param {String} title The title bar text
	 * @param {String} msg The message box body text
	 * @param {String} progressText (this.optional) The text to display inside the progress bar (defaults to '')
	 * @return {Ext.MessageBox} this
	 */
	progress : function(title, msg, progressText){
		this.show({
			title : title,
			msg : msg,
			buttons: false,
			progress:true,
			closable:false,
			minWidth: this.minProgressWidth,
			progressText: progressText
		});
		return this;
	},

	/**
	 * Displays a message box with an infinitely auto-updating progress bar.  This can be used to block user
	 * interaction while waiting for a long-running process to complete that does not have defined intervals.
	 * You are responsible for closing the message box when the process is complete.
	 * @param {String} msg The message box body text
	 * @param {String} title (this.optional) The title bar text
	 * @param {Object} config (this.optional) A {@link Ext.ProgressBar#waitConfig} object
	 * @return {Ext.MessageBox} this
	 */
	wait : function(msg, title, config){
		this.show({
			title : title,
			msg : msg,
			buttons: false,
			closable:false,
			wait:true,
			modal:true,
			minWidth: this.minProgressWidth,
			waitConfig: config
		});
		return this;
	},

	/**
	 * Displays a standard read-only message box with an OK button (comparable to the basic JavaScript alert prompt).
	 * If a callback function is passed it will be called after the user clicks the button, and the
	 * id of the button that was clicked will be passed as the only parameter to the callback
	 * (could also be the top-right close button).
	 * @param {String} title The title bar text
	 * @param {String} msg The message box body text
	 * @param {Function} fn (this.optional) The callback function invoked after the message box is closed
	 * @param {Object} scope (this.optional) The scope (<code>this</code> reference) in which the callback is executed. Defaults to the browser wnidow.
	 * @return {Ext.MessageBox} this
	 */
	alert : function(title, msg, fn, scope){
		this.show({
			title : title,
			msg : msg,
			buttons: this.OK,
			fn: fn,
			scope : scope,
			minWidth: this.minWidth
		});
		return this;
	},

	/**
	 * Displays a confirmation message box with Yes and No buttons (comparable to JavaScript's confirm).
	 * If a callback function is passed it will be called after the user clicks either button,
	 * and the id of the button that was clicked will be passed as the only parameter to the callback
	 * (could also be the top-right close button).
	 * @param {String} title The title bar text
	 * @param {String} msg The message box body text
	 * @param {Function} fn (this.optional) The callback function invoked after the message box is closed
	 * @param {Object} scope (this.optional) The scope (<code>this</code> reference) in which the callback is executed. Defaults to the browser wnidow.
	 * @return {Ext.MessageBox} this
	 */
	confirm : function(title, msg, fn, scope){
		this.show({
			title : title,
			msg : msg,
			buttons: this.YESNO,
			fn: fn,
			scope : scope,
			icon: this.QUESTION,
			minWidth: this.minWidth
		});
		return this;
	},

	/**
	 * Displays a message box with OK and Cancel buttons prompting the user to enter some text (comparable to JavaScript's prompt).
	 * The prompt can be a single-line or multi-line textbox.  If a callback function is passed it will be called after the user
	 * clicks either button, and the id of the button that was clicked (could also be the top-right
	 * close button) and the text that was entered will be passed as the two parameters to the callback.
	 * @param {String} title The title bar text
	 * @param {String} msg The message box body text
	 * @param {Function} fn (this.optional) The callback function invoked after the message box is closed
	 * @param {Object} scope (this.optional) The scope (<code>this</code> reference) in which the callback is executed. Defaults to the browser wnidow.
	 * @param {Boolean/Number} multiline (this.optional) True to create a multiline textbox using the defaultTextHeight
	 * property, or the height in pixels to create the textbox (defaults to false / single-line)
	 * @param {String} value (this.optional) Default value of the text input element (defaults to '')
	 * @return {Ext.MessageBox} this
	 */
	prompt : function(title, msg, fn, scope, multiline, value){
		this.show({
			title : title,
			msg : msg,
			buttons: this.OKCANCEL,
			fn: fn,
			minWidth: this.minPromptWidth,
			scope : scope,
			prompt:true,
			multiline: multiline,
			value: value
		});
		return this;
	},

	/**
	 * Function which is use to set active browser window messageBox.
	 * It will check that given browser window was registered in {@Link Ext.MessageBox.browserWindowsMessageBox}
	 * If it was not registered then re initialize a set of {@Link Ext.MessageBox.browserWindowsMessageBoxProps props}
	 * of {@link Ext.MessageBox} so it will create new object and registered in {@Link Ext.MessageBox.browserWindowsMessageBox}
	 * And if given browser window was already registered then get {@Link Ext.MessageBox.browserWindowsMessageBox}
	 * for particular browser window and apply it to {@link Ext.MessageBox}
	 */
	setActiveWindowMessageBox: function (browserWindowName)
	{
		var activeMessageBox = this.browserWindowsMessageBox.get(browserWindowName);
		if (!activeMessageBox) {
			var defaultMessageBoxConfig = {};
			Ext.each(this.browserWindowsMessageBoxProps, function (item) {
				defaultMessageBoxConfig[item] = undefined;
			});
			Ext.apply(this, defaultMessageBoxConfig);
		} else {
			this.browserWindowsMessageBox.replace(this.activeWindowName, Ext.copyTo({}, this, this.browserWindowsMessageBoxProps));
			Ext.apply(this, activeMessageBox);
		}

		this.activeWindowName = browserWindowName;
	},

	/**
	 * De-register an already registered message box for given browser window object from the {@link Ext.MessageBox#browserWindowsMessageBox}.
	 * @param {Object} browserWindowName The browser window object name
	 */
	removeBrowserWindowMessageBox : function(browserWindowName)
	{
		this.browserWindowsMessageBox.removeKey(browserWindowName);
	}
});
Ext.MessageBox = new Ext.MessageBox();

/**
 * Shorthand for {@link Ext.MessageBox}
 */
Ext.Msg = Ext.MessageBox;
(function() {
	var orig_register = Ext.QuickTip.prototype.register;
	var orig_getTipCfg = Ext.QuickTip.prototype.getTipCfg;

	/**
	 * @class Ext.QuickTip
	 * This will encode the content of tooltip to prevent the HTML injection.
	 * @singleton
	 */
	Ext.override(Ext.QuickTip, {
		/**
		 * Here it will encode title and text of tooltip when component is initialized time.
		 * It is used to prevent HTML Injection.
		 * 
		 * @param {Object} config Configuration object
		 */
		register : function(config)
		{
			config.title = Ext.util.Format.htmlEncode(config.title);
			config.text = Ext.util.Format.htmlEncode(config.text);
			orig_register.apply(this, arguments);
		},

		/**
		 * Here it will encode tooltip's text when hover the cursor on component.
		 * It is used to prevent HTML Injection.
		 * 
		 * @param {Ext.EventObject} e The mouse event object
		 * @return {String} The encoded text of tooltip.
		 */
		getTipCfg: function(e)
		{
			return Ext.util.Format.htmlEncode(orig_getTipCfg.apply(this, arguments));
		}
	});
})();Ext.namespace('Ext.QuickTips');
/*
 * @class Ext.QuickTips
 * Provides attractive and customizable tooltips for any element belongs to any available browser windows.
 * Maintains a list of all the {@link Ext.QuickTip} instances created for each of the available browser windows.
 * @singleton
 */
Ext.QuickTips = Ext.extend(Object, {
	/**
	 * The list of registered {@link #tip} bound to a unique browser window name.
	 * @property
	 * @type Ext.util.MixedCollection
	 * @private
	 */
	browserQuickTips : undefined,

	/**
	 * The {@link Ext.QuickTip} instance belongs to specific browser window which
	 * is currently {@link Zarafa.core.BrowserWindowMgr.activeBrowserWindow active}.
	 * @property
	 * @type String
	 * @private
	 */
	tip : undefined,

	/**
	 * Render this tip disabled.
	 * @property
	 * @type Boolean
	 * @private
	 */
	disabled : false,

	/**
	 * @constructor
	 */
	constructor : function(config)
	{
		config = config || {};

		this.browserQuickTips = new Ext.util.MixedCollection();
	},

	/**
	 * Initialize the global QuickTips instance and prepare any quick tips.
	 * @param {Boolean} autoRender True to render the QuickTips container immediately to preload images. (Defaults to true) 
	 */
	init : function(autoRender) {
		if(!Ext.isReady){
			Ext.onReady(function(){
				Ext.QuickTips.init(autoRender);
			});
			return;
		}
		this.tip = new Ext.QuickTip({
			elements:'header,body', 
			disabled: this.disabled
		});
		if(autoRender !== false){
			this.tip.render(Ext.getBody());
		}

		this.browserQuickTips.add(Zarafa.core.BrowserWindowMgr.getOwnerWindow(this.tip).name, this.tip);
	},

	// Protected method called by the dd classes
	ddDisable : function(){
		// don't disable it if we don't need to
		if(this.tip && !this.disabled){
			this.tip.disable();
		}
	},
	
	// Protected method called by the dd classes
	ddEnable : function(){
		// only enable it if it hasn't been disabled
		if(this.tip && !this.disabled){
			this.tip.enable();
		}
	},

	/**
	 * Enable quick tips globally.
	 */
	enable : function(){
		if(this.tip){
			this.tip.enable();
		}
		this.disabled = false;
	},

	/**
	 * Disable quick tips globally.
	 */
	disable : function(){
		if(this.tip){
			this.tip.disable();
		}
		this.disabled = true;
	},

	/**
	 * Returns true if quick tips are enabled, else false.
	 * @return {Boolean}
	 */
	isEnabled : function(){
		return this.tip !== undefined && !this.tip.disabled;
	},

	/**
	 * Gets the single {@link Ext.QuickTip QuickTip} instance used to show tips from all registered elements.
	 * @return {Ext.QuickTip}
	 */
	getQuickTip : function(){
		return this.tip;
	},

	/**
	 * Configures a new quick tip instance and assigns it to a target element.  See
	 * {@link Ext.QuickTip#register} for details.
	 * @param {Object} config The config object
	 */
	register : function(){
		this.tip.register.apply(this.tip, arguments);
	},

	/**
	 * Removes any registered quick tip from the target element and destroys it.
	 * @param {String/HTMLElement/Element} el The element from which the quick tip is to be removed.
	 */
	unregister : function(){
		this.tip.unregister.apply(this.tip, arguments);
	},

	/**
	 * Alias of {@link #register}.
	 * @param {Object} config The config object
	 */
	tips : function(){
		this.tip.register.apply(this.tip, arguments);
	}
});
Ext.QuickTips = new Ext.QuickTips();
(function() {
 	var orig_doAutoWidth = Ext.Tip.prototype.doAutoWidth;

	Ext.override(Ext.Tip, {
		/*
		 * Fix an issue where IE9 & IE10 & IE11 breaks words and wraps it to new line
		 * because of wrong calculation of text width
		 * Maybe this is caused when we request an element's dimension via offsetWidth or offsetHeight, getBoundingClientRect, etc.
		 * the browser returns the subpixel width rounded to the nearest pixel.
		 */
		doAutoWidth : function()
		{
			orig_doAutoWidth.call(this, Ext.isIE ? 1 : 0);
		}
	});
})();(function() {
	/**
	 * Override Ext.Toolbar.TextItem to make the text unselectable.
	 */
	var orig_onRender = Ext.Toolbar.TextItem.prototype.onRender;
	Ext.override(Ext.Toolbar.TextItem, {

		onRender : function(ct, position)
		{
			orig_onRender.apply(this, arguments);

			if (this.el) {
				this.el.unselectable();
			}
		}

	});
})();
(function() {
 	var orig_beforeShow = Ext.Window.prototype.beforeShow;
 	var orig_onWindowResize = Ext.Window.prototype.onWindowResize;

	Ext.override(Ext.Window, {
		/**
		 * The window object that represents the browser window that contains this Ext.Window
		 */
		browserWindow : undefined,

		/*
		 * overridden to set the correct size for the mask element in popout windows
		 */
		beforeShow : function()
		{
			orig_beforeShow.call(this);

			this.correctMaskSize();

			this.browserWindow = this.el.dom.ownerDocument.defaultView;
		},

		/*
		 * Overridden to set a different handler for the resize event of popout windows
		 */
		afterShow : function(isAnim)
		{
	        if (this.isDestroyed){
	            return false;
	        }
	        this.proxy.hide();
	        this.el.setStyle('display', 'block');
	        this.el.show();
	        if(this.maximized){
	            this.fitContainer();
	        }

	        if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
           		// Popout browser windows should listen to their own resize event and not to the one of the main window
				if ( this.browserWindow.name === 'mainBrowserWindow' ){
	            	Ext.EventManager.onWindowResize(this.onWindowResize, this);
	           } else {
					Zarafa.core.BrowserWindowMgr.on('separatewindowresize', this.onSeparateWindowResize, this);
	           }
	        }
	        this.doConstrain();
	        this.doLayout();
	        if(this.keyMap){
	            this.keyMap.enable();
	        }
	        this.toFront();
	        this.updateHandles();
	        if(isAnim && (Ext.isIE || Ext.isWebKit)){
	            var sz = this.getSize();
	            this.onResize(sz.width, sz.height);
	        }
	        this.onShow();
	        this.fireEvent('show', this);
		},

		/*
		 * Overridden to remove the correct event listener for popout browser windows
		 */
		afterHide : function(){
			this.proxy.hide();
			if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
				if ( this.browserWindow.name === 'mainBrowserWindow' ){
					Ext.EventManager.removeResizeListener(this.onWindowResize, this);
			   } else {
					Zarafa.core.BrowserWindowMgr.un('separatewindowresize', this.onSeparateWindowResize, this);
			   }
			}
			if(this.keyMap){
				this.keyMap.disable();
			}
			this.onHide();
			this.fireEvent('hide', this);
		},

		/*
		 * Overridden to set the correct size of the mask for popout windows
		 */
		onWindowResize : function()
		{
			orig_onWindowResize.call(this);

			this.correctMaskSize();
		},

		/**
		 * Event handler for the separatewindowresize event of the {@link Zarafa.core.BrowserWindowMgr}
		 *
		 * @param {Window} browserWindow The window object that represents the browser window that
		 * was resized.
		 */
		onSeparateWindowResize : function(browserWindow)
		{
			if ( browserWindow === this.browserWindow ){
				this.onWindowResize();
			}
		},

		/**
		 * Resizes the mask that is used for modal windows to fit the browser window size
		 */
		correctMaskSize : function()
		{
			if(this.modal){
				// Hide the mask when resizing it or it will influence the size of the window
				this.mask.hide();
				this.mask.setSize(
					this.mask.dom.ownerDocument.body.scrollWidth,
					this.mask.dom.ownerDocument.body.scrollHeight
				);
				this.mask.show();
			}
		}
	});
})();
(function() {
	/*
	 * Fix the Ext.data.Node, when child nodes have been added or removed, the 'leaf'
	 * property must be updated. Otherwise the expand button will never be actually
	 * updated when adding or removing child nodes.
	 */
	var orig_appendChild = Ext.data.Node.prototype.appendChild;
	var orig_removeChild = Ext.data.Node.prototype.removeChild;

	Ext.override(Ext.data.Node, {
		appendChild : function(node)
		{
			this.leaf = false;
			return orig_appendChild.apply(this, arguments);
		},

		removeChild : function(node, destroy)
		{
			var ret = orig_removeChild.apply(this, arguments);
			if (!this.hasChildNodes()) {
				this.leaf = true;
			}
			return ret;
		}
	});
})();
(function() {

 	// Convert a string to a Integer
	//
	// Opposite to the Extjs implementation, this won't apply the
	// Ext.data.Types.stripRe regular expression, which means that
	// the protocol will demand that when the field is declared as
	// "Int" it _must_ be an integer and not a string like "$14,00"
	// or "15%".
 	var intConvert = function(v) {
		return v !== undefined && v !== null && v !== '' ?
		       parseInt(v, 10) : (this.useNull ? null : 0);
	};

	Ext.data.Types.INT.convert = intConvert;
	Ext.data.Types.INTEGER.convert = intConvert;

 	// Convert a string to a Float
	//
	// Opposite to the Extjs implementation, this won't apply the
	// Ext.data.Types.stripRe regular expression, which means that
	// the protocol will demand that when the field is declared as
	// "Float" it _must_ be an number and not a string like "$14,00"
	// or "15%".
 	var floatConvert = function(v) {
		return v !== undefined && v !== null && v !== '' ?
		       parseFloat(v, 10) : (this.useNull ? null : 0);
	};

	Ext.data.Types.FLOAT.convert = floatConvert;
	Ext.data.Types.NUMBER.convert = floatConvert;
})();
(function() {
	var orig_unreg = Ext.dd.DD.prototype.unreg;
	Ext.override(Ext.dd.DD, {
		/**
		 * When set to true, the utility automatically tries to scroll the browser
		 * window when a drag and drop element is dragged near the viewport boundary.
		 * Defaults to false. Overriden because in webapp we will never need to drag anything out of window.
		 * @property scroll
		 * @type boolean
		 */
		scroll : false,

		/**
		 * Remove all drag and drop hooks for this element,
		 * Override the method to de-register element which was destroyed with respect to its owner window.
		 * @method unreg
		 */
		unreg: function() {
			orig_unreg.apply(this, arguments);

			// Remove the element if it is being dragged currently from DragDropMgr as well
			if(this == this.DDM.dragCurrent) {
				this.DDM.dragCurrent = null;
			}
		}
	});
})();(function() {
	/**
	 * @class Ext.dd.DragDropMgr
	 * DragDropMgr is a singleton that tracks the element interaction for
	 * all DragDrop items in the window.  Generally, you will not call
	 * this class directly, but it does have helper methods that could
	 * be useful in your DragDrop implementations.
	 * @singleton
	 */
	var orig_getLocation = Ext.dd.DragDropMgr.getLocation;

	Ext.apply(Ext.dd.DragDropMgr, {

		/**
		 * Returns the DragDrop instance for a given id which belongs to
		 * the given group (as configured in the {@link Ext.dd.DragSource}.
		 * @method getGroupDDById
		 * @param {String} group the {@link Ext.dd.DragSource#ddGroup ddGroup}
		 * for which the id is searched for.
		 * @param {String} id the id of the DragDrop object
		 * @return {DragDrop} the drag drop object, null if it is not found
		 * @static
		 */
		getGroupDDById : function(group, id)
		{
			if (this.ids[group] && this.ids[group][id]) {
				return this.ids[group][id];
			}
			return null;
		},

		/**
		 * Returns a Region object containing the drag and drop element's position
		 * and size, including the padding configured for it
		 * @method getLocation
		 * @param {DragDrop} oDD the drag and drop object to get the
		 *                       location for
		 * @return {Ext.lib.Region} a Region object representing the total area
		 *                             the element occupies, including any padding
		 *                             the instance is configured for.
		 */
		getLocation : function(oDD)
		{
			var el = oDD.getEl();

			var region = orig_getLocation.apply(this, arguments);

			// below code is taken from previous version of extjs
			// to fix drag and drop between overlapping elements
			if(el && region) {
				/*
				 * The code below is to ensure that large scrolling elements will
				 * only have their visible area recognized as a drop target, otherwise it
				 * can potentially erronously register as a target when the element scrolls
				 * over the top of something below it.
				 */
				el = Ext.get(el.parentNode);
				while (el && region) {
					if (el.isScrollable()) {
						// check whether our element is visible in the view port:
						region = region.intersect(el.getRegion());
					}
					el = el.parent();
				}
			}

			return region;
		},

		/**
		 * @private
		 * Collects the z-index of the passed element, looking up the parentNode axis to find an absolutely positioned ancestor
		 * which is able to yield a z-index. If found to be not absolutely positionedm returns -1.
		 *
		 * This is used when sorting potential drop targets into z-index order so that only the topmost receives `over` and `drop` events.
		 *
		 * @return {Number} The z-index of the element, or of its topmost absolutely positioned ancestor. Returns -1 if the element is not
		 * absolutely positioned.
		 */
		getZIndex : function(element)
		{
			// to fix drag and drop between overlapping elements
			// we are removing use of this function as previous version of extjs was not having this function
			return -1;
		},

		/**
		 * Drag and drop initialization.Setting up the global event handlers on browser window
		 * @param {Object} browserWindowObject The newly created window object
         */
		initEvents : function(browserWindowObject)
		{
			// Initialize mouse event handlers which are use to handle drag and drop in separate browser window.
			Ext.EventManager.on(browserWindowObject.document, "mousemove", this.handleMouseMove, this, true);
			Ext.EventManager.on(browserWindowObject.document, "mouseup", this.handleMouseUp, this, true);
		},

		/**
		 * Checks the cursor location to see if it over the target
		 * @method isOverTarget
		 * @param {Ext.lib.Point} pt The point to evaluate
		 * @param {DragDrop} oTarget the DragDrop object we are inspecting
		 * @return {boolean} true if the mouse is over the target
		 * @private
		 */
		isOverTarget: function(pt, oTarget, intersect) {
			// use cache if available
			var loc = this.locationCache[oTarget.id];
			if (!loc || !this.useCache) {
				loc = this.getLocation(oTarget);
				this.locationCache[oTarget.id] = loc;

			}

			if (!loc) {
				return false;
			}

			oTarget.cursorIsOver = loc.contains( pt );

			// DragDrop is using this as a sanity check for the initial mousedown
			// in this case we are done.  In POINT mode, if the drag obj has no
			// contraints, we are also done. Otherwise we need to evaluate the
			// location of the target as related to the actual location of the
			// dragged element.
			var dc = this.dragCurrent;
			if (!dc || !dc.getTargetCoord || (!intersect && !dc.constrainX && !dc.constrainY)) {

				// verified is cursor is over the target by location and position.
				// But now we have multiple windows that's way it's require to check that
				// the target element is belongs to active window or not?

				if (oTarget.cursorIsOver) {
					var activeWindow = Zarafa.core.BrowserWindowMgr.getActive();
					var targetOwnerWindow = Zarafa.core.BrowserWindowMgr.getOwnerWindow(oTarget);
					return activeWindow === targetOwnerWindow;
				} else {
					return false
				}
			}

			oTarget.overlap = null;

			// Get the current location of the drag element, this is the
			// location of the mouse event less the delta that represents
			// where the original mousedown happened on the element.  We
			// need to consider constraints and ticks as well.
			var pos = dc.getTargetCoord(pt.x, pt.y);

			var el = dc.getDragEl();
			var curRegion = new Ext.lib.Region( pos.y,
					pos.x + el.offsetWidth,
					pos.y + el.offsetHeight,
					pos.x );

			var overlap = curRegion.intersect(loc);

			if (overlap) {
				oTarget.overlap = overlap;
				return (intersect) ? true : oTarget.cursorIsOver;
			} else {
				return false;
			}
		}
	});
})();
(function() {
	/*
	 * Fix the Ext.dd.DragSource, so that it uses the Ext.dd.DragDropMgr.getGroupDDById
	 * to find the correct DropZone class for the given id. ExtJs does support
	 * registering multiple zones to an id, but the DragSource doesn't handle
	 * that case since it would always return the first dropZone which the
	 * DragDropMgr would return (the one with a ddGroup name which is
	 * alphabetical the highest).
	 */
	var orig_onDragEnter = Ext.dd.DragSource.prototype.onDragEnter;
	var orig_onDragOver = Ext.dd.DragSource.prototype.onDragOver;
	var orig_onDragOut = Ext.dd.DragSource.prototype.onDragOut;
	var orig_onDragDrop = Ext.dd.DragSource.prototype.onDragDrop;

	Ext.override(Ext.dd.DragSource, {
		onDragEnter : function(e, id)
		{
			// If we still have a cached target, then we still have
			// a connection with a DropZone which we should now force
			// to disconnect using onDragOut(). This prevents that we
			// are dragging the same item over 2 dragzones at the same
			// time.
			if (this.cachedTarget) {
				var oldId = this.cachedTarget.id;

				this.onDragOut(e, oldId);
			}

			var target;
			if (this.ddGroup) {       
				target = Ext.dd.DragDropMgr.getGroupDDById(this.ddGroup, id);
			} else {
				// backwards compatible for components which didn't use
				// configure the ddGroup correctly (as they actually should,
				// but as ExtJs was bugged, it was unnoticed).
				target = Ext.dd.DragDropMgr.getDDById(id);
			}

			// Literally copied from original function, we can't call the original
			// function as we have no way to pass our intended target variable.
			this.cachedTarget = target;
			if (target && this.beforeDragEnter(target, e, id) !== false) {
				if (target.isNotifyTarget) {
					var status = target.notifyEnter(this, e, this.dragData);
					this.proxy.setStatus(status);
				} else {
					this.proxy.setStatus(this.dropAllowed);
				}

				if (this.afterDragEnter) {
					this.afterDragEnter(target, e, id);
				}
			}
		},

		onDragOver : function(e, id)
		{
			// If we don't have a cached target, then we haven't got a connection
			// with a DropZone. This can happen when 2 DropZones are hovering over
			// eachother, when we enter the second DropZone, onDragEnter will have
			// unhooked the first DropZone. But since we are now hovering over it
			// again, we seem to have exited the top DropZone and we are back at
			// the first. So we force the connection again using onDragEnter().
			if (!this.cachedTarget){
				this.onDragEnter(e, id);
			}

			this.cachedTarget = this.cachedTarget || Ext.dd.DragDropMgr.getGroupDDById(this.ddGroup, id);
			return orig_onDragOver.apply(this, arguments);
		},

		onDragOut : function(e, id)
		{
			// If we haven't cached our target, then apparently we aren't hovering over
			// this DropZone. So no point in informing the onDragOut then.
			if (this.cachedTarget){
				return orig_onDragOut.apply(this, arguments);
			}
		},

		onDragDrop : function(e, id)
		{
			// If we haven't cached our target, then apparently we aren't hovering over
			// this DropZone. So no point in informing the onDragDrop then.
			if (this.cachedTarget){
				return orig_onDragDrop.apply(this, arguments);
			}
		}
	});
})();
(function() {
	/*
	 * Override Ext.form.BasicForm, there is a unwanted behavior in there
	 * which annoys users. For example the user is typing in field A, but
	 * loadRecord() is called on the form. This will remove the changes
	 * in field A and load them with the new contents.
	 *
	 * So to fix this, we prevent that when a field has the focus, and
	 * contains modifications, we ignore that given field.
	 */
	Ext.override(Ext.form.BasicForm, {

		// updateRecord overridden to check for the 'isSingleValued' property.
		updateRecord : function(record)
		{
			record.beginEdit();
			var fs = record.fields,
				 field,
				 value;
			fs.each(function(f){
				field = this.findField(f.name);
				if (field) {
					value = field.getValue();
					if (Ext.type(value) !== false && value.getGroupValue) {
						value = value.getGroupValue();
						// This else statement has been changed, originally it was if (field.eachItem).
						// From ExtJs code this could only be true for CompositeFields, however in WebApp
						// we use Composite fields for returning a single values based on combining the
						// values from the individual components. To keep supporting this feature without
						// requiring a completely new component support for the config option 'isSingleValued'
						// has been added (defined in Zarafa.common.ui.CompositeField).
					} else if (field.isSingleValued !== true && field.eachItem) {
						value = [];
						field.eachItem(function(item){
							value.push(item.getValue());
						});
					}
					record.set(f.name, value);
				}
			}, this);
			record.endEdit();
			return this;
		},

		// setValues overridden to add the checks:
		//   if (!field.hasFocus || (field.originalValue == field.el.dom.value)) {
		//   }
		setValues : function(values)
		{
			if(Ext.isArray(values)){ // array of objects
				for(var i = 0, len = values.length; i < len; i++){
					var v = values[i];
					var f = this.findField(v.id);
					if(f){
						// Don't update an input field which the user is working in
						if (!f.hasFocus || (f.originalValue == f.el.dom.value)) {
							f.setValue(v.value);
							if(this.trackResetOnLoad){
								f.originalValue = f.getValue();
							}
						}
					}
				}
			}else{ // object hash
				var field, id;
				for(id in values){
					if(!Ext.isFunction(values[id]) && (field = this.findField(id))) {
						// Don't update an input field which the user is working in
						if (!field.hasFocus || (field.originalValue == field.el.dom.value)) {
							field.setValue(values[id]);
							if(this.trackResetOnLoad){
								field.originalValue = field.getValue();
							}
						}
					}
				}
			}
			return this;
		}
	});
})();
(function() {
	/*
	 * Override Ext.form.Checkbox to add the proper CSS class to the wrap
	 * element of the checkbox. This fixes the behavioral difference between:
	 *
	 *  {
	 *      xtype: 'textfield',
	 *      fieldLabel: 'test'
	 *  }
	 *
	 * and
	 *
	 *  {
	 *      xtype: 'checkbox',
	 *      boxLabel: 'test'
	 *  }
	 *
	 *  In the first example the HTML looks like:
	 *
	 *  <div class="... x-form-item ...">
	 *    <label>test</test>
	 *    ...
	 *  </div>
	 *
	 *  While for the second example the HTML looks like:
	 *
	 *  <div class="... x-box-item ...">
	 *    <label>test</test>
	 *  </div>
	 *
	 *  In the first example, the CSS class x-form-item is applied,
	 *  which causes the label to be rendered differently then when
	 *  the CSS class is not applied.
	 *
	 *  However since both are Ext.form.Field subclasses, they should
	 *  behave the same when considering CSS classes and rendering of
	 *  labels.
	 */
	var orig_onRender = Ext.form.Checkbox.prototype.onRender;
	Ext.override(Ext.form.Checkbox, {

		onRender : function(ct, position)
		{
			orig_onRender.apply(this, arguments);

			// Add x-form-item CSS class to the wrap element
			this.wrap.addClass('x-form-item');

			// Make the text in the label unselectable
			if(this.boxLabel && this.el){
				var lbl = Ext.query('.x-form-cb-label', this.el.parent().dom)[0];
				if (lbl) {
					Ext.get(lbl).unselectable();
				}
			}
		}
	});
})();
(function() {
	var orig_initList = Ext.form.ComboBox.prototype.initList;
	var orig_expand = Ext.form.ComboBox.prototype.expand;
	var orig_initComponent = Ext.form.ComboBox.prototype.initComponent;

	Ext.override(Ext.form.ComboBox, {
		// private
		defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off", spellcheck: 'true'},

		/*
		 * Overridden to add 'beforeexpand' event.
		 */
		initComponent : function()
		{
			orig_initComponent.apply(this, arguments);

			this.addEvents(
				/**
				 * @event beforeexpand
				 * Fires before list is expanded. Return false to cancel the expansion.
				 * @param {Ext.form.ComboBox} combo This combo box
				 */
				'beforeexpand'
			);
		},

		/*
		 * Fix the default behavior for the Ext.form.Combobox. By default the combobox
		 * will not encode any text which is placed into the list. Since the entire
		 * combobox accepts data directly from a store this can be dangerous and it is
		 * better to htmlEncode the data by default.
		 */
		initList : function()
		{
			if (!this.tpl) {
				this.tpl = '<tpl for="."><div class="x-combo-list-item">{' + this.displayField + ':htmlEncode}</div></tpl>';
			}
			orig_initList.apply(this, arguments);
		},

		/*
		 * Overridden to provide facility to fire 'beforeexpand' event.
		 */
		expand : function()
		{
			if(this.isExpanded() || !this.hasFocus){
				return;
			}

			if(this.fireEvent('beforeexpand', this) !== false){
				orig_expand.apply(this, arguments);
			}
		},

		/*
		 * Override getListParent to return the body element of the owner document which owns the list element.
		 * @return {HTMLElement} The body of owner document of list element.
		 */
		getListParent : function()
		{
			var elOwnerDocument = this.getEl() ? this.getEl().dom.ownerDocument : undefined;

			if(elOwnerDocument){
				return elOwnerDocument.body;
			} else {
				return document.body;
			}
		}
	});
})();
(function() {
	var orig_getValue = Ext.form.DateField.prototype.getValue;
	var orig_initComponent = Ext.form.DateField.prototype.initComponent;
	var orig_onTriggerClick = Ext.form.DateField.prototype.onTriggerClick;
	var orig_menuEvents = Ext.form.DateField.prototype.menuEvents;
	Ext.override(Ext.form.DateField, {
		/**
		 * @cfg {Boolean} showNow True to enable the mechanism which convert 'Today' button into 'Now'
		 * and fire {@link #selectnow} event while 'Now' button will be pressed, false otherwise.
		 * defaults to false.
		 */
		showNow : false,
		/**
		 * overriden to set starting day of the week
		 * @override
		 */
		initComponent: function()
		{
			// if startDay is not specified through config then use one specified in settings
			if(!this.initialConfig.startDay) {
				this.startDay = container.getSettingsModel().get('zarafa/v1/main/week_start');
			}

			orig_initComponent.apply(this, arguments);

			this.addEvents(
				/**
				 * @event selectnow
				 * Fires when 'Today' button is pressed from the date picker only if {@link #showNow} is configured as true.
				 * @param {Ext.form.DateField} this
				 * @param {Date} date The date that was selected
				 */
				'selectnow'
			);

			// Check for invalid start day
			if(this.startDay < 0 || this.startDay >= Date.dayNames.length) {
				// by default make it sunday
				this.startDay = 0;
			}
		},

		/*
		 * Fix the getValue function for the DateField, normally Extjs would
		 * return an empty string ("") when no date was provided, but it more
		 * logically would be to return null.
		 */
		getValue : function()
		{
			var value = orig_getValue.apply(this, arguments);
			return Ext.isEmpty(value) ? null : value;
		},

		/**
		* This function prepares raw values for validation purpose only. Here when
		* field value is null than empty string will be returned because ExtJS by default uses
		* empty string to indicate that date is not present but there is no way in mapi to set
		* empty date. Here the validation function for date field doesn't expect null so we have
		* overriden processValue to give empty string if value is null.
		* @param {Mixed} value
		* @return {Mixed} value or empty string.
		*/
		processValue : function(value)
		{
			return Ext.isEmpty(value) ? "" : value;
		},

		/**
		 * Overridden to add possibilities to get an event fired when 'Today' button will be clicked.
		 * and rename the button from 'Today' to 'Now'.
		 * @override
		 */
		onTriggerClick : function()
		{
			if(this.showNow && this.menu == null) {
				this.menu = new Ext.menu.DateMenu({
					hideOnClick: false,
					focusOnSelect: false,
					initialConfig : {
						showNow : true,
						todayText : _("Now")
					}
				});
			}

			orig_onTriggerClick.apply(this, arguments);

			if(this.showNow) {
				 /**
				 * @event selectnow
				 * Fires when 'Now' button is clicked from the {@link Ext.DatePicker}
				 * @param {DatePicker} picker The {@link Ext.DatePicker}
				 * @param {Date} date The selected date
				 */
				this.menu.relayEvents(this.menu.picker, ['selectnow']);
			}
		},

		/**
		 * Overridden to register/deregister 'selectnow' event.
		 * This is a helper function to dynamically achieve registration and deregistration of any event by single function.
		 * @param {String} method Name of method like 'on' or 'un'.
		 * @private
		 * @override
		 */
		menuEvents: function(method){

			orig_menuEvents.apply(this, arguments);

			if(this.showNow) {
				this.menu[method]('selectnow', this.onSelectnow, this);
			}
		},

		/**
		 * Handler for the 'selectnow' event of {@link #menu}.
		 * Overridden to relay/fire 'selectnow' event for {@link #this}.
		 * @param {DatePicker} picker The {@link #picker Ext.DatePicker}
		 * @param {Date} date The selected date
		 * @private
		 * @override
		 */
		onSelectnow : function(picker,date){
			this.fireEvent('selectnow', this, date);
		}
	});
})();
(function() {
	/*
	 * Override Ext.form.DisplayField to guarentee the availability
	 * of the 'x-form-item' CSS class.
	 * This is normally only applied when the component is being
	 * rendered using the FormLayout, but this doesn't really make
	 * sense for styling.
	 */
	Ext.override(Ext.form.DisplayField, {
		cls: 'x-form-item'
	});
})();
(function() {
	/**
	 * @class Ext.form.FormPanel
	 * @extends Ext.Panel
	 * <p>Standard form container.</p>
	 *
	 * <p><b><u>Layout</u></b></p>
	 * <p>By default, FormPanel is configured with <tt>layout:'form'</tt> to use an {@link Ext.layout.FormLayout}
	 * layout manager, which styles and renders fields and labels correctly. When nesting additional Containers
	 * within a FormPanel, you should ensure that any descendant Containers which host input Fields use the
	 * {@link Ext.layout.FormLayout} layout manager.</p>
	 *
	 * <p><b><u>BasicForm</u></b></p>
	 * <p>Although <b>not listed</b> as configuration options of FormPanel, the FormPanel class accepts all
	 * of the config options required to configure its internal {@link Ext.form.BasicForm} for:
	 * <div class="mdetail-params"><ul>
	 * <li>{@link Ext.form.BasicForm#fileUpload file uploads}</li>
	 * <li>functionality for {@link Ext.form.BasicForm#doAction loading, validating and submitting} the form</li>
	 * </ul></div>
	 *
	 * <p><b>Note</b>: If subclassing FormPanel, any configuration options for the BasicForm must be applied to
	 * the <tt><b>initialConfig</b></tt> property of the FormPanel. Applying {@link Ext.form.BasicForm BasicForm}
	 * configuration settings to <b><tt>this</tt></b> will <b>not</b> affect the BasicForm's configuration.</p>
	 *
	 * <p><b><u>Form Validation</u></b></p>
	 * <p>For information on form validation see the following:</p>
	 * <div class="mdetail-params"><ul>
	 * <li>{@link Ext.form.TextField}</li>
	 * <li>{@link Ext.form.VTypes}</li>
	 * <li>{@link Ext.form.BasicForm#doAction BasicForm.doAction <b>clientValidation</b> notes}</li>
	 * <li><tt>{@link Ext.form.FormPanel#monitorValid monitorValid}</tt></li>
	 * </ul></div>
	 *
	 * <p><b><u>Form Submission</u></b></p>
	 * <p>By default, Ext Forms are submitted through Ajax, using {@link Ext.form.Action}. To enable normal browser
	 * submission of the {@link Ext.form.BasicForm BasicForm} contained in this FormPanel, see the
	 * <tt><b>{@link Ext.form.BasicForm#standardSubmit standardSubmit}</b></tt> option.</p>
	 *
	 * @constructor
	 * @param {Object} config Configuration options
	 * @xtype form
	 */
	Ext.override(Ext.form.FormPanel, {
		/**
		 * @cfg {String} labelAlign The label alignment value used for the <tt>text-align</tt> specification
		 * for the <b>container</b>. Valid values are <tt>"left</tt>", <tt>"top"</tt> or <tt>"right"</tt>
		 * (defaults to <tt>"right"</tt>). This property cascades to child <b>containers</b> and can be
		 * overridden on any child <b>container</b> (e.g., a fieldset can specify a different <tt>labelAlign</tt>
		 * for its fields).
		 */
		labelAlign: 'right'
	});
})();
(function() {
	/*
	 * Override Ext.form.Label, there is a bahavioral difference
	 * between with using:
	 *      {
	 *          xtype: 'component',
	 *          fieldLabel: 'test'
	 *      }
	 * and
	 *      {
	 *          xtype: 'label',
	 *          text: 'test'
	 *      }
	 *
	 *  Altough both would render a label with the contents 'test',
	 *  the CSS classes are applied incorrectly. When using the
	 *  fieldLabel option, the generated HTML is:
	 *
	 *      <div class="x-form-item">
	 *          <label class="x-form-item-label">test</label>
	 *      </div>
	 *
	 * while using xtype: 'label' generates the HTML:
	 *
	 *      <label>test</test>
	 *
	 * Due to the missing CSS classes the Font size and padding are
	 * not applied correctly. However, adding the 'cls' statement
	 * to the configuration for adding the CSS classes 'x-form-item'
	 * or 'x-form-item-label' will not result in the same behavior
	 * either. The CSS definitions from Extjs really require the
	 * <label> element to be wrapped by a <div class="x-form-item">
	 * element.
	 */
	var orig_onRender = Ext.form.Label.prototype.onRender;
	Ext.override(Ext.form.Label, {
		cls: 'x-form-item-label',

		onRender : function(ct, position)
		{
			orig_onRender.apply(this, arguments);

			// Wrap the main element in a div element with class x-form-item. By naming it positionEl,
			// ExtJs will correctly position the div and its  contents on the correct location.
			this.positionEl = this.el.wrap({cls: 'x-form-item'});

			// Make the element unselectable by default.
			this.el.unselectable();
		}
	});
})();
(function() {
	/*
	 * Override Ext.form.TextField to add the spellcheck attribute to inputs
	 */
	Ext.override(Ext.form.TextField, {
	    /**
	     * @cfg {String/Object} autoCreate <p>A {@link Ext.DomHelper DomHelper} element spec, or true for a default
	     * element spec. Used to create the {@link Ext.Component#getEl Element} which will encapsulate this Component.
	     * See <tt>{@link Ext.Component#autoEl autoEl}</tt> for details.  Defaults to:</p>
	     * <pre><code>{tag: 'input', type: 'text', size: '20', autocomplete: 'off', spellcheck: 'true'}</code></pre>
	     */
    	defaultAutoCreate : {tag: 'input', type: 'text', size: '20', autocomplete: 'off', spellcheck: 'true'}
	});
})();
(function() {
	/*
	 * Override Ext.form.TriggerField to add the spellcheck attribute to inputs
	 */
	Ext.override(Ext.form.TriggerField, {
	    /**
	     * @cfg {String/Object} autoCreate <p>A {@link Ext.DomHelper DomHelper} element spec, or true for a default
	     * element spec. Used to create the {@link Ext.Component#getEl Element} which will encapsulate this Component.
	     * See <tt>{@link Ext.Component#autoEl autoEl}</tt> for details.  Defaults to:</p>
	     * <pre><code>{tag: "input", type: "text", size: "16", autocomplete: "off"}</code></pre>
	     */
    	defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off", spellcheck: "true"}
	});
})();
(function() {
	var checkPerc = /^(100?|\d?\d)?%?$/;
	var checkNaturalInteger = /^[1-9]\d*$/i;
	// Override regex to allow TLD with max length of 10 characters
	var email = /^(\w+)([\-+.\'][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,10}$/;

	/**
	 * @class Ext.form.VTypes
	 * This will apply the custom vtype which is used to check
	 * given percentage must be between 0 to 100.
	 * @singleton
	 */
	Ext.apply(Ext.form.VTypes, {
		/**
		 * Used to validate the given percentage value must be between 0 to 100.
		 * and also check that value is not float.
		 * @param {Number} perc the perc is represent percentage value from field.
		 * @return {Boolean} return true if given percentage value matches
		 * with regular expression else return false.
		 */
		percentage : function(perc) {
			return checkPerc.test(perc);
		},

		//The error text to display when the validation function returns false
		percentageText: _('Value must be between 0% to 100%'),

		/**
		 * Used to validate the given value must be a whole number of one or higher
		 * @param {Number} value the value of the spinner field
		 * @return {Boolean} return true if the value is one or higher,
		 * else return false.
		 */
		naturalInteger: function(value)
		{
			return checkNaturalInteger.test(value);
		},

		// The error text to display when the validation function returns false
		naturalIntegerText: _('Number must be higher than zero'),

		/**
		 * The function used to validate email addresses.  Note that this is a very basic validation -- complete
		 * validation per the email RFC specifications is very complex and beyond the scope of this class, although
		 * this function can be overridden if a more comprehensive validation scheme is desired.  See the validation
		 * section of the <a href="http://en.wikipedia.org/wiki/E-mail_address">Wikipedia article on email addresses</a>
		 * for additional information.  This implementation is intended to validate the following emails:<tt>
		 * 'barney@example.de', 'barney.rubble@example.com', 'barney-rubble@example.coop', 'barney+rubble@example.com'
		 * </tt>.
		 * @param {String} value The email address
		 * @return {Boolean} true if the RegExp test passed, and false if not.
		 */
		'email' : function(v){
		    return email.test(v);
		}
	});
})();
(function() {
	var orig_setColumnWidth = Ext.grid.ColumnModel.prototype.setColumnWidth;

	Ext.override(Ext.grid.ColumnModel, {
		/**
		 * {@link Ext.grid.GridView#fitColumns fitColumns} has buggy behavior,
		 * which generates the fraction using division operation. When all columns 
		 * are disable (except fixed width columns), then fraction is "Infinity" 
		 * because the division operation is performed with "0". So to overcome this problem
		 * we check that width should not be infinite.
		 * 
		 * @param {Number} col The column index
		 * @param {Number} width The new width
		 * @param {Boolean} suppressEvent True to suppress firing the <code>{@link #widthchange}</code>
		 * event. Defaults to false.
		 */
		setColumnWidth : function(col, width, suppressEvent)
		{
			if(isFinite(width)) {
				orig_setColumnWidth.apply(this, arguments);
			}
		}
	});
})();(function() {
	var orig_onClick = Ext.grid.GridPanel.prototype.onClick;

	Ext.override(Ext.grid.GridPanel, {
		/*
		 * Override onClick to fix an issue that clicking on an
		 * already selected row will not put the focus on the grid itself. This
		 * prevents key-control to work properly on a grid.
		 */
		onClick : function(e)
		{
			orig_onClick.apply(this, arguments);

			// Don't change the focus when the user clicks on an input because
			// that would close a grid editor when one clicks on it
			var target = e.getTarget();
			if ( target.tagName !== 'INPUT' && target.className !== 'x-grid-group-title' && target.className !== 'x-grid-group-hd'){
				this.view.focusEl.focus();
			}
		},

		/*
		 * Override reconfigure to fix an issue that reconfiguring grid with
		 * new column model and store, was not re-initializing the state to get state settings
		 * for column model.
		 */
		reconfigure : function(store, colModel)
		{
			// initStateEvents registers 'hiddenchange' event on column model,
			// and we are going to change the column model, so we are here removing listener for hiddenchange event
			// and this will be again registered by initStateEvents for new column model
			if(this.stateful !== false && colModel !== this.colModel) {
				this.mun(this.colModel, 'hiddenchange', this.saveState, this);
			}

			var rendered = this.rendered;
			if(rendered){
				if(this.loadMask){
					this.loadMask.destroy();
					this.loadMask = new Ext.LoadMask(this.bwrap,
							Ext.apply({}, {store:store}, this.initialConfig.loadMask));
				}
			}

			if(this.view){
				this.view.initData(store, colModel);
			}

			this.store = store;
			this.colModel = colModel;

			// we have reconfigured column model, so re-apply state settings
			// that will change column order in column model
			if(this.stateful !== false) {
				this.initStateEvents();
				this.initState();
			}

			if(rendered){
				this.view.refresh(true);
			}

			this.fireEvent('reconfigure', this, store, colModel);
		}
	});
})();
(function() {
	var orig_onColConfigChange = Ext.grid.GridView.prototype.onColConfigChange;
	var orig_initTemplates = Ext.grid.GridView.prototype.initTemplates;

	Ext.override(Ext.grid.GridView, {
		/*
		 * Override the Ext.grid.GridView to fix an issue where the columns are rendered
		 * partally behind the scrollbar in Google Chrome. This is due to the fact that
		 * ExtJs assumes the borders take up no space in Chrome, while in fact they do.
		 */
		getColumnWidth : function(column)
		{
			var columnWidth = this.cm.getColumnWidth(column);
			var borderWidth = this.borderWidth;

			if (Ext.isNumber(columnWidth)) {
				// Original if-statement: Ext.isBorderBox || (Ext.isWebKit && !Ext.isSafari2)
				if (Ext.isBorderBox) {
					return columnWidth + 'px';
				} else {
					return Math.max(columnWidth - borderWidth, 0) + 'px';
				}
			} else {
				return columnWidth;
			}
		},

		/**
		 * Event handler for the {@link #cm}#{@link Ext.grid.ColumnModel#configchange configchange} event.
		 * This will call {@link Ext.grid.GridPanel#initState initState} on the {@link #grid}.
	 	 * @private
	 	 */
		onColConfigChange : function()
		{
			// Call initState on the gridpanel at this exact time, the superclass will
			// perform a layout on the applied configuration and needs the updated information.
			var grid = this.grid;

			if(grid.stateful !== false) {
				grid.initState();
			}

			orig_onColConfigChange.apply(this, arguments);
		},

	    /**
	     * @private
	     * Overriding this method so we can add a custom class to the header cells of the grid
	     * Provides default templates if they are not given for this particular instance. Most of the templates are defined on
	     * the prototype, the ones defined inside this function are done so because they are based on Grid or GridView configuration
	     */
	    initTemplates : function() {
			orig_initTemplates.apply(this);
	    	
	        var headerCellTpl = new Ext.Template(
	                '<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css} {cls}" style="{style}">',
	                    '<div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">', 
	                        this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
	                        '<div class="zarafa-x-grid3-hd-title">{value}</div>',
	                        '<img alt="" class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
	                    '</div>',
	                '</td>'
	           );
	           
	        headerCellTpl.disableFormats = true;
	        this.templates.hcell = headerCellTpl.compile();
	    },
	
	    /**
	     * @private
	     * Overriding this method so we can add a custom class to the header cells of the grid
	     * Renders the header row using the 'header' template. Does not inject the HTML into the DOM, just
	     * returns a string.
	     * @return {String} Rendered header row
	     */
	    renderHeaders : function() {
	        var colModel   = this.cm,
	            templates  = this.templates,
	            headerTpl  = templates.hcell,
	            properties = {},
	            colCount   = colModel.getColumnCount(),
	            last       = colCount - 1,
	            cells      = [],
	            i, cssCls;
	        
	        for (i = 0; i < colCount; i++) {
	            if (i == 0) {
	                cssCls = 'x-grid3-cell-first ';
	            } else {
	                cssCls = i == last ? 'x-grid3-cell-last ' : '';
	            }
	            
	            properties = {
	                id     : colModel.getColumnId(i),
	                value  : colModel.getColumnHeader(i) || '',
	                style  : this.getColumnStyle(i, true),
	                css    : cssCls,
	                tooltip: this.getColumnTooltip(i),
	                // NB: This is the only line we add to this method, but since Ext decided to define this properties array inline we have to overwrite the whole method. (sigh)
	                cls    : colModel.getColumnAt(i).headerCls || ''
	            };
	            
	            if (colModel.config[i].align == 'right') {
	                properties.istyle = 'padding-right: 16px;';
	            } else {
	                delete properties.istyle;
	            }
	            
	            cells[i] = headerTpl.apply(properties);
	        }
	        
	        return templates.header.apply({
	            cells : cells.join(""),
	            tstyle: String.format("width: {0};", this.getTotalWidth())
	        });
	    }
	});
})();
(function() {
	/**
	 * @class Ext
	 * Overridden to add checks for identifying Internet Explorer and it's latest versions
	 * @singleton
	 */
	var userAgentString = navigator.userAgent.toLowerCase();
	var isIE = !Ext.isOpera && (((/msie/).test(userAgentString)) || ((/trident/).test(userAgentString)));
	var orig_getDom = Ext.getDom;

	Ext.apply(Ext, {
		/**
		 * True if the detected browser is Internet Explorer.
		 * @type Boolean
		 * @property
		 */
		isIE : isIE,

		/**
		 * True if the detected browser is Internet Explorer 10.
		 * @type Boolean
		 * @property
		 */
		isIE10 : isIE && ((/msie 10/).test(userAgentString)),

		/**
		 * True if the detected browser is Internet Explorer 11.
		 * @type Boolean
		 * @property
		 */
		isIE11 : isIE && ((/rv:11/).test(userAgentString)),

		/**
		 * True if the detected browser is Microsoft Edge.
		 * @type Boolean
		 * @property
		 */
		isEdge : (/Edge\/\d./i).test(navigator.userAgent),

		/**
		 * Clone almost any type of variable including array, object, DOM nodes and Date without keeping the old reference
		 * @param {Mixed} item The variable to clone
		 * @return {Mixed} clone
		 */
		clone: function(item) {
			if (item === null || item === undefined) {
				return item;
			}

			// DOM nodes
			// TODO proxy this to Ext.Element.clone to handle automatic id attribute changing
			// recursively
			if (item.nodeType && item.cloneNode) {
				return item.cloneNode(true);
			}

			var type = Object.prototype.toString.call(item);

			// Date
			if (type === '[object Date]') {
				return new Date(item.getTime());
			}

			var clone;

			// Array
			if (type === '[object Array]') {
				var i = item.length;

				clone = [];

				while (i--) {
					clone[i] = Ext.clone(item[i]);
				}
			}
			// Object
			else if (type === '[object Object]' && item.constructor === Object) {
				clone = {};

				for (var key in item) {
					clone[key] = Ext.clone(item[key]);
				}
			}
			return clone || item;
		},

		/**
		 * Override isArray, to use the native browser function
		 *
	 	 * @param {Mixed} value The value to test
		 * @return {Boolean}
		 */
		isArray: function(v) {
			return Array.isArray(v);
		},

		/*
		 * Override getDom to consider separate window as well while getting HTMLElement of provided id.
		 * 
		 * @param {Mixed} el The id string or DOM element
		 * @return {HTMLElement} HTMLElement
		 */
		getDom : function(el) {
			var getDomResult = null;
			var activeBrowserWindow = Zarafa.core.BrowserWindowMgr.getActive();

			// First, search for the element in active window only if browser window manager has active window available
			// and is not the main webapp window.
			if(Ext.isDefined(activeBrowserWindow) && activeBrowserWindow.name !== 'mainBrowserWindow' && typeof el === 'string') {
				getDomResult = activeBrowserWindow.document.getElementById(el);
			}

			// The element not found in active window which is not the main webapp window.
			// Try to search the element in main webapp window.
			if(getDomResult === null) {
				getDomResult = orig_getDom.apply(this, arguments);
			}

			// Check if the result of original getDom method is empty/null.
			// If the element is not found in 'webapp main window DOM' and 'active window' then the element must belongs to
			// other separately created window, try to look there as well.
			if(getDomResult === null && typeof el === 'string') {
				var browserWindows = Zarafa.core.BrowserWindowMgr.browserWindows;
				if(Ext.isDefined(browserWindows)) {
					browserWindows.each(function(browserWindow) {
						var elementResult = browserWindow.document.getElementById(el);
						if(browserWindow.name !== 'mainBrowserWindow' && browserWindow !== activeBrowserWindow && !(elementResult === null)) {
							getDomResult = elementResult;
							return;
						}
					});
				}
			}

			return getDomResult;
		},

		/*
		 * Override getBody to return the body element of currently active browser
		 * window from all the available browser windows.
		 * @return {Ext.Element} The document body of the currently active browser window.
		 */
		getBody : function(){
			var activeBrowserWindow = Zarafa.core.BrowserWindowMgr.getActive();
			var documentObject = Ext.isDefined(activeBrowserWindow) ? activeBrowserWindow.document : document;
			return Ext.get(documentObject.body || documentObject.documentElement);
		},

		/**
		 * Returns the current HTML document object as an {@link Ext.Element} which belongs to the active browser window.
		 * @return Ext.Element The document object wrapped as (@link Ext.Element}
		 */
		getDoc : function(){
			var activeBrowserWindow = Zarafa.core.BrowserWindowMgr.getActive();
			var documentObject = Ext.isDefined(activeBrowserWindow) ? activeBrowserWindow.document : document;
			return Ext.get(documentObject);
		}
	});
})();
(function() {
	/*
	 * Fix the BorderLayout#Region class, whenever the region is collapsed, we should
	 * hide the split element in such a way it will not be considered by the browser
	 * for sizing/positioning. By default the BorderLayout#region would apply "visibility: none" 
	 * to the style of the CSS element. However due to a bug in Extjs the splitEl would have
	 * a greater height then the MainViewPort element. As a result the entire WebApp could be
	 * scrolled up partially out of the view of the user. This occurred primarily when using
	 * debugging tools...
	 */
	var orig_beforeCollapse = Ext.layout.BorderLayout.Region.prototype.beforeCollapse;
	var orig_onExpand = Ext.layout.BorderLayout.Region.prototype.onExpand;
	Ext.override(Ext.layout.BorderLayout.Region, {
		// Instead of only applying "visibility: none" to the splitEl,
		// we apply the x-hide-display CSS class to prevent that the element
		// still occupies space during rendering.
		beforeCollapse : function()
		{
			if (this.splitEl) {
				this.splitEl.addClass('x-hide-display');
			}
			orig_beforeCollapse.apply(this, arguments);
		},

		// Remove the x-hide-display CSS class again.
		onExpand : function()
		{
			if (this.splitEl) {
				this.splitEl.removeClass('x-hide-display');
			}
			orig_onExpand.apply(this, arguments);
		}
	});
})();
(function() {
 	var orig_configureItem = Ext.layout.ToolbarLayout.prototype.configureItem;
 	var orig_hideItem = Ext.layout.ToolbarLayout.prototype.hideItem;
 	var orig_unhideItem = Ext.layout.ToolbarLayout.prototype.unhideItem;
	var orig_onLayout = Ext.layout.ToolbarLayout.prototype.onLayout;
	var orig_addComponentToMenu = Ext.layout.ToolbarLayout.prototype.addComponentToMenu;
	Ext.override(Ext.layout.ToolbarLayout, {
		// Fix the trigger width, Extjs defines it as 18 which only covers the '>>' button, but not
		// the padding for the trigger button itself.
		triggerWidth : 41,

		// The tabIndex that should be applied to the 'more' button when the toolbar overflows
		overflowTabIndex : undefined,

		/*
		 * Fix that the ToolbarLayout will go over all items in the container
		 * and check if those items contains layouts which need to be called as
		 * well. This ensures that the ToolbarLayout is capable of containing
		 * other Containers as well.
		 */
		onLayout : function(ct, target) 
		{
			orig_onLayout.apply(this, arguments);
			ct.items.each(function(item) {
				if (Ext.isFunction(item.doLayout)) {
					item.doLayout();
				}
			}, this);

			if (this.overflowTabIndex && this.more) {
				Ext.get(this.more.el).child('button').set({ 'tabIndex' : this.overflowTabIndex });
			}
		},

		/*
		 * Override configureItem to hook the 'show' and 'hide'
		 * event handlers to the items. This allows us to peform
		 * a layout of the items when one of them is being hidden
		 * or shown (as this means we have to consider moving items
		 * into or out of the overflow menu).
		 */
		configureItem : function(item)
		{
			var ct = this.container;
			var target = ct.getLayoutTarget();

			orig_configureItem.apply(this, arguments);

			item.on('show', function(item) {
				if (item.xtbHidden !== true) {
					this.onLayout(ct, target);
				}
			}, this);

			item.on('hide', function(item) {
				if (item.xtbHidden !== true) {
					this.onLayout(ct, target);
				}
			}, this);
		},

		/*
		 * Override the hideItem function, when the item is placed in the overflow menu,
		 * we do want to remain in touch with the "show" and "hide" requests from the
		 * component itself. Because in those cases we want to ensure that the item
		 * is removed or added into the overflow menu.
		 */
		hideItem : function(item)
		{
			var layout = this;
			orig_hideItem.apply(this, arguments);

			// When showing a previously hidden item,
			// them we must update the xtbWidth to ensure that
			// the toolbar knows if the item must be removed
			// from the overflow menu or not.
			item.xtbOrigShow = item.show;
			item.show = function() {
				item.xtbOrigShow(true);
				item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth;
				item.xtbOrigHide(false);
			}

			// When we are hiding an item in the overflow menu,
			// we must unhide it, and invoke the real hide function
			// to make it invisible.
			item.xtbOrigHide = item.hide;
			item.hide = function() {
				layout.unhideItem(item);
				item.hide();
			}
		},

		/*
		 * Override the unhideItem function to ensure we restore
		 * the "show" and "hide" function to the original implementation again.
		 */
		unhideItem : function(item)
		{
			item.show = item.xtbOrigShow;
			delete item.xtbOrigShow;

			item.hide = item.xtbOrigHide;
			delete item.xtbOrigHide;

			// Another bug from Extjs, the xtbWidth must be
			// removed when unhiding, as otherwise the layout
			// will still try to use it when the item must
			// be completely hidden.
			delete item.xtbWidth;

			orig_unhideItem.apply(this, arguments);
		},

		/*
		 * Fix that hidden items inside a buttongroup will be rendered into the
		 * overflow menu. This happens because only the top components in the
		 * toolbar will be marked with 'xtbHidden' which indicates that the 'hidden'
		 * state should be ignored because the toolbar has hidden the item.
		 * However the items below are added regardless of their 'hidden' status.
		 * This fix will not only check for xtbHidden, but also for the normal
		 * 'hidden' flag before deciding to render the item into the menu.
		 * And It will check if the toolbar item has menu and splitOnMoreMenu is set then extract all items of menu and
		 * add those items into more menu.
		 */
		addComponentToMenu : function(menu, component)
		{
			if (component.xtbHidden === true || component.hidden !== true) {

				// Check if component has menu then extract all items of menu and add into more menu
				if(Ext.isDefined(component.menu) && component.splitOnMoreMenu){
					var items = component.menu.items.items;
					Ext.each(items,function (item) {
						var config = this.createMenuConfig(item);
						if(item.isXType('menucheckitem')) {
							config.xtype = item.xtype;
							var store = item.model.store;
							if (store.hasFilterApplied) {
								config.iconCls = "";
								config.checked = true;
							}
						}
						menu.add(config);
					},this);
				} else {
					orig_addComponentToMenu.apply(this, arguments);
				}
			}
		},

		/**
		 * Override initMore to replace {@link Ext.Button More button} with our own button
		 * @private
		 * Creates the expand trigger and menu, adding them to the <tr> at the extreme right of the
		 * Toolbar table
		 */
		initMore : function ()
		{
			if (!this.more) {
				/**
				 * @private
				 * @property moreMenu
				 * @type Ext.menu.Menu
				 * The expand menu - holds items for every Toolbar item that cannot be shown
				 * because the Toolbar is currently not wide enough.
				 */
				this.moreMenu = new Ext.menu.Menu({
					ownerCt : this.container,
					listeners: {
						beforeshow: this.onBeforeShowMoreMenu,
						scope: this
					}
				});

				/**
				 * @private
				 * @property more
				 * @type Ext.Button
				 * The expand button which triggers the overflow menu to be shown
				 */
				this.more = new Ext.Button({
					iconCls: 'icon_more',
					ownerCt: this.container,
					tooltip: _('More options'),
					overflowText: _('More options'),
					listeners : {
						afterrender : this.afterMoreButtonRender,
						scope : this
					}
				});

				var td = this.insertCell(this.more, this.extrasTr, 100);
				this.more.render(td);
			}
		},

		/**
		 * Handler which is use to add menu in more button after the {@link Ext.Button} rendered
		 * @param button
         */
		afterMoreButtonRender : function (button)
		{
			// Ext will add down arrow button on render time if the button has menu
			// So, set the menu after the more button rendered successfully
			button.menu = this.moreMenu
		},

		/**
		 * Event handler for the {@link #beforeshow} event. This will go through all
		 * {@link Zarafa.core.ui.menu.ConditionalItem items} in the menu and call the
		 * {@link Zarafa.core.ui.menu.ConditionalItem#beforeShow} function.
		 *
		 * @param {Zarafa.core.ui.menu.ConditionalMenu} menu The menu which is being opened.
		 * @private
		 */
		onBeforeShowMoreMenu : function (menu)
		{
			this.beforeMoreShow(menu);
			// move over the items list and call 'beforeOpen' on each item if that function exists
			menu.items.each(function (item) {
				if (Ext.isFunction(item.beforeShow)) {
					item.beforeShow.call(item.scope || item, item);
				}
			}, this);
		}
	});
})();
(function() {
	var orig_addComponentToMenu = Ext.layout.boxOverflow.Menu.prototype.addComponentToMenu;
	Ext.override(Ext.layout.boxOverflow.Menu, {
		/*
		 * Fix that hidden items inside a buttongroup will be rendered into the
		 * overflow menu. This happens because only the top components in the
		 * toolbar will be marked with 'xtbHidden' which indicates that the 'hidden'
		 * state should be ignored because the toolbar has hidden the item.
		 * However the items below are added regardless of their 'hidden' status.
		 * This fix will not only check for xtbHidden, but also for the normal
		 * 'hidden' flag before deciding to render the item into the menu. 
		 */
		addComponentToMenu : function(menu, component)
		{
			if (component.xtbHidden === true || component.hidden !== true) {
				orig_addComponentToMenu.apply(this, arguments);
			}
		}
	});
})();
(function() {
	/*
	 * Overridden to destroy the menu when it does not have an owner component.
	 */
	var orig_constructor = Ext.menu.Menu.prototype.constructor;

	Ext.override(Ext.menu.Menu, {
		constructor : function() {
			orig_constructor.apply(this, arguments);
			this.on('hide', this.onMenuHide, this);
		},

		/**
		 * Event handler for the {@link #hide} event. It will destroy the menu when it does not have an owner component.
		 * Since the UIFactory creates a new menu on each contextclick, we must make sure the menu's are also destroyed
		 * again when they are hidden, or else we will pollute the dom with abandoned menus.
		 * Child menus will be destroyed when their parent is destroyed.
		 *
		 * @param {Ext.menu.Menu} menu The menu which is being hidden.
		 * @private
		 */
		onMenuHide : function(menu)
		{
			// Check if the menu has an owner component (only context menu's don't have it)
			if (!Ext.isDefined(menu.ownerCt) && !Ext.isDefined(menu.parentMenu) && menu.autoDestroy) {
				menu.destroy();
			}
		}
	});
})();
(function() {
	/**
	 * @class Ext.state.Manager
	 * This is the global state manager. By default all components that are "state aware" check this class
	 * for state information if you don't pass them a custom state provider. In order for this class
	 * to be useful, it must be initialized with a provider when your application initializes. Example usage:
	 <pre><code>
	 // in your initialization function
	init : function(){
	    Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
	    var win = new Window(...);
	    win.restoreState();
	}
	 </code></pre>
	 * @singleton
	 */
	Ext.apply(Ext.state.Manager, {

		/**
		 * The list of {@link Ext.Component#stateful stateful} components
		 * This can be used by {@link Ext.state.Provider State providers} to
		 * {@link #getComponent obtain} the {@link Ext.Component} which corresponds
		 * to the given stateId.
		 * @property
		 * @type Ext.util.MixedCollection
		 * @private
		 */
		components : new Ext.util.MixedCollection(false, function(item) {
			return item.getStateId();
		}),

		/**
		 * Register the {@link Ext.Component#stateful stateful} {@link Ext.Component}
		 * to the {@link #components} list.
		 * @param {Ext.Component} component The component to register
		 */
		register : function(component)
		{
			this.components.add(component);
		},

		/**
		 * Unregister a previously {@link #register registered} {@link Ext.Component}
		 * from the {@link #components}.
		 * @param {Ext.Component} component The component to unregister
		 */
		unregister : function(component)
		{
			this.components.remove(component);
		},

		/**
		 * Obtain a previously {@link #register registered} {@link Ext.Component}
		 * by the components {@link Ext.Component#getStateId State Id}.
		 * @param {String} stateId The stateId for the component
		 * @return {Ext.Component} The registered component
		 */
		getComponent : function(stateId)
		{
			return this.components.get(stateId);
		}
	});
})();
(function() {
	/*
	 * Adds the ability to conditionally allow focusing the node.
	 * This will automatically move the scroll bar to make sure that given node will
	 * be visible. Passing ensureFocus as false prevent this mechanism.
	 */
	Ext.override(Ext.tree.DefaultSelectionModel, {
		/**
		 * Select a node.
		 * @param {TreeNode} node The node to select
		 * @param {Boolean} ensureFocus True to make given folder visible in screen by focusing it.
		 * @return {TreeNode} The selected node
		 */
		select : function(node, /* private*/ selectNextNode, ensureFocus){
			// If node is hidden, select the next node in whatever direction was being moved in.
			if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) {
				return selectNextNode.call(this, node);
			}
			var last = this.selNode;
			if(node == last){
				if (ensureFocus || !Ext.isDefined(ensureFocus)) {
					node.ui.onSelectedChange(true);
				} else {
					node.ui.addClass("x-tree-selected");
				}
			}else if(this.fireEvent('beforeselect', this, node, last) !== false){
				if(last && last.ui){
					last.ui.onSelectedChange(false);
				}
				this.selNode = node;
				node.ui.onSelectedChange(true);
				this.fireEvent('selectionchange', this, node, last);
			}
			return node;
		}
	});
})();
(function() {
	/*
	 * Fix the Ext.tree.TreeEditor, the fitToTree and bindScroll are called with a small delay,
	 * and unfortunately ExtJs doesn't care that objects can be destroyed while
	 * a function which expects that object is deferred.
	 */
	var orig_bindScroll = Ext.tree.TreeEditor.prototype.bindScroll;
	var orig_fitToTree = Ext.tree.TreeEditor.prototype.fitToTree;

	Ext.override(Ext.tree.TreeEditor, {
		fitToTree : function()
		{
			if (this.tree && this.tree.isDestroyed !== true) {
				orig_fitToTree.apply(this, arguments);
			}
		},

		bindScroll : function()
		{
			if (this.tree && this.tree.isDestroyed !== true) {
				orig_bindScroll.apply(this, arguments);
			}
		}
	});
})();
(function() {
	/*
	 * Fix the Ext.tree.TreeSorter, the doSort function is always deferred
	 * by ExtJs, but unfortunately it doesn't keep in mind that the node
	 * could have been destroyed before the function is being called...
	 */
	Ext.override(Ext.tree.TreeSorter, {
		doSort : function(node)
		{
			// Check if the node has children which
			// can be sorted.
			if (node.childNodes) {
				var activeElement = document.activeElement;
				node.sort(this.sortFn);
				// If the former active element still exist, give it the focus again.
				// Except when the active element is an iframe, because that could
				// cause strange behaviour in IE and EDGE. (i.e if the focus was
				// inside the tinymce editor, after focussing the iframe the SPACE and
				// ENTER keys would not work anymore)
				if ( activeElement  && activeElement.tagName!=='IFRAME' ){
					activeElement.focus();
				}
			}
		}
	});
})();
(function() {
	/**
	 * @class Ext.util.Format
	 * Reusable data formatting functions
	 * @singleton
	 */
	Ext.apply(Ext.util.Format, {
		/**
		 * Simple format for a file size (xxx bytes, xxx KB, xxx MB)
		 * @param {Number/String} size The numeric value to format
		 * @return {String} The formatted file size
		 */
		fileSize : function(size)
		{
			if (!Ext.isNumber(size)) {
				size = 0;
			}

			if (size < 1024) {
				return String.format(ngettext('{0} byte', '{0} bytes', size), size);
			}

			size = parseFloat((size / 1024).toFixed(1));
			if (size < 1024) {
				return String.format(ngettext('{0} KB', '{0} KB', size), size);
			}

			size = parseFloat((size / 1024).toFixed(1));
			if (size < 1024) {
				return String.format(ngettext('{0} MB', '{0} MB', size), size);
			}

			size = parseFloat((size / 1024).toFixed(1));
			if (size < 1024) {
				return String.format(ngettext('{0} GB', '{0} GB', size), size);
			}

			size = parseFloat((size / 1024).toFixed(1));
			return String.format(ngettext('{0} TB', '{0} TB', size), size);
		},

		/**
		 * Returns a string version of a float number as a percentage.
		 * @param {Float} value A number in the range [0..1]
		 * @param {Number} fixed optional, The number of digits in the percentage, defaults to 2.
		 * @return {String} Formatted percentage string
		 */
		percentage: function(value, fixed)
		{
			if (!Ext.isDefined(fixed)) {
				fixed = 2;
			}
			return (value * 100.0).toFixed(fixed) + "%";
		},

		/**
		 * Generate a string which represents a duration (xx minutes, xx hours, etc)
		 * @param {Number} value The duration (in minutes)
		 * @param {Number} decimals When rounding, how many decimals should be used
		 * @return {String} The formatted duration
		 */
		duration : function(value, decimals)
		{
			decimals = Ext.isDefined(decimals) ? decimals : 0;

			// Duration is less then an hour, print the number of minutes
			if (value < 60) {
				return String.format(ngettext('{0} minute', '{0} minutes', value), value);
			}

			// Duration is less then a day, print the number of hours
			// rounded to the requested number after the decimal point.
			value = parseFloat((value / 60).toFixed(decimals));
			if (value < 24) {
				return String.format(ngettext('{0} hour', '{0} hours', value), value);
			}

			// Duration is less then a week, print the number of days
			// rounded to the requested number after the decimal point.
			value = parseFloat((value / 24).toFixed(decimals));
			if (value < 7) {
				return String.format(ngettext('{0} day', '{0} days', value), value);
			}

			// Duration is one week or more, print the number of weeks
			// rounded to the requested number after the decimal point.
			value = parseFloat((value / 7).toFixed(decimals));
			return String.format(ngettext('{0} week', '{0} weeks', value), value);
		},

		/**
		 * Generate a string which can be used for indentation in the HTML.
		 * @param {Number} value The number of tabs to indent
		 * @param {Number} size (optional) The number of spaces per tab which should be generated
		 * @return {String} A string containing multiple '&nbsp' strings
		 */
		indent : function(value, size)
		{
			var spaces = (Ext.isDefined(value) ? value : 1) * (Ext.isDefined(size) ? size : 4);
			var indent = '';

			for (var i = 0; i < spaces; i++) {
				indent += '&nbsp;';
			}

			return indent;
		},

		/**
		 * Truncate a string from the middle and add an ellipsis ('...') in between.
		 * length of the string before and after ellipsis ('...') are specified in
		 * function parameters.
		 * @param {String} value The string to truncate
		 * @param {Number} startLength The maximum length to allow before truncation
		 * @param {Number} endLength The maximum length to allow after truncation
		 * @param {Boolean} doubleDots True to add ellipsis ('..') otherwise add ellipsis ('...') after truncation
		 * @return {String} The converted/truncated text
		 */
		elide : function(value, startLength, endLength, doubleDots)
		{
			var ellipsis = doubleDots ? '..' : '...';
			startLength = startLength || 0;
			endLength = Ext.isDefined(endLength) ? endLength : startLength;

			if (startLength === 0 && endLength === 0) {
				return value;
			}

			if (value && value.length > startLength + endLength) {
				return value.substr(0, startLength) + ellipsis + value.substr(value.length - endLength);
			}
			return value;
		},

		/**
		 * Combination of {@link #htmlEncode} and {@link #undef}.
		 * @param {String} value The string to encode
		 * @return {String} The htmlEncoded text
		 */
		htmlEncodeUndef : function(value)
		{
			return this.htmlEncode(this.undef.apply(this, arguments));
		},

		/**
		 * Combination of {@link #htmlEncode} and {@link #defaultValue}.
		 * @param {String} value The string which will be first replaced by defaultValue if it is empty / undefined
		 * and then it will be encoded.
		 * @return {String} The htmlEncoded text.
		 */
		htmlEncodeDefaultValue : function(value, defaultValue)
		{
			return this.htmlEncode(this.defaultValue.apply(this, arguments));
		},

		/**
		 * Combination of {@link #htmlEncode} and {@link #elide}.
		 * @param {String} value The string to truncate
		 * @param {Number} startLength The maximum length to allow before truncation
		 * @param {Number} endLength The maximum length to allow after truncation
		 * @param {Boolean} doubleDots True to add ellipsis ('..') otherwise add ellipsis ('...') after truncation
		 * @return {String} The htmlEncoded and truncated text
		 */
		htmlEncodeElide : function(value, startLength, endLength, doubleDots)
		{
			return this.htmlEncode(this.elide.apply(this, arguments));
		},

		/**
		 * Combination of {@link #htmlEncode} and {@link #ellipsis}.
		 * @param {String} value The string to truncate
		 * @param {Number} length The maximum length to allow before truncating
		 * @param {Boolean} word True to try to find a common work break
		 * @return {String} The converted text
		 */
		htmlEncodeEllipsis : function(value, len, word)
		{
			return this.htmlEncode(this.ellipsis.apply(this, arguments));
		},

		/**
		 * Obtain the basename (filename) from the given string. This will remove
		 * everything which came before the last '\' character.
		 * @param {String} value The filename for which the basename is requested
		 * @return {String} The basename
		 */
		basename : function(value)
		{
			return value.split('\\').pop();
		},

		/**
		 * Combination of {@link #htmlEncode} and {@link #basename}.
		 * @param {String} value The filename for which the basename is requested
		 * @return {String} The htmlEncoded basename
		 */
		htmlEncodeBasename : function(value)
		{
			return this.htmlEncode(this.basename.apply(this, arguments));
		},

		/**
		 * Returns a translated string version for PR_SENSITIVITY
		 * @param {Number} value Value in PR_SENSITIVITY
		 * @return {String} Human readable sensitivity
		 */
		sensitivityString: function(value)
		{
			return Zarafa.core.mapi.Sensitivity.getDisplayName(value);
		},

		/**
		 * Returns a translated string version for PR_IMPORTANCE
		 * @param {Number} value Value in PR_IMPORTANCE
		 * @return {String} Human readable importance
		 */
		importanceString: function(value)
		{
			return Zarafa.core.mapi.Importance.getDisplayName(value);
		},

		/**
		 * Returns a translated string version for MeetingStatus property
		 * @param {Number} value Value in MeetingStatus
		 * @return {String} Human readable meeting status
		 */
		meetingStatusString: function(value)
		{
			return Zarafa.core.mapi.MeetingStatus.getDisplayName(value);
		},

		/**
		 * Returns a translated string version for ResponseStatus property
		 * @param {Number} value Value in ResponseStatus
		 * @return {String} Human readable response status
		 */
		responseStatusString: function(value)
		{
			return Zarafa.core.mapi.ResponseStatus.getDisplayName(value);
		},

		/**
		 * Returns a translated string version for Task status property
		 * @param {Number} value Enum value in TaskStatus
		 * @return {String} Human readable task status
		 */
		taskStatusString: function(value)
		{
			return Zarafa.core.mapi.TaskStatus.getDisplayName(value);
		},

		/**
		 * Returns a translated string version for busy status property
		 * @param {Number} value Enum value in BusyStatus
		 * @return {String} Human readable busy status
		 */
		busyStatusString: function(value)
		{
			return Zarafa.core.mapi.BusyStatus.getDisplayName(value);
		}
	});
})();
(function() {
	/*
	 * Override @class Ext.ux.Spinner class
	 * so that click event on trigger is actually fired after mousedown/mouseup has been called and
	 * focus has been shifted to the {@link Ext.form.TriggerField TriggerField}
	 */
	Ext.override(Ext.ux.Spinner, {
		doRender: function(ct, position){
			var el = this.el = this.field.getEl();
			var f = this.field;

			if (!f.wrap) {
				f.wrap = this.wrap = el.wrap({
					cls: "x-form-field-wrap"
				});
			}
			else {
				this.wrap = f.wrap.addClass('x-form-field-wrap');
			}

			this.trigger = this.wrap.createChild({
				tag: "img",
				src: Ext.BLANK_IMAGE_URL,
				cls: "x-form-trigger " + this.triggerClass
			});
			if (!f.width) {
				this.wrap.setWidth(el.getWidth() + this.trigger.getWidth());
			}

			this.splitter = this.wrap.createChild({
				tag: 'div',
				cls: this.splitterClass,
				style: 'width:13px; height:2px;'
			});
			this.splitter.setRight((Ext.isIE) ? 1 : 2).setTop(10).show();

			if(!Ext.isEmpty(f.boxLabel)){
				this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: f.boxLabel});
			}

			this.proxy = this.trigger.createProxy('', this.splitter, true);
			this.proxy.addClass("x-form-spinner-proxy");
			this.proxy.setStyle('left', '0px');
			this.proxy.setSize(14, 1);
			this.proxy.hide();
			this.dd = new Ext.dd.DDProxy(this.splitter.dom.id, "SpinnerDrag", {
				dragElId: this.proxy.id
			});

			this.initTrigger();
			this.initSpinner();
		},
		initSpinner: function(){
			this.field.addEvents({
				'spin': true,
				'spinup': true,
				'spindown': true
			});

			this.keyNav = new Ext.KeyNav(this.el, {
				"up": function(e){
					e.preventDefault();
					this.onSpinUp();
				},

				"down": function(e){
					e.preventDefault();
					this.onSpinDown();
				},

				"pageUp": function(e){
					e.preventDefault();
					this.onSpinUpAlternate();
				},

				"pageDown": function(e){
					e.preventDefault();
					this.onSpinDownAlternate();
				},

				scope: this
			});

			// this code has beenchanged to listen on click event of trigger instead of
			// listening on click event of Ext.util.ClickRepeater which is fired on mousedown event
			this.field.mon(this.trigger, 'click', this.onTriggerClick, this, {
				preventDefault: true
			});

			this.field.mon(this.trigger, {
				mouseover: this.onMouseOver,
				mouseout: this.onMouseOut,
				mousemove: this.onMouseMove,
				mousedown: this.onMouseDown,
				mouseup: this.onMouseUp,
				scope: this,
				preventDefault: true
			});

			this.field.mon(this.wrap, "mousewheel", this.handleMouseWheel, this);

			this.dd.setXConstraint(0, 0, 10)
			this.dd.setYConstraint(1500, 1500, 10);
			this.dd.endDrag = this.endDrag.createDelegate(this);
			this.dd.startDrag = this.startDrag.createDelegate(this);
			this.dd.onDrag = this.onDrag.createDelegate(this);
		}
	});
})();
Ext.namespace('Zarafa.util');

// This class is defined counter-intuitively in extjs-mod,
// because we need the utility function in both extjs-mod as
// well as the WebApp core.

/**
 * @class Zarafa.util.Translations
 * @extends Object
 * Utility class containing utility functions for creating
 * translation strings.
 */
Zarafa.util.Translations = {
	msg: _('The quick brown fox jumps over the lazy dog'),

	/**
	 * This will split a translation string up into different sections.
	 * The intension is to fix problems which might occur when two labels
	 * are used to construct a full sentence, this could happen with for example
	 * paging, where the translation string is "Page X of Y" where the used labels
	 * are: "Page" and "of Y". Obviously this will not translate correctly for
	 * all languages and thus we must attempt to translate the full string, and
	 * split it up ourselves, so we can provide the correct sentences to ExtJs.
	 *
	 * @param {String} translation The translation string which must be split
	 * @param {String} split The separation string which must be found in 'translation'
	 * @return {Array} Array of strings, the first element is the translation string
	 * which comes before the 'split' and the second element is the translation string
	 * which comes after the 'split'. Note that 'split' itself is not within the result.
	 * @static
	 */
	SplitTranslation : function(translation, split)
	{
		if (!Ext.isDefined(split)) {
			return translation;
		}

		var index = translation.indexOf(split);
		if (index == -1) {
			return translation;
		}

		// Find the last non-space character before the split-string
		var endFirst = index - 1;
		while (translation[endFirst] == ' ' && endFirst >= 0) {
			endFirst--;
		}

		// Find the first non-space character after the split-string
		var startSecond = index + split.length;
		while (translation[startSecond] == ' ' && startSecond < translation.length) {
			startSecond++;
		}

		return [
			translation.substr(0, endFirst + 1),
			translation.substr(startSecond)
		];
	},

	/**
	 * This will split a translation string up into different sections.
	 * The intension is to fix problems which might occur when more then two labels
	 * are used to construct a full sentence, this could happen with for example
	 * recurrence where the translation string is 'Every X Y of every Z month(s)'.
	 * We don't want to translate 'Every', 'of every' and 'month(s)' separately.
	 * Instead we want to translate the full String. And split the translated
	 * string up into the multiple labels.
	 *
	 * @param {String} translation The translation string which must be split
	 * @param {Array} split The separation strings which must be found in 'translation'
	 * @return {Array} Array of strings This contains all pieces of the translation,
	 * including the split strings. 'Every X Y of every Z month(s)' will be returned as:
	 * [ 'Every', 'X', 'Y', 'of every', 'Z', 'month(s)' ].
	 * @static
	 */
	MultiSplitTranslation : function(translation, split)
	{
		// Split must always be an array
		if (!Ext.isArray(split)) {
			split = [ split ];
		}

		// Prepare our translated pieces, by default the
		// main translation string is our piece
		var pieces = new Ext.util.MixedCollection();
		pieces.add(translation);

		// Time for some magic, for each split string, we are going
		// to loop through all pieces until we find the first piece
		// which contains our split string. We then remove the piece
		// and replace it with the result from SplitTranslation
		// with a reference to which split string we have found.
		for (var i = 0; i < split.length; i++) {
			pieces.each(function(piece, index) {
				// Let SplitTranslation determine if the
				// split string is inside this piece. If it isn't then it will
				// return a single string.
				var splitPiece = Zarafa.util.Translations.SplitTranslation(piece, split[i]);
				if (!Ext.isArray(splitPiece)) {
					return true;
				}

				// Remove the old piece, we are replacing it with
				// the new pieces.
				pieces.removeAt(index);

				// Depending on the translation it could happen that either
				// the first or the second piece is empty...
				if (!Ext.isEmpty(splitPiece[0])) {
					pieces.insert(index, splitPiece[0]);
					index++;
				}

				// Always insert the reference to the split string which
				// we have found.
				pieces.insert(index, split[i]);
				index++;

				if (!Ext.isEmpty(splitPiece[1])) {
					pieces.insert(index, splitPiece[1]);
					index++;
				}

				// We're done, we don't support the same split string
				// multiple times in the same string.
				return false;
			});
		}

		return pieces.getRange();
	}
};

// This document contains all translations of ExtJs components,
// translations are done using Ext.Override and must _only_ override
// the strings within an ExtJs component.
(function() {
	Ext.apply(Date, {
		dayNames : [
			_('Sunday'),
			_('Monday'),
			_('Tuesday'),
			_('Wednesday'),
			_('Thursday'),
			_('Friday'),
			_('Saturday')
		],

		// The shortDayNames are not defined in Ext and thus technically shouldn't
		// be part of this file. But since they are so connected to the dayNames,
		// it seems most logical to place them here.
		shortDayNames : [
			_('Sun'),
			_('Mon'),
			_('Tue'),
			_('Wed'),
			_('Thu'),
			_('Fri'),
			_('Sat')
		],

		monthNames : [
			_('January'),
			_('February'),
			_('March'),
			_('April'),
			_('May'),
			_('June'),
			_('July'),
			_('August'),
			_('September'),
			_('October'),
			_('November'),
			_('December')
		]
	});

	Ext.PagingToolbar.tmpPageText = Zarafa.util.Translations.SplitTranslation(_('Page {A} of {0}'), '{A}');
	Ext.override(Ext.PagingToolbar, {
		displayMsg : _('Displaying messages {0} - {1} of {2}'),
		emptyMsg : _('No messages to display'),
		beforePageText : Ext.PagingToolbar.tmpPageText[0],
		afterPageText : Ext.PagingToolbar.tmpPageText[1],
		firstText : _('First Page'),
		prevText : _('Previous Page'),
		nextText : _('Next Page'),
		lastText : _('Last Page'),
		refreshText : _('Refresh')
	});
	delete Ext.PagingToolbar.tmpPageText;

	Ext.override(Ext.DatePicker, {
		todayText : _('Today'),
		okText : '&nbsp;' + _('OK') + '&nbsp;',
		cancelText : _('Cancel'),
		todayTip : _('{0} (Spacebar)'),
		minText : _('This date is before the minimum date'),
		maxText : _('This date is after the maximum date'),
		// # TRANSLATORS: See http://docs.sencha.com/ext-js/3-4/#!/api/Date for the meaning of these formatting instructions
		format : _('d/m/Y'),
		disabledDaysText : _('Disabled'),
		disabledDatesText : _('Disabled'),
		nextText : _('Next Month (Control+Right)'),
		prevText : _('Previous Month (Control+Left)'),
		monthYearText : _('Choose a month (Control+Up/Down to move years)'),
		// DatePicker prototype has copied the Date.monthNames and Date.dayNames,
		// since we just translated that, we need to copy it here again.
		monthNames : Date.monthNames,
		dayNames : Date.dayNames
	});

	Ext.override(Ext.grid.GridView, {
		sortAscText : _('Sort Ascending'),
		sortDescText: _('Sort Descending'),
		columnsText: _('Columns')
	});

	Ext.override(Ext.grid.GroupingView, {
		groupByText : _('Group By This Field'),
		showGroupsText : _('Show in Groups'),
		emptyGroupText : _('(None)')
	});

	Ext.MessageBox.buttonText.ok = _('Ok');
	Ext.MessageBox.buttonText.cancel = _('Cancel');
	Ext.MessageBox.buttonText.yes = _('Yes');
	Ext.MessageBox.buttonText.no = _('No');

	Ext.override(Ext.LoadMask, {
		msg : _('Loading') + '...'
	});

	Ext.override(Ext.form.ComboBox, {
		loadingText : _('Loading') + '...'
	});

	Ext.override(Ext.form.Field, {
		invalidText : _('The value in this field is invalid')
	});

	Ext.override(Ext.form.TextField, {
		minLengthText : _('The minimum length for this field is {0}'),
		maxLengthText : _('The maximum length for this field is {0}'),
		blankText : _('This field is required')
	});

	Ext.override(Ext.form.NumberField, {
		minText : _('The minimum value for this field is {0}'),
		maxText : _('The maximum value for this field is {0}'),
		nanText : _('{0} is not a valid number')
	});

	Ext.override(Ext.form.DateField, {
		// # TRANSLATORS: See http://docs.sencha.com/ext-js/3-4/#!/api/Date for the meaning of these formatting instructions
		format : _('d/m/Y'),
		disabledDaysText : _('Disabled'),
		disabledDatesText : _('Disabled'),
		minText : _('The date in this field must be equal to or after {0}'),
		maxText : _('The date in this field must be equal to or before {0}'),
		invalidText : _('{0} is not a valid date - it must be in the format {1}')
	});

	Ext.override(Ext.form.CheckboxGroup, {
		blankText : _('You must select at least one item in this group')
	});

	Ext.override(Ext.form.RadioGroup, {
		blankText : _('You must select one item in this group')
	});

	Ext.override(Ext.form.TimeField, {
		minText : _('The time in this field must be equal to or after {0}'),
		maxText : _('The time in this field must be equal to or before {0}'),
		invalidText : _('{0} is not a valid time'),
		// # TRANSLATORS: See http://docs.sencha.com/ext-js/3-4/#!/api/Date for the meaning of these formatting instructions
		format : _('G:i')
	});

	Ext.override(Ext.grid.GridView, {
		sortAscText : _('Sort Ascending'),
		sortDescText : _('Sort Descending'),
		columnsText : _('Columns')
	});

	Ext.override(Ext.grid.PropertyColumnModel, {
		nameText : _('Name'),
		valueText : _('Value'),
		// # TRANSLATORS: See http://docs.sencha.com/ext-js/3-4/#!/api/Date for the meaning of these formatting instructions
		dateFormat : _('d/m/Y'),
		trueText: _('true'),
		falseText: _('false')
	});

	Ext.apply(Ext.form.VTypes, {
		emailText : _('This field should be an e-mail address in the format "user@example.com"'),
		urlText : String.format(_('This field should be a URL in the format "{0}"'),  'http:/' + '/www.example.com'),
		alphaText : _('This field should only contain letters and _'),
		alphanumText : _('This field should only contain letters, numbers and _')
	});
})();
(function() {
	/**
	 * @class Ext.DatePicker
	 * @extends Ext.Component
	 * <p>A popup date picker. This class is used by the {@link Ext.form.DateField DateField} class
	 * to allow browsing and selection of valid dates.</p>
	 * <p>All the string values documented below may be overridden by including an Ext locale file in
	 * your page.</p>
	 * @constructor
	 * Create a new DatePicker
	 * @param {Object} config The config object
	 * @xtype datepicker
	 */
	var orig_onRender = Ext.DatePicker.prototype.onRender;
	var orig_update = Ext.DatePicker.prototype.update;
	var orig_beforeDestroy = Ext.DatePicker.prototype.beforeDestroy;
	var orig_initComponent = Ext.DatePicker.prototype.initComponent;
	var orig_selectToday = Ext.DatePicker.prototype.selectToday;
	Ext.override(Ext.DatePicker, {
		/**
		 * @cfg {number} width width of the datepicker (defaults to auto)
		 */
		width: '180',

		/**
		 * True to show week numbers, false otherwise.
		 * defaults to false.
		 * @cfg {Boolean} showWeekNumber
		 */
		showWeekNumber: false,

		/**
		 * Contains a collection DOM elements for week number.
		 * @property
		 * @type Ext.CompositeElementLite
		 */
		weekCells : undefined,

		/**
		 * @cfg {Boolean} showNow True to enable the mechanism which convert 'Today' button into 'Now'
		 * and fire {@link #selectnow} event while 'Now' button will be pressed along with the
		 * original functionality, false otherwise.
		 * defaults to false.
		 */
		showNow : false,

		/**
		 * overriden to set starting day of the week
		 * @override
		 */
		initComponent: function()
		{
			// if startDay is not specified through config then use one specified in settings
			if(!this.initialConfig.startDay) {
				this.startDay = container.getSettingsModel().get('zarafa/v1/main/week_start');
			}

			// Check for invalid start day
			if(this.startDay < 0 || this.startDay >= Date.dayNames.length) {
				// by default make it sunday
				this.startDay = 0;
			}

			orig_initComponent.apply(this, arguments);
		},

		/**
		 * handler for the render event
		 * overriden to set the width of the table
		 * @private
		 * @override
		 */
		onRender: function()
		{
			orig_onRender.apply(this, arguments);

			var table = this.getEl().down('table');
			table.applyStyles({ 'width' : this.width });
		},

		/**
		 * update function called when date has been changed (by clicking on date, through month picker, etc.)
		 * Additionally, an extra column will be created to display week number, if {@link #showWeekNumber} is configured as true.
		 * @param {Date} date The newly selected date
		 * @param {Boolean} forceRefresh
		 * @private
		 * @override
		 */
		update: function(date, forceRefresh)
		{
			// Check if week-number column will be shown or not.
			// Also check if week number column is already created.
			if(this.showWeekNumber === true && !Ext.isDefined(this.weekCells)) {
				// Get the table element of date-picker.
				var datePickerTable = this.el.child('table.x-date-inner', true);

				// Dynamically create week-number header.
				var tblHeadObj = datePickerTable.tHead;
				var headerRow = tblHeadObj.rows[0];
				var headerElement = {
					tag : 'th',
					/* # TRANSLATORS: This message is used as label for the column which indicates the week number of the month in date picker. and 'Wk' stands for week */
					html : '<span>' + _('Wk') + '</span>'
				};
				// Insert an extra table header at first position.
				Ext.DomHelper.insertFirst(headerRow, headerElement);

				// Dynamically create week-number cell in all rows.
				var tblBodyObj = datePickerTable.tBodies[0];
				var rowElement = {
					tag : 'td',
					cls : 'x-date-weeknumber',
					html : '<a><em><span></span></em></a>'
				};
				// Insert an extra cell at first position of all table rows.
				for (var i=0; i<tblBodyObj.rows.length; i++) {
					Ext.DomHelper.insertFirst(tblBodyObj.rows[i], rowElement);
				}

				this.weekCells = this.el.select('td.x-date-weeknumber a em span');
			}

			orig_update.apply(this, arguments);

			// Check if week-number column will be shown or not.
			if(this.showWeekNumber === true) {
				// Set week-number values into the dom elements respectively.
				var weekCells = this.weekCells.elements;
				var monthStartDate = date.getFirstDateOfMonth();

				for(var index = 0, len = weekCells.length; index < len; index++) {
					weekCells[index].innerHTML = monthStartDate.getWeekOfYear();
					monthStartDate = monthStartDate.add(Date.DAY, 7);
				}
			}
		},

		/**
		 * Handler for the before destroy event
		 * overriden to delete the {@link Ext.DatePicker#weekCells} property.
		 * @private
		 * @override
		 */
		beforeDestroy : function()
		{
			orig_beforeDestroy.apply(this, arguments);
			if(this.rendered && Ext.isDefined(this.weekCells)) {
				Ext.destroy(
					this.weekCells.el
				);

				delete this.weekCells;
			}
		},

		/**
		 * Overriden to fire 'selectnow' event if {@link #showNow} is set to true.
		 * @override
		 */
		selectToday : function()
		{
			if(this.showNow) {
				this.fireEvent('selectnow', this, this.value);
			}

			orig_selectToday.apply(this, arguments);
		}
	});
})();
/*
 * #dependsFile client/extjs-mod/Ext.js
 *
 * Override if browser is IE/Edge because IE and Edge throws a 'permission denied' exception when trying to compare a missing element (e.g. an iframe) from the 'specialElCache'
 * The element has been removed, but is prevented from being garbage collected
 * That's why a try/catch was added on line 45 so that the entire function would not fail on such occasion
 */
if(Ext.isIE || Ext.isEdge) {


	(function () {
		/**
		 * @class Ext.EventManager
		 * Registers event handlers that want to receive a normalized EventObject instead of the standard browser event and provides
		 * several useful events directly.
		 * See {@link Ext.EventObject} for more details on normalized event objects.
		 * @singleton
		 */
		Ext.apply(Ext.EventManager, function () {
			var docReadyEvent,
				docReadyProcId,
				docReadyState = false,
				DETECT_NATIVE = Ext.isGecko || Ext.isWebKit || Ext.isSafari,
				E = Ext.lib.Event,
				D = Ext.lib.Dom,
				DOC = document,
				WINDOW = window,
				DOMCONTENTLOADED = "DOMContentLoaded",
				COMPLETE = 'complete',
				propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
			/*
			 * This cache is used to hold special js objects, the document and window, that don't have an id. We need to keep
			 * a reference to them so we can look them up at a later point.
			 */
				specialElCache = [];

			function getId(el) {
				var id = false,
					i = 0,
					len = specialElCache.length,
					skip = false,
					o;

				if (el) {
					if (el.getElementById || el.navigator) {
						// look up the id
						for (; i < len; ++i) {
							o = specialElCache[i];
							//entire override because of this try - otherwise IE/Edge chokes on missing elements
							try {
								if (o.el === el) {
									id = o.id;
									break;
								}
							} catch (e) {
							}
						}
						if (!id) {
							// for browsers that support it, ensure that give the el the same id
							id = Ext.id(el);
							specialElCache.push({
								id: id,
								el: el
							});
							skip = true;
						}
					} else {
						id = Ext.id(el);
					}
					if (!Ext.elCache[id]) {
						Ext.Element.addToCache(new Ext.Element(el), id);
						if (skip) {
							Ext.elCache[id].skipGC = true;
						}
					}
				}
				return id;
			}

			/// There is some jquery work around stuff here that isn't needed in Ext Core.
			function addListener(el, ename, fn, task, wrap, scope) {
				el = Ext.getDom(el);
				var id = getId(el),
					es = Ext.elCache[id].events,
					wfn;

				wfn = E.on(el, ename, wrap);
				es[ename] = es[ename] || [];

				/* 0 = Original Function,
				 1 = Event Manager Wrapped Function,
				 2 = Scope,
				 3 = Adapter Wrapped Function,
				 4 = Buffered Task
				 */
				es[ename].push([fn, wrap, scope, wfn, task]);

				// this is a workaround for jQuery and should somehow be removed from Ext Core in the future
				// without breaking ExtJS.

				// workaround for jQuery
				if (el.addEventListener && ename == "mousewheel") {
					var args = ["DOMMouseScroll", wrap, false];
					el.addEventListener.apply(el, args);
					Ext.EventManager.addListener(WINDOW, 'unload', function () {
						el.removeEventListener.apply(el, args);
					});
				}

				// fix stopped mousedowns on the document
				if (el == DOC && ename == "mousedown") {
					Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);
				}
			}

			function doScrollChk() {
				/* Notes:
				 'doScroll' will NOT work in a IFRAME/FRAMESET.
				 The method succeeds but, a DOM query done immediately after -- FAILS.
				 */
				if (window != top) {
					return false;
				}

				try {
					DOC.documentElement.doScroll('left');
				} catch (e) {
					return false;
				}

				fireDocReady();
				return true;
			}

			/**
			 * @return {Boolean} True if the document is in a 'complete' state (or was determined to
			 * be true by other means). If false, the state is evaluated again until canceled.
			 */
			function checkReadyState(e) {

				if (Ext.isIE && doScrollChk()) {
					return true;
				}
				if (DOC.readyState == COMPLETE) {
					fireDocReady();
					return true;
				}
				docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
				return false;
			}

			var styles;

			function checkStyleSheets(e) {
				styles || (styles = Ext.query('style, link[rel=stylesheet]'));
				if (styles.length == DOC.styleSheets.length) {
					fireDocReady();
					return true;
				}
				docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
				return false;
			}

			function OperaDOMContentLoaded(e) {
				DOC.removeEventListener(DOMCONTENTLOADED, arguments.callee, false);
				checkStyleSheets();
			}

			function fireDocReady(e) {
				if (!docReadyState) {
					docReadyState = true; //only attempt listener removal once

					if (docReadyProcId) {
						clearTimeout(docReadyProcId);
					}
					if (DETECT_NATIVE) {
						DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);
					}
					if (Ext.isIE && checkReadyState.bindIE) {  //was this was actually set ??
						DOC.detachEvent('onreadystatechange', checkReadyState);
					}
					E.un(WINDOW, "load", arguments.callee);
				}
				if (docReadyEvent && !Ext.isReady) {
					Ext.isReady = true;
					docReadyEvent.fire();
					docReadyEvent.listeners = [];
				}

			}

			function initDocReady() {
				docReadyEvent || (docReadyEvent = new Ext.util.Event());
				if (DETECT_NATIVE) {
					DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
				}
				/*
				 * Handle additional (exceptional) detection strategies here
				 */
				if (Ext.isIE) {
					//Use readystatechange as a backup AND primary detection mechanism for a FRAME/IFRAME
					//See if page is already loaded
					if (!checkReadyState()) {
						checkReadyState.bindIE = true;
						DOC.attachEvent('onreadystatechange', checkReadyState);
					}

				} else if (Ext.isOpera) {
					/* Notes:
					 Opera needs special treatment needed here because CSS rules are NOT QUITE
					 available after DOMContentLoaded is raised.
					 */

					//See if page is already loaded and all styleSheets are in place
					(DOC.readyState == COMPLETE && checkStyleSheets()) ||
					DOC.addEventListener(DOMCONTENTLOADED, OperaDOMContentLoaded, false);

				} else if (Ext.isWebKit) {
					//Fallback for older Webkits without DOMCONTENTLOADED support
					checkReadyState();
				}
				// no matter what, make sure it fires on load
				E.on(WINDOW, "load", fireDocReady);
			}

			function createTargeted(h, o) {
				return function () {
					var args = Ext.toArray(arguments);
					if (o.target == Ext.EventObject.setEvent(args[0]).target) {
						h.apply(this, args);
					}
				};
			}

			function createBuffered(h, o, task) {
				return function (e) {
					// create new event object impl so new events don't wipe out properties
					task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]);
				};
			}

			function createSingle(h, el, ename, fn, scope) {
				return function (e) {
					Ext.EventManager.removeListener(el, ename, fn, scope);
					h(e);
				};
			}

			function createDelayed(h, o, fn) {
				return function (e) {
					var task = new Ext.util.DelayedTask(h);
					if (!fn.tasks) {
						fn.tasks = [];
					}
					fn.tasks.push(task);
					task.delay(o.delay || 10, h, null, [new Ext.EventObjectImpl(e)]);
				};
			}

			function listen(element, ename, opt, fn, scope) {
				var o = (!opt || typeof opt == "boolean") ? {} : opt,
					el = Ext.getDom(element), task;

				fn = fn || o.fn;
				scope = scope || o.scope;

				if (!el) {
					throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
				}
				function h(e) {
					// prevent errors while unload occurring
					if (!Ext) {// !window[xname]){  ==> can't we do this?
						return;
					}
					e = Ext.EventObject.setEvent(e);
					var t;
					if (o.delegate) {
						if (!(t = e.getTarget(o.delegate, el))) {
							return;
						}
					} else {
						t = e.target;
					}
					if (o.stopEvent) {
						e.stopEvent();
					}
					if (o.preventDefault) {
						e.preventDefault();
					}
					if (o.stopPropagation) {
						e.stopPropagation();
					}
					if (o.normalized === false) {
						e = e.browserEvent;
					}

					fn.call(scope || el, e, t, o);
				}

				if (o.target) {
					h = createTargeted(h, o);
				}
				if (o.delay) {
					h = createDelayed(h, o, fn);
				}
				if (o.single) {
					h = createSingle(h, el, ename, fn, scope);
				}
				if (o.buffer) {
					task = new Ext.util.DelayedTask(h);
					h = createBuffered(h, o, task);
				}

				addListener(el, ename, fn, task, h, scope);
				return h;
			}

			var pub = {
				/**
				 * Appends an event handler to an element.  The shorthand version {@link #on} is equivalent.  Typically you will
				 * use {@link Ext.Element#addListener} directly on an Element in favor of calling this version.
				 * @param {String/HTMLElement} el The html element or id to assign the event handler to.
				 * @param {String} eventName The name of the event to listen for.
				 * @param {Function} handler The handler function the event invokes. This function is passed
				 * the following parameters:<ul>
				 * <li>evt : EventObject<div class="sub-desc">The {@link Ext.EventObject EventObject} describing the event.</div></li>
				 * <li>t : Element<div class="sub-desc">The {@link Ext.Element Element} which was the target of the event.
				 * Note that this may be filtered by using the <tt>delegate</tt> option.</div></li>
				 * <li>o : Object<div class="sub-desc">The options object from the addListener call.</div></li>
				 * </ul>
				 * @param {Object} scope (optional) The scope (<b><code>this</code></b> reference) in which the handler function is executed. <b>Defaults to the Element</b>.
				 * @param {Object} options (optional) An object containing handler configuration properties.
				 * This may contain any of the following properties:<ul>
				 * <li>scope : Object<div class="sub-desc">The scope (<b><code>this</code></b> reference) in which the handler function is executed. <b>Defaults to the Element</b>.</div></li>
				 * <li>delegate : String<div class="sub-desc">A simple selector to filter the target or look for a descendant of the target</div></li>
				 * <li>stopEvent : Boolean<div class="sub-desc">True to stop the event. That is stop propagation, and prevent the default action.</div></li>
				 * <li>preventDefault : Boolean<div class="sub-desc">True to prevent the default action</div></li>
				 * <li>stopPropagation : Boolean<div class="sub-desc">True to prevent event propagation</div></li>
				 * <li>normalized : Boolean<div class="sub-desc">False to pass a browser event to the handler function instead of an Ext.EventObject</div></li>
				 * <li>delay : Number<div class="sub-desc">The number of milliseconds to delay the invocation of the handler after te event fires.</div></li>
				 * <li>single : Boolean<div class="sub-desc">True to add a handler to handle just the next firing of the event, and then remove itself.</div></li>
				 * <li>buffer : Number<div class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed
				 * by the specified number of milliseconds. If the event fires again within that time, the original
				 * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</div></li>
				 * <li>target : Element<div class="sub-desc">Only call the handler if the event was fired on the target Element, <i>not</i> if the event was bubbled up from a child node.</div></li>
				 * </ul><br>
				 * <p>See {@link Ext.Element#addListener} for examples of how to use these options.</p>
				 */
				addListener: function (element, eventName, fn, scope, options) {
					if (typeof eventName == 'object') {
						var o = eventName, e, val;
						for (e in o) {
							val = o[e];
							if (!propRe.test(e)) {
								if (Ext.isFunction(val)) {
									// shared options
									listen(element, e, o, val, o.scope);
								} else {
									// individual options
									listen(element, e, val);
								}
							}
						}
					} else {
						listen(element, eventName, options, fn, scope);
					}
				},
				/**
				 * Removes an event handler from an element.  The shorthand version {@link #un} is equivalent.  Typically
				 * you will use {@link Ext.Element#removeListener} directly on an Element in favor of calling this version.
				 * @param {String/HTMLElement} el The id or html element from which to remove the listener.
				 * @param {String} eventName The name of the event.
				 * @param {Function} fn The handler function to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>
				 * @param {Object} scope If a scope (<b><code>this</code></b> reference) was specified when the listener was added,
				 * then this must refer to the same object.
				 */
				removeListener: function (el, eventName, fn, scope) {
					el = Ext.getDom(el);
					var id = getId(el),
						f = el && (Ext.elCache[id].events)[eventName] || [],
						wrap, i, l, k, len, fnc;

					for (i = 0, len = f.length; i < len; i++) {

						/* 0 = Original Function,
						 1 = Event Manager Wrapped Function,
						 2 = Scope,
						 3 = Adapter Wrapped Function,
						 4 = Buffered Task
						 */
						if (Ext.isArray(fnc = f[i]) && fnc[0] == fn && (!scope || fnc[2] == scope)) {
							if (fnc[4]) {
								fnc[4].cancel();
							}
							k = fn.tasks && fn.tasks.length;
							if (k) {
								while (k--) {
									fn.tasks[k].cancel();
								}
								delete fn.tasks;
							}
							wrap = fnc[1];
							E.un(el, eventName, E.extAdapter ? fnc[3] : wrap);

							// jQuery workaround that should be removed from Ext Core
							if (wrap && el.addEventListener && eventName == "mousewheel") {
								el.removeEventListener("DOMMouseScroll", wrap, false);
							}

							// fix stopped mousedowns on the document
							if (wrap && el == DOC && eventName == "mousedown") {
								Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
							}

							f.splice(i, 1);
							if (f.length === 0) {
								delete Ext.elCache[id].events[eventName];
							}
							for (k in Ext.elCache[id].events) {
								return false;
							}
							Ext.elCache[id].events = {};
							return false;
						}
					}
				},

				/**
				 * Removes all event handers from an element.  Typically you will use {@link Ext.Element#removeAllListeners}
				 * directly on an Element in favor of calling this version.
				 * @param {String/HTMLElement} el The id or html element from which to remove all event handlers.
				 */
				removeAll: function (el) {
					el = Ext.getDom(el);
					var id = getId(el),
						ec = Ext.elCache[id] || {},
						es = ec.events || {},
						f, i, len, ename, fn, k, wrap;

					for (ename in es) {
						if (es.hasOwnProperty(ename)) {
							f = es[ename];
							/* 0 = Original Function,
							 1 = Event Manager Wrapped Function,
							 2 = Scope,
							 3 = Adapter Wrapped Function,
							 4 = Buffered Task
							 */
							for (i = 0, len = f.length; i < len; i++) {
								fn = f[i];
								if (fn[4]) {
									fn[4].cancel();
								}
								if (fn[0].tasks && (k = fn[0].tasks.length)) {
									while (k--) {
										fn[0].tasks[k].cancel();
									}
									delete fn.tasks;
								}
								wrap = fn[1];
								E.un(el, ename, E.extAdapter ? fn[3] : wrap);

								// jQuery workaround that should be removed from Ext Core
								if (el.addEventListener && wrap && ename == "mousewheel") {
									el.removeEventListener("DOMMouseScroll", wrap, false);
								}

								// fix stopped mousedowns on the document
								if (wrap && el == DOC && ename == "mousedown") {
									Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
								}
							}
						}
					}
					if (Ext.elCache[id]) {
						Ext.elCache[id].events = {};
					}
				},

				getListeners: function (el, eventName) {
					el = Ext.getDom(el);
					var id = getId(el),
						ec = Ext.elCache[id] || {},
						es = ec.events || {},
						results = [];
					if (es && es[eventName]) {
						return es[eventName];
					} else {
						return null;
					}
				},

				purgeElement: function (el, recurse, eventName) {
					el = Ext.getDom(el);
					var id = getId(el),
						ec = Ext.elCache[id] || {},
						es = ec.events || {},
						i, f, len;
					if (eventName) {
						if (es && es.hasOwnProperty(eventName)) {
							f = es[eventName];
							for (i = 0, len = f.length; i < len; i++) {
								Ext.EventManager.removeListener(el, eventName, f[i][0]);
							}
						}
					} else {
						Ext.EventManager.removeAll(el);
					}
					if (recurse && el && el.childNodes) {
						for (i = 0, len = el.childNodes.length; i < len; i++) {
							Ext.EventManager.purgeElement(el.childNodes[i], recurse, eventName);
						}
					}
				},
				_unload: function () {
					var el;
					for (el in Ext.elCache) {
						Ext.EventManager.removeAll(el);
					}
					delete Ext.elCache;
					delete Ext.Element._flyweights;

					// Abort any outstanding Ajax requests
					var c,
						conn,
						tid,
						ajax = Ext.lib.Ajax;
					(typeof ajax.conn == 'object') ? conn = ajax.conn : conn = {};
					for (tid in conn) {
						c = conn[tid];
						if (c) {
							ajax.abort({conn: c, tId: tid});
						}
					}
				},
				/**
				 * Adds a listener to be notified when the document is ready (before onload and before images are loaded). Can be
				 * accessed shorthanded as Ext.onReady().
				 * @param {Function} fn The method the event invokes.
				 * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the handler function executes. Defaults to the browser window.
				 * @param {boolean} options (optional) Options object as passed to {@link Ext.Element#addListener}. It is recommended that the options
				 * <code>{single: true}</code> be used so that the handler is removed on first invocation.
				 */
				onDocumentReady: function (fn, scope, options) {
					if (Ext.isReady) { // if it already fired or document.body is present
						docReadyEvent || (docReadyEvent = new Ext.util.Event());
						docReadyEvent.addListener(fn, scope, options);
						docReadyEvent.fire();
						docReadyEvent.listeners = [];
					} else {
						if (!docReadyEvent) {
							initDocReady();
						}
						options = options || {};
						options.delay = options.delay || 1;
						docReadyEvent.addListener(fn, scope, options);
					}
				},

				/**
				 * Forces a document ready state transition for the framework.  Used when Ext is loaded
				 * into a DOM structure AFTER initial page load (Google API or other dynamic load scenario.
				 * Any pending 'onDocumentReady' handlers will be fired (if not already handled).
				 */
				fireDocReady: fireDocReady
			};
			pub.on = pub.addListener;
			pub.un = pub.removeListener;
			pub.stoppedMouseDownEvent = new Ext.util.Event();

			return pub;
		}());
	})();
}/**
 * Override Ext.Layer when parentEl is not specified in config.
 * Consider body of active browser window as a parent element instead of main browser window.
 *
 * @class Ext.Layer
 * @extends Ext.Element
 * An extended {@link Ext.Element} object that supports a shadow and shim, constrain to viewport and
 * automatic maintaining of shadow/shim positions.
 * @cfg {Boolean} shim False to disable the iframe shim in browsers which need one (defaults to true)
 * @cfg {String/Boolean} shadow True to automatically create an {@link Ext.Shadow}, or a string indicating the
 * shadow's display {@link Ext.Shadow#mode}. False to disable the shadow. (defaults to false)
 * @cfg {Object} dh DomHelper object config to create element with (defaults to {tag: 'div', cls: 'x-layer'}).
 * @cfg {Boolean} constrain False to disable constrain to viewport (defaults to true)
 * @cfg {String} cls CSS class to add to the element
 * @cfg {Number} zindex Starting z-index (defaults to 11000)
 * @cfg {Number} shadowOffset Number of pixels to offset the shadow (defaults to 4)
 * @cfg {Boolean} useDisplay
 * Defaults to use css offsets to hide the Layer. Specify <tt>true</tt>
 * to use css style <tt>'display:none;'</tt> to hide the Layer.
 * @constructor
 * @param {Object} config An object with config options.
 * @param {String/HTMLElement} existingEl (optional) Uses an existing DOM element. If the element is not found it creates it.
 */
(function(){
    Ext.Layer = function(config, existingEl){
        config = config || {};
        var dh = Ext.DomHelper,
            activeBrowserObject = Zarafa.core.BrowserWindowMgr.getActive(),
            cp = config.parentEl, pel = cp ? Ext.getDom(cp) : activeBrowserObject.document.body;

        if (existingEl) {
            this.dom = Ext.getDom(existingEl);
        }
        if(!this.dom){
            var o = config.dh || {tag: 'div', cls: 'x-layer'};
            this.dom = dh.append(pel, o);
        }
        if(config.cls){
            this.addClass(config.cls);
        }
        this.constrain = config.constrain !== false;
        this.setVisibilityMode(Ext.Element.VISIBILITY);
        if(config.id){
            this.id = this.dom.id = config.id;
        }else{
            this.id = Ext.id(this.dom);
        }
        this.zindex = config.zindex || this.getZIndex();
        this.position('absolute', this.zindex);
        if(config.shadow){
            this.shadowOffset = config.shadowOffset || 4;
            this.shadow = new Ext.Shadow({
                offset : this.shadowOffset,
                mode : config.shadow
            });
        }else{
            this.shadowOffset = 0;
        }
        this.useShim = config.shim !== false && Ext.useShims;
        this.useDisplay = config.useDisplay;
        this.hide();
    };

    var supr = Ext.Element.prototype;

// shims are shared among layer to keep from having 100 iframes
    var shims = [];

    Ext.extend(Ext.Layer, Ext.Element, {

        getZIndex : function(){
            return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;
        },

        getShim : function(){
            if(!this.useShim){
                return null;
            }
            if(this.shim){
                return this.shim;
            }
            var shim = shims.shift();
            if(!shim){
                shim = this.createShim();
                shim.enableDisplayMode('block');
                shim.dom.style.display = 'none';
                shim.dom.style.visibility = 'visible';
            }
            var pn = this.dom.parentNode;
            if(shim.dom.parentNode != pn){
                pn.insertBefore(shim.dom, this.dom);
            }
            shim.setStyle('z-index', this.getZIndex()-2);
            this.shim = shim;
            return shim;
        },

        hideShim : function(){
            if(this.shim){
                this.shim.setDisplayed(false);
                shims.push(this.shim);
                delete this.shim;
            }
        },

        disableShadow : function(){
            if(this.shadow){
                this.shadowDisabled = true;
                this.shadow.hide();
                this.lastShadowOffset = this.shadowOffset;
                this.shadowOffset = 0;
            }
        },

        enableShadow : function(show){
            if(this.shadow){
                this.shadowDisabled = false;
                if(Ext.isDefined(this.lastShadowOffset)) {
                    this.shadowOffset = this.lastShadowOffset;
                    delete this.lastShadowOffset;
                }
                if(show){
                    this.sync(true);
                }
            }
        },

        // private
        // this code can execute repeatedly in milliseconds (i.e. during a drag) so
        // code size was sacrificed for effeciency (e.g. no getBox/setBox, no XY calls)
        sync : function(doShow){
            var shadow = this.shadow;
            if(!this.updating && this.isVisible() && (shadow || this.useShim)){
                var shim = this.getShim(),
                    w = this.getWidth(),
                    h = this.getHeight(),
                    l = this.getLeft(true),
                    t = this.getTop(true);

                if(shadow && !this.shadowDisabled){
                    if(doShow && !shadow.isVisible()){
                        shadow.show(this);
                    }else{
                        shadow.realign(l, t, w, h);
                    }
                    if(shim){
                        if(doShow){
                            shim.show();
                        }
                        // fit the shim behind the shadow, so it is shimmed too
                        var shadowAdj = shadow.el.getXY(), shimStyle = shim.dom.style,
                            shadowSize = shadow.el.getSize();
                        shimStyle.left = (shadowAdj[0])+'px';
                        shimStyle.top = (shadowAdj[1])+'px';
                        shimStyle.width = (shadowSize.width)+'px';
                        shimStyle.height = (shadowSize.height)+'px';
                    }
                }else if(shim){
                    if(doShow){
                        shim.show();
                    }
                    shim.setSize(w, h);
                    shim.setLeftTop(l, t);
                }
            }
        },

        // private
        destroy : function(){
            this.hideShim();
            if(this.shadow){
                this.shadow.hide();
            }
            this.removeAllListeners();
            Ext.removeNode(this.dom);
            delete this.dom;
        },

        remove : function(){
            this.destroy();
        },

        // private
        beginUpdate : function(){
            this.updating = true;
        },

        // private
        endUpdate : function(){
            this.updating = false;
            this.sync(true);
        },

        // private
        hideUnders : function(negOffset){
            if(this.shadow){
                this.shadow.hide();
            }
            this.hideShim();
        },

        // private
        constrainXY : function(){
            if(this.constrain){
                var vw = Ext.lib.Dom.getViewWidth(),
                    vh = Ext.lib.Dom.getViewHeight();
                var s = Ext.getDoc().getScroll();

                var xy = this.getXY();
                var x = xy[0], y = xy[1];
                var so = this.shadowOffset;
                var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;
                // only move it if it needs it
                var moved = false;
                // first validate right/bottom
                if((x + w) > vw+s.left){
                    x = vw - w - so;
                    moved = true;
                }
                if((y + h) > vh+s.top){
                    y = vh - h - so;
                    moved = true;
                }
                // then make sure top/left isn't negative
                if(x < s.left){
                    x = s.left;
                    moved = true;
                }
                if(y < s.top){
                    y = s.top;
                    moved = true;
                }
                if(moved){
                    if(this.avoidY){
                        var ay = this.avoidY;
                        if(y <= ay && (y+h) >= ay){
                            y = ay-h-5;
                        }
                    }
                    xy = [x, y];
                    this.storeXY(xy);
                    supr.setXY.call(this, xy);
                    this.sync();
                }
            }
            return this;
        },

        getConstrainOffset : function(){
            return this.shadowOffset;
        },

        isVisible : function(){
            return this.visible;
        },

        // private
        showAction : function(){
            this.visible = true; // track visibility to prevent getStyle calls
            if(this.useDisplay === true){
                this.setDisplayed('');
            }else if(this.lastXY){
                supr.setXY.call(this, this.lastXY);
            }else if(this.lastLT){
                supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
            }
        },

        // private
        hideAction : function(){
            this.visible = false;
            if(this.useDisplay === true){
                this.setDisplayed(false);
            }else{
                this.setLeftTop(-10000,-10000);
            }
        },

        // overridden Element method
        setVisible : function(v, a, d, c, e){
            if(v){
                this.showAction();
            }
            if(a && v){
                var cb = function(){
                    this.sync(true);
                    if(c){
                        c();
                    }
                }.createDelegate(this);
                supr.setVisible.call(this, true, true, d, cb, e);
            }else{
                if(!v){
                    this.hideUnders(true);
                }
                var cb = c;
                if(a){
                    cb = function(){
                        this.hideAction();
                        if(c){
                            c();
                        }
                    }.createDelegate(this);
                }
                supr.setVisible.call(this, v, a, d, cb, e);
                if(v){
                    this.sync(true);
                }else if(!a){
                    this.hideAction();
                }
            }
            return this;
        },

        storeXY : function(xy){
            delete this.lastLT;
            this.lastXY = xy;
        },

        storeLeftTop : function(left, top){
            delete this.lastXY;
            this.lastLT = [left, top];
        },

        // private
        beforeFx : function(){
            this.beforeAction();
            return Ext.Layer.superclass.beforeFx.apply(this, arguments);
        },

        // private
        afterFx : function(){
            Ext.Layer.superclass.afterFx.apply(this, arguments);
            this.sync(this.isVisible());
        },

        // private
        beforeAction : function(){
            if(!this.updating && this.shadow){
                this.shadow.hide();
            }
        },

        // overridden Element method
        setLeft : function(left){
            this.storeLeftTop(left, this.getTop(true));
            supr.setLeft.apply(this, arguments);
            this.sync();
            return this;
        },

        setTop : function(top){
            this.storeLeftTop(this.getLeft(true), top);
            supr.setTop.apply(this, arguments);
            this.sync();
            return this;
        },

        setLeftTop : function(left, top){
            this.storeLeftTop(left, top);
            supr.setLeftTop.apply(this, arguments);
            this.sync();
            return this;
        },

        setXY : function(xy, a, d, c, e){
            this.fixDisplay();
            this.beforeAction();
            this.storeXY(xy);
            var cb = this.createCB(c);
            supr.setXY.call(this, xy, a, d, cb, e);
            if(!a){
                cb();
            }
            return this;
        },

        // private
        createCB : function(c){
            var el = this;
            return function(){
                el.constrainXY();
                el.sync(true);
                if(c){
                    c();
                }
            };
        },

        // overridden Element method
        setX : function(x, a, d, c, e){
            this.setXY([x, this.getY()], a, d, c, e);
            return this;
        },

        // overridden Element method
        setY : function(y, a, d, c, e){
            this.setXY([this.getX(), y], a, d, c, e);
            return this;
        },

        // overridden Element method
        setSize : function(w, h, a, d, c, e){
            this.beforeAction();
            var cb = this.createCB(c);
            supr.setSize.call(this, w, h, a, d, cb, e);
            if(!a){
                cb();
            }
            return this;
        },

        // overridden Element method
        setWidth : function(w, a, d, c, e){
            this.beforeAction();
            var cb = this.createCB(c);
            supr.setWidth.call(this, w, a, d, cb, e);
            if(!a){
                cb();
            }
            return this;
        },

        // overridden Element method
        setHeight : function(h, a, d, c, e){
            this.beforeAction();
            var cb = this.createCB(c);
            supr.setHeight.call(this, h, a, d, cb, e);
            if(!a){
                cb();
            }
            return this;
        },

        // overridden Element method
        setBounds : function(x, y, w, h, a, d, c, e){
            this.beforeAction();
            var cb = this.createCB(c);
            if(!a){
                this.storeXY([x, y]);
                supr.setXY.call(this, [x, y]);
                supr.setSize.call(this, w, h, a, d, cb, e);
                cb();
            }else{
                supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
            }
            return this;
        },

        /**
         * Sets the z-index of this layer and adjusts any shadow and shim z-indexes. The layer z-index is automatically
         * incremented by two more than the value passed in so that it always shows above any shadow or shim (the shadow
         * element, if any, will be assigned z-index + 1, and the shim element, if any, will be assigned the unmodified z-index).
         * @param {Number} zindex The new z-index to set
         * @return {this} The Layer
         */
        setZIndex : function(zindex){
            this.zindex = zindex;
            this.setStyle('z-index', zindex + 2);
            if(this.shadow){
                this.shadow.setZIndex(zindex + 1);
            }
            if(this.shim){
                this.shim.setStyle('z-index', zindex);
            }
            return this;
        }
    });
})();