/**
 * Util.js
 *
 * Created by Michael Kramer
 */


/**
 * A Data Grid Object
 * This data grid allows for mass selection of data in a table.
 * It supports pagination, individual selections on any page,
 * select/unselect page, and select/unselect all functions
 * 
 * Calling DataGrid.copySelectedIds() will copy all the ids into a 
 * form variable called selected_ids
 * 
 * @author Michael Kramer
 */
var DataGrid = function(){
	DATA_REFRESH_RATE = 5000; //ms
	return {
		class_prefix: '-tr-',
		tr_prefix: 'data', //Should be updated with whatever data type you are working with. (ie, account, group, message, etc)
		data_counter_id: 'selectCounter',
		form_id: '',
		href: '',
		contentPane: null,
		id_list: Array(),
		
		/**
		 * 
		 */
		add: function(id){
			index = dojo.indexOf(this.id_list, parseInt(id));
			if(index == -1){
				this.id_list.push(parseInt(id));
			} else {
				return false;
			}
			dojo.byId(this.tr_prefix+this.class_prefix+id).className += ' active';
			this.update();
			return true;
		},
		
		/**
		 * 
		 */
		remove: function(id){
			index = dojo.indexOf(this.id_list, parseInt(id));
			if(index != -1){
				this.id_list.splice(index, 1);
			} else {
				return false;
			}
			dojo.byId(this.tr_prefix+this.class_prefix+id).className = dojo.byId(this.tr_prefix+this.class_prefix+id).className.replace(' active','');
			this.update();
			return true;
		},
		
		/**
		 * 
		 */
		update: function(){
			if(dojo.byId(this.data_counter_id) != null){
				dojo.byId(this.data_counter_id).innerHTML = this.id_list.length;
			}
		},
		
		/**
		 * Go to the next page and submit the selected ids and add them to any previous.
		 * @param node
		 * @returns nothing
		 */
		submitNextPage: function(){
			var page = dojo.byId('current_page').value;
			page++;
			
			var tempActiveContentPane = this;
			dojo.xhrPost({
				url: this.href,
				dataGrid: this,
				handleAs: 'text',
				timeout: 5000,
				content: {
					selected_ids: [this.id_list],
					page: page,
					sort: this.sortAttribute,
					dir: this.sortDir
				},
				load: function(response){
					tempActiveContentPane.contentPane.attr('content', response);
				}
			});
		},
		
		/**
		 * 
		 */
		submitToPage: function(node){
			if (window.event.keyCode == 13)
			{
				dojo.stopEvent(window.event);
				var page = dojo.byId('current_page').value;
				if(page > dojo.attr(dojo.byId('current_page'), 'last_page') ){
					page = dojo.attr(dojo.byId('current_page'), 'last_page');
				}
				
				if(page < 1)
					page = 1;
				
				var tempActiveContentPane = this;
				dojo.xhrPost({
					url: this.href,
					handleAs: 'text',
					timeout: 5000,
					content: {
						selected_ids: [this.id_list],
						page: page,
						sort: this.sortAttribute,
						dir: this.sortDir
					},
					load: function(response){
						tempActiveContentPane.contentPane.attr('content', response);
					}
				});
			}
		},
		
		/**
		 * Go to the previous page and submit the selected ids and add them to any previous.
		 * @param node
		 * @returns nothing
		 */
		submitPrevPage: function(contentPane){
			var page = dojo.byId('current_page').value;
			page--;
			var tempActiveContentPane = this;
			dojo.xhrPost({
				url: this.href,
				handleAs: 'text',
				timeout: 5000,
				content: {
					selected_ids: [this.id_list],
					page: page,
					sort: this.sortAttribute,
					dir: this.sortDir
				},
				load: function(response){
					tempActiveContentPane.contentPane.attr('content', response);
				}
			});
		},
		
		/**
		 * Select Page
		 * @param node
		 * @returns nothing
		 */
		selectPage: function(node){
			dojo.query('.select-box').forEach(function(checkbox){
				checkbox.checked = node.checked;
				if(node.checked == true){
					this.add(checkbox.value);
				} else{
					this.remove(checkbox.value);
				}
			}, this);
		},
		
		/**
		 * Update Select Page
		 * @param node
		 * @returns nothing
		 */
		updateSelectPage: function(){
			this.page_select_all = true;
			dojo.query('.select-box').forEach(function(checkbox){
				if(checkbox.checked == false){
					this.page_select_all = false;
				}
			}, this);
			dojo.byId('select_page').checked = this.page_select_all;
			
		},
		
		/**
		 * 
		 * @param checkbox
		 * @returns nothing
		 */
		updateSelected: function(checkbox){
			if(checkbox.checked == true){
				this.add(checkbox.value);
			} else{
				this.remove(checkbox.value);
			}
			this.updateSelectPage();
		},
		
		/**
		 * Select all
		 * @param node
		 * @returns nothing
		 */
		selectAll: function(node){
			this.id_list = this.all_ids.slice(0); //copy them over.
			dojo.query('.select-box').forEach(function(checkbox){
				checkbox.checked = true;
				if(dojo.byId(this.tr_prefix+this.class_prefix+dojo.attr(checkbox, 'value')).className.indexOf(' active') == -1){
					dojo.byId(this.tr_prefix+this.class_prefix+dojo.attr(checkbox, 'value')).className += ' active';
				}
			}, this);
			this.update();
			this.updateSelectPage();
		},
		
		/**
		 * Unselect all
		 * @param node
		 * @returns nothing
		 */
		unselectAll: function(node){
			this.id_list = Array();
			dojo.query('.select-box').forEach(function(checkbox){
				checkbox.checked = false;
				dojo.byId(this.tr_prefix+this.class_prefix+dojo.attr(checkbox, 'value')).className = dojo.byId(this.tr_prefix+this.class_prefix+dojo.attr(checkbox, 'value')).className.replace(' active','');
			}, this);
			this.update();
			this.updateSelectPage();
		},
		
		/**
         * Set certain ids selected
         * @param ids string of sms_account_ids
         * @returns nothing
         */
		setSelected: function(ids){
			this.unselectAll(); //start fresh
			this.id_list = ids.split(','); //copy them over.
			//get list of boxes on page, select those that are needed to be there.
			dojo.query('.select-box').forEach(function(checkbox){
				if(this.inArray(dojo.attr(checkbox, 'value'), this.id_list)){
					checkbox.checked = true;
					if(dojo.byId(this.tr_prefix+this.class_prefix+dojo.attr(checkbox, 'value')).className.indexOf(' active') == -1){
						dojo.byId(this.tr_prefix+this.class_prefix+dojo.attr(checkbox, 'value')).className += ' active';
					}
				}
			}, this);
			this.update();
			this.updateSelectPage();
		},
        
		/**
         * Find out if needle is in haystack
         * @param needle
         * @param haystack
         */
		inArray: function (needle, haystack) {
			var length = haystack.length;
			for(var i = 0; i < length; i++) {
				if(haystack[i] == needle) return true;
			}
			return false;
		},
		
		/**
		 * Copy the selected id's to the form
		 */
		copySelectedIds: function(){
			dojo.byId('selected_ids').value = this.id_list.join(',');
		},
		
		/**
		 * Run a mass action on our selected data
		 */
		updateMassAction: function(node){
			dojo.byId(this.form_id).action = BASE_URL + node.value;
		},
		
		setupSort: function(field, dir){
			dojo.query('th.sort').forEach(function(th){
				th.grid = this;
				//clear from ALL of them at first
				dojo.removeClass(th, 'desc');
				dojo.removeClass(th, 'asc');
                
				if(dir != '' && dojo.attr(th, 'field') == field){
					dojo.attr(th,'direction',dir);
				} else {
					dojo.attr(th,'direction','DESC'); // DEFAULT
				}
				if(dir == 'DESC' && dojo.attr(th, 'field') == field){
					dojo.attr(th,'direction','ASC');
					dojo.addClass(th, 'desc');
				} else if(dojo.attr(th, 'field') == field){
					dojo.attr(th,'direction','DESC');
					dojo.addClass(th, 'asc');
				}

				dojo.connect(th, "onclick", th, function(){
					th.grid.sort(th);
				});
			},this);
		},
		
		sort: function(th){
			dir = dojo.attr(th, 'direction');
			attribute = dojo.attr(th, 'field');
			//TODO: classes
			this.sortAttribute = attribute;
			this.sortDir = dir;
			var page = dojo.byId('current_page').value;
			var tempActiveContentPane = this;
			dojo.xhrPost({
				url: this.href,
				handleAs: 'text',
				timeout: 5000,
				content: {
					selected_ids: [this.id_list],
					page: page,
					sort: attribute,
					dir: dir
				},
				load: function(response){
					tempActiveContentPane.contentPane.attr('content', response);
				}
			});
		},
		
		refresh: function(){
			var tempActiveContentPane = this;
			var page = dojo.byId('current_page').value;
			dojo.xhrPost({
				url: this.href,
				dataGrid: this,
				handleAs: 'text',
				timeout: 5000,
				content: { 
					selected_ids: [this.id_list],
					page: page
				},
				load: function(response){
					tempActiveContentPane.contentPane.attr('content', response);
				}
			});
		}
	};
};

/**
 * CharacterCounter
 * 	Allows you to set a character limit on a given Textarea or Input field
 * and display the value in a DOM Nodes innerHTML. It will also limit
 * the amount of text that can be in the textarea.
 * 
 * @author Michael Kramer
 */
var CharacterCounter = function(){
	return {
		init: function(node, display, maxValue){
			this.node = node;
			this.display = display;
			this.maxValue = maxValue;
			this.update();
		},
		/**
             * Update character limits of the given textarea field and display results in the display node.
             * @param node
             * @param display
             * @param maxValue
             * @returns nothing
             */
		update: function(){
			if(typeof this.node != 'undefined'){
				if(this.node.get('value').length > this.maxValue){
					this.node.set('value', this.node.get('value').substr(0, this.maxValue) );
				} else{
					this.display.innerHTML = this.node.get('value').length +'/'+this.maxValue;
				}
			}
		}
	};
};

var Virge = new function(){
	return{
		timeout: null,
		started: false,
		/**
		 * Fade In a given target
		 *
		 * @param target The target we are Fading In
		 * @param d The duration of the Fade
		 */
		fadeIn: function(target, d){
			target.style.display = 'block';
			var args = {
				node: target,
				duration: d,
				properties: {
					opacity: {
						start:0.2,
						end:1.00
					}
				}
			};
			dojo.animateProperty(args).play();
		},

		getNotificationBox: function(){
			if(dojo.byId('notifications') != null){
				return dojo.byId('notifications');
			} else {
				return dojo.create('div', {
					id: 'notifications', 
					innerHTML: '<div class="top"></div><div class="content"><ul id="notification-box"></ul></div><div class="bottom"></div><div class="clear"></div>',
					style: {display: 'none'}
				}, dojo.byId('middle'), 'before');
			}
		},

		addNotification: function(message){
			if (this.started == true) {
				setTimeout(function() {Virge.addNotification(message)}, 200);
				return;
			} 
			if (this.timeout) {
				clearTimeout(this.timeout);
			}
			
			var notfication_box = this.getNotificationBox();
			if (notfication_box.style.display == 'none') {
				Virge.fadeIn(notfication_box, 500);
			}
			dojo.hash("notifications",true);

			this.node = dojo.create('li', {
				innerHTML:message, 
				style:'display:none;'
			}, dojo.byId('notification-box'));
			Virge.fadeIn(this.node, 500);
			Virge.startNotificationCleanup();
		},
		
		startNotificationCleanup: function() {
			var notfication_box = Virge.getNotificationBox();
			notfication_box.style.overflow='hidden';
			if (this.timeout) {
				clearTimeout(this.timeout);
			}
			if (notfication_box.style.display != 'none') {
				this.timeout=setTimeout(function() {
					Virge.started = true;
					var args = {
						node: notfication_box,
						duration: 1000,
						properties: {
							opacity: {
								start:1.00,
								end:0.0
							},
							height: {start: dojo.contentBox(notfication_box).h, end: 0},
							marginTop: {end: 0}
						},
						onEnd: function() {
							notfication_box.style.display='none';
							notfication_box.style.marginTop='20px';
							notfication_box.style.height='auto';
							dojo.query("#notifications li").forEach(dojo.destroy);
							Virge.started = false;
						}
					};
					dojo.animateProperty(args).play();
				}, 5000);
			}
		}
	};
}

dojo.addOnLoad(function(){
	// Deals with notification box disapearing after some time
	Virge.startNotificationCleanup();
	// Starts the quick edit dialog widget
    quickEditor.init();
});

var quickEditor = new function(){
    var quickEditorDialog;
    var formConnect;
    var quickEditForm;
    return {
        init: function () {
	        quickEditorDialog = new dijit.Dialog({id:'quickEditorDialog'});
        },
        hide: function () {
            quickEditorDialog.hide();
        },
        show: function () {
            quickEditorDialog.show();
        },
        loadData: function (data, onComplete, onLoad) {
            if (data == null || data == '') {
                quickEditor.loadError(error);
                return false;
            }
            if (data.content != '') {
                quickEditorDialog.set('content', data.content);
                quickEditor.setupForm(onComplete, onLoad);
                dojo.query("#quickEditForm button[type='submit'], #quickEditForm input[type='submit']").forEach(function(node){
                    dojo.connect(node, 'onclick', function (event) {
                        event.preventDefault();
                        quickEditor.sendForm(node, onComplete, onLoad);
                    });
                });
            } else {
                quickEditorDialog.hide();
            }
            var message = '';
            dojo.forEach(data.notifications, function(n) {
                if (data.content == '') {
                    Virge.addNotification(n);
                } else {
                    message += "- " + n + "\n";
                }
            });
            if (message != '') {
                alert(message);
            }
            return true;
        },
        loadError: function (error) {
            quickEditorDialog.hide();
            alert('There was an error loading: ' + error);
        },
        load: function (title, url, onComplete, onLoad) {
            quickEditorDialog.set('title', title);
            quickEditorDialog.set('content', "Loading...");
            quickEditorDialog.show();
            if (onComplete == null) {
                onComplete = function () {};
            }
            if (onLoad == null) {
                onLoad = function () {};
            }
            var xhrArgs = {
                url: url,
                handleAs: "json",
                load: function(data) {
                    if (quickEditor.loadData(data, onComplete, onLoad) == false) {
                        return false;
                    }
                },
                error: function(error) {
                    quickEditor.loadError(error);
                }
            }
            var deferred = dojo.xhrPost(xhrArgs);
        },
        setupForm: function (onComplete, onLoad) {
            onLoad();
            quickEditForm = dojo.byId("quickEditForm");
            formConnect = dojo.connect(quickEditForm, "onsubmit", function(event) {
                event.preventDefault();
                quickEditor.sendForm(null, onComplete, onLoad);
            });
        },
        sendForm: function (target, onComplete, onLoad) {
            dojo.disconnect(formConnect);
            var content = new Object();
            if (target != null && dojo.attr(target, 'name') != null && dojo.attr(target, 'value') != null && (target.tagName == 'BUTTON' || target.tagName == 'SUBMIT')) {
                content[dojo.attr(target, 'name')] = dojo.attr(target, 'value');
            }
            var xhrArgs = {
                form: quickEditForm,
                handleAs: "json",
                content: content,
                load: function(data) {
                    if (quickEditor.loadData(data, onComplete, onLoad) != false && data.content == '') {
                        onComplete();
                    }
                },
                error: function(error) {
                    quickEditor.loadError(error);
                }
            }
            var deferred = dojo.xhrPost(xhrArgs);
            quickEditorDialog.set('content', "Processing...");
        }
    }
}
