/*
    Class: MEMOZ.dialog
    Provides a simple dialog
    
    Parameters:
    	elId		- Either the element id of an existing div or an object containing instructions to create the dialog {id, title, zIndex}
    	callback	- callback function on close
    	ajaxParams	- Parameters for AJAX request
    	fields		- Form input fields (array)
    	dlgParams	- (optional) Extra dialog parameters object, like width, etc..
*/
MEMOZ.dialog = function(elId, callback, ajaxParams, fields, dlgParams) {
    if (callback) this.callback = callback;
    if (ajaxParams) this.ajaxParams = ajaxParams;
    if (fields) this.fields = fields;
    if (dlgParams) this.dlgParams = dlgParams;

    if (typeof elId == 'object') {
    	this.id = elId.id;
    	this.title = elId.title;
    	this.zIndex = elId.zIndex;
    	if (MEMOZ.loaded) {
		    console.info(' --> now');
    		this.createMarkup();
    	} else {
		    console.info(' --> later');
    		onWindowLoad.subscribe(this.createMarkup, this, true);
    	}
	} else {
	    this.id = elId;
		YAHOO.util.Event.onAvailable(this.id, this.draw, this, true);
	}
}


onWindowLoad.subscribe(function() { 
	MEMOZ.dialog.mySimpleDialog = new YAHOO.widget.SimpleDialog('memozSimpleDlg', {  
		width: '30em',
		visible: false,
		monitorresize: true,
		zIndex: 959,
		text: " ",
		fixedcenter: true,
		icon: YAHOO.widget.SimpleDialog.ICON_INFO																	   
		// keylisteners: listenForReturn,
	}); 
	MEMOZ.dialog.mySimpleDialogOnHideParam = 0;
	MEMOZ.dialog.mySimpleDialog.hideEvent.subscribe(function() {
		MEMOZ.dialog.simpleOnHide();
	});
	MEMOZ.dialog.mySimpleDialog.render(document.body);
	// console.log('make dlg');
});


MEMOZ.dialog.simpleOnHide = function() {
	MEMOZ.hideModalBg();

	if (MEMOZ.dialog.mySimpleDialogOnHide)
		MEMOZ.dialog.mySimpleDialogOnHide(MEMOZ.dialog.mySimpleDialogOnHideParam);	
}

/*
	Function: infoDlg
	Displays a simle info dialog with a "Ok"-button.
	
	Parameters:
		str 			 - Dialog text
		onHideCallbackFn - callback function (optional)

	Example:
		MEMOZ.dialog.infoDlg("Informasjonen ble lagret.");

*/
MEMOZ.dialog.infoDlg = function(str, onHideCallbackFn) {
	
	if (!MEMOZ.dialog.mySimpleDialog) {
		MEMOZ.log("Could not show dialog because it hasn't been created yet!",'error');
	}
	
	MEMOZ.dialog.mySimpleDialogOnHideParam = 0;
    MEMOZ.dialog.mySimpleDialogOnHide = onHideCallbackFn;
    console.log(YAHOO.widget.SimpleDialog.ICON_INFO);
	MEMOZ.dialog.mySimpleDialog.cfg.setProperty('buttons', [
		{ text: "Ok", isDefault: true, handler: function() { 
			MEMOZ.dialog.mySimpleDialogOnHideParam = 0;
			this.hide(); 
		}}
	]);    
    MEMOZ.dialog.mySimpleDialog.setBody("<table width='100%'><tr><td width='40'><img src='imgs/info32.png'></td><td>"+str+"</td></tr></table>");
    MEMOZ.showModalBg();
    MEMOZ.dialog.mySimpleDialog.show(); 

}

/*
	Function: errorDlg
	Displays a simle info dialog with a "Ok"-button.

	Parameters:
		str - Dialog text
		onHideCallbackFn - callback function
*/
MEMOZ.dialog.errorDlg = function(str, onHideCallbackFn) {

	if (!MEMOZ.dialog.mySimpleDialog) {
		MEMOZ.log("Could not show dialog because it hasn't been created yet!",'error');
	}

	MEMOZ.dialog.mySimpleDialogOnHideParam = 0;
    MEMOZ.dialog.mySimpleDialogOnHide = onHideCallbackFn;
	MEMOZ.dialog.mySimpleDialog.cfg.setProperty('buttons', [
		{ text: "Ok", isDefault: true, handler: function() { 
			MEMOZ.dialog.mySimpleDialogOnHideParam = 0;
			this.hide(); 
		}}
	]);    
    MEMOZ.dialog.mySimpleDialog.setBody(str);
    MEMOZ.dialog.mySimpleDialog.cfg.setProperty('icon',YAHOO.widget.SimpleDialog.ICON_WARN);
    MEMOZ.showModalBg();
    MEMOZ.dialog.mySimpleDialog.show(); 
}

/*
	Function: confirmDlg
	Displays a simple confirmation dialog with "Yes"- and "No"-buttons.
	
	Parameters:
		str - Dialog text
		onHideCallbackFn - callback function
	
	Example:
		MEMOZ.dialog.confirmDlg("Are you sure?", function(confirmed) { console.log(confirmed); });
*/
MEMOZ.dialog.confirmDlg = function(str, onHideCallbackFn) {

	if (!MEMOZ.dialog.mySimpleDialog) {
		MEMOZ.log("Could not show dialog because it hasn't been created yet!",'error');
	}

	MEMOZ.dialog.mySimpleDialogOnHideParam = 0;
    MEMOZ.dialog.mySimpleDialogOnHide = onHideCallbackFn;
    MEMOZ.dialog.mySimpleDialog.cfg.setProperty('buttons', [
		{ text: "Ja", handler: function() { 
			MEMOZ.dialog.mySimpleDialogOnHideParam = true;
			this.hide(); 
		}},{ text: "Nei", isDefault: true, handler: function() { 
			MEMOZ.dialog.mySimpleDialogOnHideParam = false;
			this.hide(); 
		}}
	]);
    MEMOZ.dialog.mySimpleDialog.setBody("<table width='100%'><tr><td width='40' valign='top'><img src='imgs/question32.png'></td><td>"+str+"</td></tr></table>");
    //MEMOZ.dialog.mySimpleDialog.cfg.setProperty('icon', YAHOO.widget.SimpleDialog.ICON_HELP);
    // MEMOZ.dialog.mySimpleDialog.cfg.setProperty('fixedcenter', true);
    MEMOZ.showModalBg();
    MEMOZ.dialog.mySimpleDialog.show(); 
}

YAHOO.extend(MEMOZ.dialog, MEMOZ.base, {

    _className: "MEMOZ.dialog",
	
	id: '', // Element id
	title: '',
	zIndex: 962,

	fields: [],
	callback: '',
	ajaxParams: {},
	dlgParams: {},
	instance: null,
	isWorking: false,
	keylistener: null,
	statusIndicator: "<img src='imgs/indicator6.gif' alt='One moment...' />",
    
    createMarkup: function() {
    
		if ($(this.id)) {
			MEMOZ.log('The dialog div '+this.id+' already exists!','error',true);
			this.draw();
			return;
		}
		var dlgDiv = document.createElement('div');
		dlgDiv.id = this.id;
		YAHOO.util.Dom.addClass(dlgDiv,'memozDlg');      
		var cache = '<div class="hd">'+this.title+'</div>'+
			'<div class="bd">' +
			'	<form id="'+this.id+'Form" method="POST" onsubmit="return false;">'+
			'	<table>';
		for (var i = 0; i < this.fields.length; i++) {
			f = this.fields[i]; 
			cache += '<tr><td align="right"><label id="'+this.id+f.id+'Label" for="'+this.id+f.id+'">'+f.label+':</label></td><td>';
			switch (f.type) {
				case 'checkbox':
					cache += '<input type="checkbox" id="'+this.id+f.id+'" class="textField">';
					break;
				case 'file':
					cache += '<input type="file" id="'+this.id+f.id+'">';
					break
				default:
					cache += '<input type="text" id="'+this.id+f.id+'" value="'+f.def+'" class="textField" style="width:180px;">';
					break;
			}
			cache += '</td></tr>';
		}
		cache += '</table><div id="'+this.id+'Status" class="errors"><!-- --></div> ' +
			'</form></div>';
		dlgDiv.innerHTML = cache;
		document.body.appendChild(dlgDiv);
		
        YAHOO.util.Event.onContentReady(this.id, this.draw, this, true);
	},
    
    /*
    	Method: draw
    	Should be called only once, at load
    */
    draw: function() {
    	//console.info('draw dialog');
    	//console.info(document.getElementById(this.id));

        var me = this;
        this.keylistener = new YAHOO.util.KeyListener(document, 
            { keys:[13,27] },           
            { fn:function(type, args, obj) { 
                if (args[0] == 27) me.cancel();
                else me.instance.submit();
            } } 
        )
        var  btns;
        if (this.fields.length > 0) {
        	btns = [
                { text:this.getLabel('btnOk'), handler:function(){ this.submit(); }, isDefault:true }, 
                { text:this.getLabel('btnCancel'), handler:function(){ me.cancel(); } } 
            ];
        } else {
        	btns = [
                { text:this.getLabel('btnClose'), handler:function(){ this.cancel(); }, isDefault:true }
            ];        
        }
        
        var dlgParams = {
            visible: false,
            width: '400px',
            zIndex: this.zIndex,
            postmethod: 'manual',
            hideaftersubmit: false,
            close: false,
            modal: false,
            keylisteners: this.keylistener,
            fixedcenter: true,
            buttons: btns
        };
        for (i in this.dlgParams) {
        	dlgParams[i] = this.dlgParams[i];
        }
        this.instance = new YAHOO.widget.Dialog(this.id, dlgParams);
                
        // we don't want to hide the dialog before we get a response from the server
        this.instance.validate = function() { 
	    	if (me.isWorking) {
	    		console.info("Already working... please be patient.");
	    		return false;
	    	} else {
	    		return true;
	    	}
        }; 
        
        this.instance.submitEvent.subscribe(this.onSubmit, this, true);
        this.instance.beforeHideEvent.subscribe(this.onBeforeHide, this, true);
        this.instance.hideEvent.subscribe(this.onHide, this, true);
        this.instance.showEvent.subscribe(this.onShow, this, true);
        this.instance.cancelEvent.subscribe(this.onCancel, this, true);

        this.instance.render();
        
        for (var i = 0; i < this.fields.length; i++) {
        	if ($(this.id+this.fields[i].id) == null) {
        		MEMOZ.log("Error in the dialog "+this.id+". The field '"+this.fields[i].id+"' could not be found!","error");
        	}
        }
    },
    
    /*
    	Method: cancel
    	Hides the dialog if not working
    */
    cancel: function() {
    	if (this.isWorking) {
	    	console.info("Already working... please be patient.");
	    	return false;
	    } else {
	    	this.instance.cancel();
	    	return true;
	    }
    },


    /*
    	Method: show
    	Shows the dialog
    */
    show: function() {
        this.instance.show();
    },
    
    /*
    	Method: show
    	Set state
    	
    	Parameters:
    		isWorking - (booL) True to show the status-indicator and lock the dialog, 
    					false to hide the status-indicator and unlock the dialog.
    */
    setWorking: function(isWorking) {
		this.isWorking = isWorking;
    	var statusDiv = $(this.id+'Status');
    	if (statusDiv) {
			if (isWorking) {				
				statusDiv.innerHTML = this.statusIndicator;
			} else {
				statusDiv.innerHTML = "";    	    	
			}
		}
    },
    
    /*
    	Method: errorMessage
    	Outputs an error message
    	
    	Parameters:
    		str - (string) The error text
    */
    errorMessage: function(str) {
    	var statusDiv = $(this.id+'Status');
    	if (statusDiv) {
			statusDiv.innerHTML = str;			
		}
		// MEMOZ.log(str,'error');
    },
    
    /*
    	Method: isUploadCase
    	Checks if we need to upload something
    	
    	Returns:
    		True if we have an [input type='file'] field in the form.
    */
    isUploadCase: function() {
    	for (var i = 0; i < this.fields.length; i++) {
			if (this.fields[i].type == 'file') return true;
		}
		return false;
    },
    
    dummyFilter: function(el) {
    	return true;
    },

    /*
    	Method: submit
    	Submits the dialog form using <MEMOZ.ajaxReq> or YAHOO.util.Connect.asyncRequest if
    	we need to upload something.
    	
    	Returns:
    		True if we have an [input type='file'] field in the form.
    */
    submit: function() {
        MEMOZ.log('[dialog] Submitting form...');
        var me = this;
        var Dom = YAHOO.util.Dom;
        this.setWorking(true);
    	this.instance.blurButtons();
                
        if (this.isUploadCase()) {
        
	        MEMOZ.log('[dialog] Upload case');
        	var dialogDiv = $(this.id);
        	var forms = Dom.getElementsBy(this.dummyFilter, 'form', dialogDiv);
        	if (forms.length != 1) {
        		MEMOZ.log(forms.length+' forms were found in this dialog. Can\'t continue...','error');
        		return false;
        	}
        	var formEl = forms[0];
                
			// the second argument is true to indicate file upload. 
			YAHOO.util.Connect.setForm(formEl, true); 
			MEMOZ.log("Uploading file...");
			MEMOZ.ajaxTransactionId++; // We must manually update this!
	        MEMOZ.log('[dialog] Request');
			var cObj = YAHOO.util.Connect.asyncRequest('POST', './?upload', {
				timeout: 5000, 
				upload: function(o){ me.uploadComplete(o); }, 
				failure: function(o){ me.uploadFailed(o); }
			}); 
		
		} else {
        
	        MEMOZ.log('[dialog] Normal case');
			var postObj = this.ajaxParams;
			for (var i = 0; i < this.fields.length; i++) {
				var el = document.getElementById(this.id+this.fields[i].id);
				if (this.fields[i].type == 'checkbox') {
					postObj[this.fields[i].submitAs] = el.checked;
				} else {
					postObj[this.fields[i].submitAs] = el.value;
				}
			}
			this.ajaxReq(postObj.action,'ajaxReply', postObj);
		
		}
    },
    
    ajaxReply: function(json) {
    	this.setWorking(false);
        if (json.error == 0) {
    		this.instance.hide();
    	} else {
    		this.errorMessage(json.error);
    	}
    	this.callback.ref[this.callback.fn](json);
    },
 
    
    /* 	------------------------------------------------------- 
    	 Section: Event listeners 
    	------------------------------------------------------- */ 

	onShow: function() {
		for (var i = 0; i < this.fields.length; i++) {
        	if (this.fields[i].focus) {
        		console.info("Set focus to "+this.id+this.fields[i].id);
        		setTimeout("$('"+this.id+this.fields[i].id+"').focus()",100);
        		break;
        	}
        }
	},
	
    /*
    	Method: onBeforeHide
    	Called before dialog hide.
    */
    onBeforeHide: function() {
    	console.info("Before hide");
    	console.info("Resetting dialog "+this.id+" ("+this.fields.length+" fields)");
    	var statusDiv = $(this.id+'Status');
    	if (statusDiv) statusDiv.innerHTML = "";
        for (var i = 0; i < this.fields.length; i++) {
        	var el = document.getElementById(this.id+this.fields[i].id);
        	if (this.fields[i].type == 'text' || this.fields[i].type == 'hidden' || this.fields[i].type == 'password') {
		        el.value = this.fields[i].def;
        	} else if (this.fields[i].type == 'checkbox') {
		        el.checked = this.fields[i].def;
        	}
	        YAHOO.util.Dom.setStyle(this.id+this.fields[i].id+'Label', 'color', '#000000');
    	    YAHOO.util.Dom.setStyle(this.id+this.fields[i].id+'Label', 'font-weight', 'normal');
        }    	
    },

    /*
    	Method: onHide
    	Called on dialog hide. Resets the dialog
    */
    onHide: function() {
            
    },

    /*
    	Method: onCancel
    	Called on cancel.
    */
    onCancel: function() {
    	console.info("[event] cancel");
    },

    /*
    	Method: onSubmit
    	Called on submit.
    */
    onSubmit: function() {
    	console.info("[event] submit");
    	this.submit();
    },
    
    /* 	------------------------------------------------------- 
    	 Section: Upload 
    	------------------------------------------------------- */ 
    
	/* 
		Method: uploadComplete
		Callback function for the YAHOO.util.Connect.asyncRequest upload
		
		Parameters:
			o - <object> Return from server
	*/
	uploadComplete: function(o) {
        this.setWorking(false);
        console.log(o.responseText);
        try {
            var json = eval('(' + o.responseText + ')');
        } catch(err) {
            var json = { error: 'serverError'};
        }
        switch (json.error) {
            case 0:
	    		this.instance.hide();
                break;
            default:
                this.errorMessage(json.error);
                break;            
        }
    	this.callback.ref[this.callback.fn](json);
    },

    /* 
		Method: uploadFailed
		Callback function for the YAHOO.util.Connect.asyncRequest upload
		
		Response object (o) contains:
			tId  		- The transaction id
			status 		- 0  (or -1 if aborted by client-sidetimeout)
			statusText 	- "communication failure" (or "transaction aborted" if aborted by client-sidetimeout)
			argument 	- The user-defined argument or arguments as defined as the callback object.
		
		Parameters:
			o - <object> Return from server
	*/
	uploadFailed: function(o) {
        this.setWorking(false);
        if (o.status == 0) {
	    	this.errorMessage('Opplastingen mislyktes pga. en meget ukjent feil!');
	    } else {
	    	this.errorMessage('Opplastingen mislyktes fordi den tok for lang tid!');	    
	    }
    }
    
});