dojo.provide("epages.widget.Modaldialog");
dojo.require("epages.widget.LocalizedWidget");
dojo.require("epages.browser");
dojo.require("epages.template");
dojo.require("epages.html");
dojo.require("epages.event");
dojo["require"]('dijit.Dialog'); //change require syntax to keep it here after shrinksafe
dojo.require('dojox.layout.ContentPane');
dojo.require('epages.lang.hash');
dojo.require('epages.io.text');
dojo.require('epages.widget.Button');

dojo.declare(
	"epages.widget.Modaldialog",
	[dijit.Dialog, epages.widget.LocalizedWidget],
	{

		/**
		 * public properties
		 */
		buttons: undefined,
		options: undefined,
		duration: epages.Browser.engine=="MSIE" ? 10 : 150,
		title: '',
		'class' : '',
		/**
		 * private properties
		 */
		_contentWidget: null,
		_contentPane: null,
		_events: null,
		_tabEvents: null,
		_tabs: undefined,
		_currentTab: undefined,
		_iframe: null,
		_doc: null,

		/**
		 * dojo widget properties
		 */
		translationName       : dojo.moduleUrl('epages.widget', "templates/translation"),
		imagePath             : epages.themeUrl('images'),
		buttonTemplateString  : '<span class="Button EnableHover (%Class%)" (%buttonId%)><span class="ButtonContainer">(%Label%)</span></span>',
		tabTemplateString     : '<div class="Tab"><div>(%Label%)</div></div>',
		innerTemplatePath     : null,
		widgetsInTemplate     : true,
		templateString: dojo.cache("epages.widget", "templates/Modaldialog.html"),

		clearFloatNode        : undefined,

		buildRendering: function() {
			// summary:
			//    replaces the placeholder in the base template with the template from innerTemplateString,
			//    so this works like an include and you don't have to rewrite the whole template in sub-
			//    classes.
			if (this.innerTemplatePath != null) {
				this.templateString = dijit._Templated.getCachedTemplate(this.templatePath, this.templateString, true);
				var innerTemplateString = dijit._Templated.getCachedTemplate(this.innerTemplatePath, null, true);
				this.templateString = this.templateString.replace('<!-- //innerTemplate// -->', innerTemplateString);
				this.templatePath = '';
			}
			this.inherited("buildRendering", arguments);
		},

		postMixInProperties: function() {
			var options = {containerClass: ''};
			dojo.mixin(options, this.options);
			this.options = options;
			dijit.Dialog.prototype.postMixInProperties.apply(this, arguments);
			this.inherited("postMixInProperties", arguments);
		},

		postCreate: function() {
			this._doc = this.domNode.ownerDocument;
			//call postCreate of dijit.dialog because this.inherited only references to the last parent class
			dijit.Dialog.prototype.postCreate.apply(this, arguments);
			this.inherited("postCreate", arguments);
			if(this.buttons===undefined){
				this.buttons=[];
			}
			if(this.tabs===undefined){
				this.tabs=[];
			}
			if(this.options===undefined){
				this.options={};
			}
			this._createContent(this.options);
			this._createButtons(this.buttons);
			this._createTabs();
			dojo.addClass(this.domNode, this['class']);
			dojo.subscribe(this.id+"/executeAction",dojo.hitch(this,this.executeAction));
		},
		executeAction : function(/*String*/ functionName,/*anything...*/additionalParams){
			// summary: executes the specified function with the passed arguments
			// example: dojo.publish(id/executeAction,[disableButton,startButton])
			// functionName: function name to call and every following
			// additionalParams: parameters will be pushed as parameter to the called function
			if(this[functionName] && dojo.isFunction(this[functionName])){
				var params = [];
				dojo.forEach(arguments,function(el,i){
					if(i!=0){
						params.push(el);
					}
				});
				epages.lang.hitch(this,functionName,params)();
			}
		},

		destroyRendering: function() {
			this.hide();
			this.inherited("destroyRendering", arguments);
		},

		hide: function() {
			this.inherited("hide", arguments);
			if(epages.Browser.engine=="MSIE") { // layer display corrections
				this.domNode.style.width="auto";
			}
			dojo.publish(this.id+'/hide',[{dialog: this}]);
		},

		show: function() {
			this.inherited("show", arguments);
			if(epages.Browser.engine=="MSIE") { // layer display corrections
				this.domNode.style.width=this.domNode.offsetWidth+"px";
			}
			//set zIndex to epages.vars.ZIndex
			if(this.domNode && epages.zIndex){
				this.domNode.style.zIndex = epages.zIndex;
			}
			if(this._underlay){
				this._underlay.domNode.style.zIndex = this.domNode.style.zIndex-1;
			}
			if(epages.zIndex){
				epages.zIndex+=2;
			}
			//disconnect scrollevent from dialog, because there is no parameter in dojo dialog to achive this
			for(var i = 0, iLength = this._modalconnects.length; i < iLength; i++){
				var currentEventHandle = this._modalconnects[i];
				if( currentEventHandle.length && currentEventHandle[1] &&  currentEventHandle[1] == 'onscroll'){
					dojo.disconnect(currentEventHandle);
				}
			}
			//check if there is enough space to see the close button
			var popupTop = parseInt(this.domNode.style.top);
			var popupLeft = parseInt(this.domNode.style.left);
			if(popupTop < 0){
				this.domNode.style.top = "0px";
			}
			if(popupLeft < 0){
				this.domNode.style.left = "";
				this.domNode.style.right = "0px";
			}
			else {
				this.domNode.style.right = "";
			}
			//remove dragging
			if(this._moveable){
				this._moveable.destroy();
			}
			// manual focus handling : focus first input
			if(!this.autofocus) {
				var inputs = dojo.query('input', this.containerNode);
				if(inputs && inputs.length > 0) {
					inputs[0].focus();
				}
			}
			// trigger resize to adjust CKEditor dimensions
			jq(window).trigger('resize');

			dojo.publish(this.id+'/show',[{dialog: this}]);
		},

		close: function() {
			this.hide();
			window.setTimeout(dojo.hitch(this,function(){
				this._destroyContent();
				this._destroyButtons();
			}),this.duration);
		},

		setupContent: function(/*Object*/ opt) {
		// summary: setup new content (destorys old content contentarea, tabs, buttons)
		// opt: {
		//  content - string / domNode / widget object (strings may contain widgets e.g. <div dojoType="epages.widget.Tooltip"></div>)
		//  buttons - array with buttons e.g. [{label: 'Cancel',onclick: function() {this._modalDialogWidget.hide();}]}
		//  width - integer or string - width of content area
		//  height - integer or string - height of content area
		//  scroll - string - possible values: 'y', 'x', 'scroll', 'hidden'
		//  title - string - text in titlebar
		//  translationName - string (url) specify translation file to translate language tags in title attribute
		//  url - load content via url
		//  destroyWidgetOnClose - boolean - option to destroy widgets after closing the content widget (also after setting up new content)
		// }
			this._destroyTabs();
			this._destroyContent();
			this._destroyButtons();

			if (opt.buttons){
				this.setupButtons(opt.buttons);
			}
			this._createContent(opt);
			this._createTabs();
		},

		setupButtons: function (buttons) {
			this._destroyButtons();
			this._createButtons(buttons);
		},


		setTitle: function(title) {
			this.titleNode.innerHTML = title;
		},

/**
* widget button/ display functions
*/

		hideInnerButtonBar : function() {
			this.innerButtonBarNode.style.display ='none';
		},

		showInnerButtonBar : function() {
			this.innerButtonBarNode.style.display ='';
		},

		disableButton : function(/* string|DomNode*/ but) {
		// summary: disables specified button
			if(dojo.isString(but)){
				var buttons = dojo.query("[buttonid="+but+"]", this.domNode );
				if(buttons){
					buttons = buttons[0];
				}
			} else {
				var buttons = but;
			}
			if(buttons) {
				dojo.removeClass(buttons, "Active");
				dojo.addClass(buttons, "Disabled");
				buttons.disabled=true;
			}

			dojo.forEach(this._events, function(evtmap) {
				if(evtmap.button.domNode == buttons) {
					dojo.disconnect(evtmap.event);
				}
			});

		},

		enableButton : function(/* string */ buttonId) {
		// summary: enables specified button
			var buttonData = undefined;
			dojo.forEach(this.buttons, function (button) {
				if(button.buttonId == buttonId) {
					buttonData = button;
				}
			});

			if(buttonData && buttonData.domNode.disabled == true) {
				buttonData.domNode.disabled=false;
				if(buttonData.cssClass) {
					dojo.addClass(buttonData.domNode, buttonData.cssClass );
				}
				dojo.removeClass(buttonData.domNode, "Disabled");
				dojo.forEach(this._events, function(evtmap) {
					if(evtmap.button.buttonId == buttonId) {
						evtmap.event = dojo.connect(buttonData.domNode, "onclick", buttonData, "onclick");
					}
				});
			}
		},

		_createContent: function(/*Object*/ opt) {
			if(opt){
				dojo.mixin(this.options, opt);
			}

			var translation = undefined;
			if(this.options.translationName) {
				translation = new epages.io.Translation(this.options.translationName,"auto");
				if(this.options.title){
					this.options.title = translation.replaceLanguageTags(this.options.title);
				}
			}
			if (this.options.title){
				this.setTitle(this.options.title);
			}
			// set Layout
			switch(this.options.scroll){
				case "y":
					this.containerNode.style.overflowY='scroll';
					break;
				case "x":
					this.containerNode.style.overflowX='scroll';
					break;
				case "scroll":
					this.containerNode.style.overflow='scroll';
					break;
				case "hidden":
					this.containerNode.style.overflow='hidden';
					break;
				default:
					this.containerNode.style.overflow='auto';
					break;
			}
			if (this.options.width) {
				if (typeof this.options.width == 'number') {
					this.layerContentNode.style.width=this.options.width+"px";
				} else {
					this.layerContentNode.style.width=this.options.width;
				}
			} else {
				this.containerNode.style.width="auto";
				this.layerContentNode.style.width="auto";
			}
			if (this.options.height) {
				if (typeof this.options.height == 'number') {
					this.containerNode.style.height=this.options.height+"px";
				} else {
					this.containerNode.style.height=this.options.height;
				}
			} else {
				this.containerNode.style.height="auto";
			}
			if (this.options.url != null) {
				// url, use contentPane
				if (this._contentPane == null) {
					// contentPane does not exist -> create it
					this._contentPane = new dojox.layout.ContentPane({
						// url of content
						href: this.options.url,
						// wait for download to finish
						preload: true,
						// extract content from body tag
						extractContent: false,
						// adjust relative paths
						adjustPaths: true,
						// set content on download end to avoid resizing problem <-- does not work
						ioMethod: function(args) {
							var result = dojo.xhrGet(args);
							if(translation){
								result.addCallback(function(html){
										return translation.replaceLanguageTags(html);
								});
							}
							return result;
						},
						onLoad: dojo.hitch(this, function() {
							//Timeout necessary for IE
							window.setTimeout(dojo.hitch(this,function(){
							this.containerNode.appendChild(this._contentPane.domNode);
							// call event function
							if (this.options && this.options.onLoad && typeof this.options.onLoad == 'function'){
								this.options.onLoad();
							}
							this.layout();
							this.show();
							this._createTabs();
							dojo.publish(this.id+'/onLoadContentPane',[{dialog: this}]);
						}),10);
						})
					});
					this._contentPane.refresh();
				} else {
					this._contentPane.setHref(this.options.url);
				}
			} else {
				if(typeof this.options.content == "object") {
					// content, string, nodes or widgets
					if(this.options.content.domNode) { // widget
						this.containerNode.appendChild(this.options.content.domNode);
						this._contentWidget=this.options.content;
					} else {                           // dom node
						this.containerNode.appendChild(this.options.content);
					}
				} else if(typeof this.options.content == "string") {
					this.containerNode.innerHTML=this.options.content;  // html string
					var scripts = this.containerNode.getElementsByTagName('script');
					var win = this._doc.parentWindow ? this._doc.parentWindow : this._doc.defaultView;
					for( var i=0,iLength=scripts.length ; i<iLength ; i++ ) {
						if (scripts[i].childNodes.length > 0) {
							// Mozilla
							// Fix for bug https://bugzilla.mozilla.org/show_bug.cgi?id=194231: only 4K string in array element
							var evalString = "";
							for( var j=0,jLength=scripts[i].childNodes.length ; j<jLength ; j++ ) {
								evalString += scripts[i].childNodes[j].nodeValue;
							}
							win.eval(evalString);
						} else {
							// IE
							win.eval(scripts[i].innerHTML);
						}
					}
					win.dojo.parser.parse(this.containerNode); // build widgets
					//epages.widget.TransformButtons(this.containerNode);
				}
			}
			dojo.publish(this.id+'/change',[{dialog: this}]);
		},

		_destroyContent: function() {
			this.options.scroll=undefined;
			this.options.width=undefined;
			this.options.height=undefined;
			this.options.title=undefined;
			this.options.url=undefined;

			if(this.titleNode.firstChild){
				this.titleNode.firstChild.data=" ";
			}
			this.containerNode.style.overflow='auto';
			this.containerNode.style.overflowX='auto';
			this.containerNode.style.overflowY='auto';
			this.containerNode.style.width="auto";
			this.layerContentNode.style.width="auto";
			this.containerNode.style.height="auto";
			this.innerButtonBarNode.style.display="none";
			this.tabBarNode.style.display="none";

			// remove containerNode children

			epages.html.removeChildren(this.containerNode);

			if(typeof this.options.content == "object" && this.options.destroyWidgetOnClose){
				this.options.content.destroy();   // destroy widget
			}
			this._contentWidget = null;
			this.options.content = "";
		},

		_createButtons: function(/* Object[] */ buttons) {
		// summary: create modal dialog buttons
		// buttons:
		// [{
		//   label: '{Delete}',
		//   cssClass: 'Active',
		//   buttonId: 'delete',
		//   hideOnShow: 'false',
		//   isDisabled: 'false',
		//   onclick: function() {
		//     me.deleteNavigationElement();
		//     this._modalDialogWidget.hide();
		//   }
		//  },{
		//    label: '{Cancel}',
		//    onclick: function() { this._modalDialogWidget.hide(); }
		// }]
			if(buttons.length){
				this.innerButtonBarNode.style.display="";
			}
			this.buttons = [];
			this._events = [];
			dojo.forEach(buttons, function (button) {
				button.domNode=[];
				var tmplProcessor=new epages.Template({
					template: this.buttonTemplateString,
					vars    : {
						'Label': button.label,
						'Class': button.cssClass ? button.cssClass : '',
						'buttonId': (button.buttonId) ? 'buttonid='+button.buttonId+' ' : ''
					}
				});
				var buttonNode= this.createNodesFromText(tmplProcessor.generateOutput());
				this.innerButtonBarNode.appendChild(buttonNode);
				button.domNode=buttonNode;
				dojo.mixin(button, {_modalDialogWidget: this, _contentWidget: this._contentWidget});
				this._events.push({ event: dojo.connect(button.domNode, "onclick", button, "onclick"), button : button});
				this.buttons.push(button);
				if(button.isDisabled == 'true'){
					this.disableButton(buttonNode);
				}
			}, this);
			this.clearFloatNode = document.createElement("div");
			this.clearFloatNode.className="ClearBoth";
			this.innerButtonBarNode.appendChild(this.clearFloatNode);
		},

		_destroyButtons: function () {
			dojo.forEach(this._events, function(evtmap) {
				dojo.disconnect(evtmap.event);
			});
			dojo.forEach(this.buttons, function (button) {
				button.domNode.parentNode.removeChild(button.domNode);
				button.domNode = undefined;
			});
			this._events = null;
			delete this._events;			// delete var
			this.buttons=[];
			if(this.clearFloatNode !== undefined && this.clearFloatNode.parentNode != null) {
				this.clearFloatNode.parentNode.removeChild(this.clearFloatNode);
				this.clearFloatNode = undefined;
			}
		},

		_createTabs: function() {
		// summary: creates tabs by looking for dom nodes with css class "TabPage"
		// description: tab labels ar specified by attribute ep_label of the dom node
			var tabs = epages.html.getElementsByClassName('TabPage',this.containerNode);
			if(tabs.length && tabs.length > 1){
				this.tabBarNode.style.display="";
				dojo.addClass(this.tabBarNode, "Visible");
				this._tabs = [];
				this._tabEvents = [];
				dojo.forEach(tabs, function (domNode) {
					var tab = {
						domNode : [],
						changeNode: domNode
					};
					var tmplProcessor = new epages.Template({
						template: this.tabTemplateString,
						vars    : {
							'Label': domNode.getAttribute('ep_label')
						}
					});
					var tabNode = this.createNodesFromText(tmplProcessor.generateOutput());
					this.tabBarNode.appendChild(tabNode);
					tab.domNode = tabNode;
					//dojo.mixin(tab, {_modalDialogWidget: this, _contentWidget: this._contentWidget});
					this._tabEvents.push(dojo.connect(tab.domNode, "onclick", this, "_onTabClick"));
					tab.changeNode.style.display = 'none';
					this._tabs.push(tab);
				}, this);
				//activate first tab
				this._tabs[0].changeNode.style.display = '';
				dojo.addClass(this._tabs[0].domNode, 'Active');
				this._currentTab = this._tabs[0];
			} else {
				dojo.removeClass(this.tabBarNode, "Visible");
			}
		},

		_destroyTabs: function () {
			dojo.forEach(this._tabEvents, dojo.disconnect);
			dojo.forEach(this._tabs, function (tab) {
				tab.domNode.parentNode.removeChild(tab.domNode);
				tab.domNode = undefined;
				tab.changeNode = undefined;
			});
			this._tabs=[];
			this._currentTab = undefined;
		},

		_onTabClick: function(evt){
			var targetTab = evt.currentTarget;
			var tab = undefined;
			for( var i=0,iLength=this._tabs.length ; i<iLength ; i++ ){
				if(targetTab == this._tabs[i].domNode){
					tab = this._tabs[i];
				}
			}
			if(tab){
				if(this._currentTab){
					dojo.removeClass(this._currentTab.domNode,'Active');
					this._currentTab.changeNode.style.display = 'none';
				}
				tab.changeNode.style.display = '';
				dojo.addClass(tab.domNode, 'Active');
				this._currentTab = tab;
				dojo.publish(this.id+"/tabChange",[tab.changeNode]);
			}
		}
	}
);