var $ = YAHOO.util.Dom.get;
var dh = Ext.DomHelper;

var gNexusInfo = new Array();
var gNexusObjectRegistry = new ObjectRegistry();

var kNexusTypeDocument = 'doc';
var kNexusTypeCategory = 'cat';

var kViewIcon = 'icon';
var kViewList = 'list';

var kCookieViewType = 'viewtype';

var kTriggerText = 'text_trigger';
var kTriggerImage = 'image_trigger';

var gCurrentContext = '';

(function() {
    YAHOO.namespace('widget.alert');

    alert_old = window.alert;
    window.alert = function(str) {
        YAHOO.widget.alert.dlg.setBody(str);
        YAHOO.widget.alert.dlg.cfg.queueProperty('icon', YAHOO.widget.SimpleDialog.ICON_WARN);
        YAHOO.widget.alert.dlg.cfg.queueProperty('zIndex', 9999);
        YAHOO.widget.alert.dlg.render(document.body);
        if (YAHOO.widget.alert.dlg.bringToTop) {
            YAHOO.widget.alert.dlg.bringToTop();
        }
        YAHOO.widget.alert.dlg.show();
    };


    YAHOO.util.Event.on(window, 'load', function() {

        var handleOK = function() {
            this.hide();
        };

        YAHOO.widget.alert.dlg = new YAHOO.widget.SimpleDialog('widget_alert', {
            visible:false,
            width: '20em',
            zIndex: 9999,
            close: false,
            fixedcenter: true,
            modal: false,
            draggable: true,
            constraintoviewport: true, 
            icon: YAHOO.widget.SimpleDialog.ICON_WARN,
            buttons: [
                { text: 'OK', handler: handleOK, isDefault: true }
                ]
        });
        YAHOO.widget.alert.dlg.setHeader("Alert!");
        YAHOO.widget.alert.dlg.setBody('Alert body passed to window.alert'); // Bug in panel, must have a body when rendered
        YAHOO.widget.alert.dlg.render(document.body);
    });
})();

/**
 * The ask dialog generates a YUI dialog that presents a given message and
 * YES/NO buttons.  On 'yes', the given yesCallback function is called.  On 
 * no, nothing happens. 
 * @param {String} title The title for the dialog
 * @param {String} message The message to display in the dialog
 * @param {Function} yesCallback The function reference to call when user hits 'yes'
 */
function askDialog (title, message, yesCallback)
{
    //alert('This is a test');

    var handleNo = function (){mySimpleDialog.hide();}
    
	mySimpleDialog = new YAHOO.widget.SimpleDialog("dlg", {  
            visible:false,
            width: '20em',
            zIndex: 9999,
            close: false,
            fixedcenter: true,
            modal: false,
            draggable: true,
            constraintoviewport: true, 
            icon: YAHOO.widget.SimpleDialog.ICON_HELP,
            buttons: [
                { text:"Yes", handler:yesCallback }, 
                { text:"Cancel",  handler:handleNo, isDefault:true } 
            ]
        });
	
    mySimpleDialog.setHeader(title); 
    mySimpleDialog.setBody(message); 
    
	mySimpleDialog.render(document.body);
	mySimpleDialog.show();
}

/**
 * The tell dialog generates a YUI dialog that presents a given message and
 * OK buttons. 
 * @param {String} title The title for the dialog
 * @param {String} message The message to display in the dialog
 */
function tellDialog (title, message)
{
    var handleOk = function (){mySimpleDialog.hide();}
    
	mySimpleDialog = new YAHOO.widget.SimpleDialog("dlg", {  
            visible:false,
            width: '20em',
            zIndex: 9999,
            close: false,
            fixedcenter: true,
            modal: false,
            draggable: true,
            constraintoviewport: true, 
            icon: YAHOO.widget.SimpleDialog.ICON_INFO,
            buttons: [
                { text:"OK",  isDefault:true, handler:handleOk } 
            ]
        });	
	
	mySimpleDialog.setHeader(title); 
	mySimpleDialog.setBody(message); 
	mySimpleDialog.render(document.body);
	mySimpleDialog.show();  		
}

function makeDialog(containerId,formId,successCallback,hasCancel)
{
	var dialog = new YAHOO.widget.Dialog(containerId, {visible : false, fixedcenter: true, modal : true});
		
	//var handleSubmit = function() {xajax_shAjaxServer.submitForm(successCallback,xajax.getFormValues(formId)); this.hide();};
	var handleSubmit = function() {xajax_shAjaxServer.submitForm(successCallback,this.getData()); this.hide();};
	var handleCancel = function() {this.cancel(); };
	
	var myButtons = null;
	if (hasCancel)
	{
		myButtons = [ { text:"Submit",handler:handleSubmit, isDefault:true },  { text:"Cancel", handler:handleCancel }];	
	}
	else
	{
		myButtons = [ { text:"Submit",handler:handleSubmit, isDefault:true } ];	
	}
		
	dialog.cfg.queueProperty("buttons", myButtons);
	dialog.cfg.queueProperty("postmethod","manual");
	dialog.render(document.body);
	
	return dialog;
}

/**
 * Creates a normal modal Nexus dialog.  It uses a plain html div that contains
 * the form and uses the action attribute of the form to do the submission.
 * The submission, though, is handled asyncronously, therefore it is up
 * to the caller to correctly handle async events using the YUI.
 * @param string formId The ID of the div that contains the form to display in the dialog
 * @param string dialogTitle The title of the dialog to display
 * @param bool hasCancel True to show a cancel button, false otherwise.
 * @return Returns a YAHOO.widget.Dialog
 */
function createDialog(formContainerId, formId, dialogTitle,hasCancel)
{
	var dialog = new YAHOO.widget.Dialog(formContainerId, {visible : false, fixedcenter: true, modal : true});
	dialog.setHeader (dialogTitle);
	
	var handleSubmit = function() {xajax_shAjaxServer.submitForm(xajax.getFormValues(formId)); this.hide();};
	var handleCancel = function() {this.cancel(); };
	
	var myButtons = null;
	if (hasCancel)
	{
		myButtons = [ { text:"Submit",handler:handleSubmit, isDefault:true },  { text:"Cancel", handler:handleCancel }];	
	}
	else
	{
		myButtons = [ { text:"Submit",handler:handleSubmit, isDefault:true } ];	
	}
		
	dialog.cfg.queueProperty("buttons", myButtons);
	dialog.cfg.queueProperty("postmethod","manual");
	dialog.render();
	
	return dialog;
}

/**
 * This will update the text/image that the user clicks on
 * to switch between icon and list view. It uses the currently
 * stored cookie to know what is currently being displayed.
 * @param {Object} triggerId The Id of the element that is displaying the
 * 					text or image that the user clicks on to change the view
 * @param {Object} triggerType The type of element this is displaying
 * 					(kTriggerText or kTriggerImage).
 */
function updateBrowseViewTypeText(triggerId, triggerType)
{
	var viewText = YAHOO.util.Dom.get(triggerId);
	var currentView = YAHOO.Tools.getCookie(kCookieViewType);
	
	if (currentView == kViewIcon || currentView == "" || currentView == null)
	{
		if (triggerType == kTriggerText)			
			viewText.innerHTML = 'Switch to List View';
		else
			viewText.innerHTML = "<img border='0' title='Switch to List View' src='themes/default/images/view_icon.jpg' />";
	}
	else
	{
		if (triggerType == kTriggerText)
			viewText.innerHTML = 'Switch to Icon View';
		else
			viewText.innerHTML = "<img border='0' title='Switch to Icon View' src='themes/default/images/view_list.jpg' />";			
	}			
}

/**
 * Switches the browser view (contained inside nexusObjects element) to whatever
 * 	view it's NOT displaying. It also updates the trigger with the appropriate
 * 	text (or image).
 * @param {Object} triggerId
 */
function toggleLibraryBrowserView(triggerId)
{
	var objectContainer = YAHOO.util.Dom.get('nexusObjects');
	objectContainer.innerHTML = '';
	
	var newViewStyle = kViewIcon;
	var lastStyle = YAHOO.Tools.getCookie(kCookieViewType);
	
	if ((lastStyle == kViewIcon) || (lastStyle == null))
	{
		newViewStyle = kViewList;
	}
	
	var i=0;
	for (i; i < gNexusObjectRegistry.count(); i++)
	{
		obj = gNexusObjectRegistry.get(i);
		
		if (newViewStyle == kViewIcon)
		{		
			obj.render_large('nexusObjects');
		}
		else
		{
			obj.render_list('nexusObjects');
		}
	}		
	
	if (gNexusObjectRegistry.count() == 0)
	{
		var container = YAHOO.util.Dom.get('nexusObjects');
		container.innerHTML = '<div class="nodata">There are no items to display</div>';
	}	
	
	YAHOO.Tools.setCookie(kCookieViewType,newViewStyle);
	
	updateBrowseViewTypeText(triggerId, kTriggerImage);	
}

/**
 * Asynchronously adds the given nexus objects (NexusObject) to the 
 * document bin (or briefcase).
 * @param {Array} nexusObjectArray The array of NexusObject instances.
 */
function addObjectsToDocumentBin(nexusObjectArray)
{
	docs = new Array();
	docs['shItemDocument'] = new Array;
	
	var i = 0;
	for (i; i < nexusObjectArray.length; i++)
	{
		var ob = nexusObjectArray[i];
		if (ob && ob.type == kNexusTypeDocument)
		{
			docs['shItemDocument'][docs['shItemDocument'].length] = ob.id;
		}
	}
	
	if (docs['shItemDocument'].length > 0)
	{
		xajax_shAjaxServer.addToDocumentBin(docs);
	}
}

/**
 * Asynchronously adds the given nexus objects (NexusObject) to the 
 * document bin (or briefcase).
 * @param {Array} nexusObjectArray The array of NexusObject instances.
 */
function addObjectsToTrash(nexusObjectArray)
{
	docs = new Array();
	
	var i = 0;
	for (i; i < nexusObjectArray.length; i++)
	{
		var ob = nexusObjectArray[i];
		docs[docs.length] = ob.getElementId();
	}
	
	if (docs.length > 0)
	{
		xajax_shAjaxServer.addItemsToTrash(docs);
	}
}


/**
 * This simply calls the given menu objects show method.  Additionally,
 * though, it will hide any menus that are currently displayed.
 * @param YAHOO.widget.Menu menuObject The menu object to show
 */
function showMenu (menuObject)
{
	YAHOO.widget.MenuManager.hideVisible();
	menuObject.show();
	
}
/**
 * Set general use nexus-specific data for use by
 * other areas of the page.
 * @param string property The name of the property
 * @param string value The value of the property
 */
function nexusSet (property, value)
{
	gNexusInfo[property] = value;
}

/**
 * Gets the list of selected nexus objects that are stored in 
 * the nexus object registry.
 * @return Returns an array of NexusObject instances.
 */
function getSelectedNexusObjects()
{
	var selectedObjects = new Array();
	
	for (i = 0; i < gNexusObjectRegistry.count(); i++)
	{
		var obj = gNexusObjectRegistry.get(i);
		if (obj && obj.selected)
		{
			selectedObjects[selectedObjects.length] = obj;
		}
	}	
	
	return selectedObjects;
}

/**
 * Get general use nexus-specific data set by
 * other areas of the page.
 * @param string property The name of the property
 * @return string The value of the property
 */
function nexusGet (property)
{
	return gNexusInfo[property];
}

/**
 * Determines if the given element represents 
 * the nexus briefcase object.
 * @param string id
 * @param bool Returns true if it's a briefcase
 */
function isBriefcaseElement(id)
{
	return (id == 'briefcase');			
}

/**
 * Determines if the given element represents 
 * the nexus trashcan object.
 * @param string id
 * @param bool Returns true if it's a trashcan
 */
function isTrashcanElement(id)
{
	return (id == 'trashcan');		
}

/**
 * Determines if the given element Id represents
 * an item.
 * @param string elementId
 * @return bool Returns true if the element is an item
 */
function isItemElement(id)
{
	var info = getElementIdInfo(elementId);
	return (info['type'] == kNexusTypeDocument);		
}

/**
 * Determines if the given element Id represents
 * a category.
 * @param string elementId
 * @return bool Returns true if the element is a category
 */
function isCategoryElement(elementId)
{
	var info = getElementIdInfo(elementId);
	return (info['type'] == kNexusTypeCategory);
}

/**
 * Converts an id into information about the nexus 
 * object contained within the element.
 * @param string elementId
 * @return array An array of information:
 * 					'type' = cat|item
 * 					'id' = number
 */
function getElementIdInfo(elementId)
{
	var info = new Array();
	
	var splitId = elementId.split ('_');
	
	info['type'] = splitId[0];
	info['id'] = splitId[1];
	 
	return info;	
}

/**
 * Returns the nexus object ID based on the id
 * string given.  The ID string has to match
 * the following format [type]_[id]
 * @param string elementId The ID of the DOM element
 * @return number The nexus object id or 0 if error
 */
function getNexusId(elementId)
{
	var id = -1;
	var splitId = elementId.split ('_',2);	
	if (splitId.length != 2)
	{
		return 0;
	}
	else
	{
		return splitId[1];		
	}	
}

/**
 * Invokes the rename dialog populating it
 * with the appropriate 'original name' text
 * and setting the dialog header correctly.  Note that 
 * this requires that a variable of type renameDialog has been
 * created that represents a YUI Dialog object (see forms/form.ajax.rename.tpl.html)
 * Also, this function creates two new member variables for renameDialog:
 * data1 = object type (e.g. kNexusTypeDocument)
 * data2 = object id
 * You can use those in your rename dialog submit handlers. 
 * @param {String} type The type of object to rename (e.g. kNexusTypeDocument)
 * @param {String} id The id of the object to rename
 */
function renameObject(type,id)
{
	var title = YAHOO.util.Dom.get(type+'_' + id + '_name');
	var field = YAHOO.util.Dom.get('rename_title_field');
	field.value = YAHOO.Tools.trim(title.innerHTML);		
	field.select();
	field.focus();
	
	if (type == kNexusTypeDocument)
	{
		renameDialog.setHeader('Rename Document');
	}
	else if (type == kNexusTypeCategory)
	{
		renameDialog.setHeader('Rename Category');
	}
	
	renameDialog.data1 = type;
	renameDialog.data2 = id;
	
	renameDialog.show();
}	
	
/** Check all the items in the given field list
 *	@param bool bCheckAll True to check all, false to uncheck all
 * 	@param string fieldList The id of the checkboxes that should be checked or unchecked.
 */
function checkAllItems (bCheckAll, fieldList)
{
	if (!fieldList.length)
	{
		fieldList.checked = bCheckAll;
	}
	else
	{		
		for (i=0; i < fieldList.length; i++)
		{
			fieldList[i].checked = bCheckAll;
		}
	}	
}

/**
 * This is used to select all options in a select element
 * @param {String} selObId The id of the select element
 */
function selectAllOptions (selObId)
{
	var obSelObId = YAHOO.util.Dom.get(selObId);
	if (obSelObId != null)
	{
		for (i=0;i<obSelObId.options.length;i++)
		{
			obSelObId.options[i].selected = true;
		}
	}	
}

/**
 * Used for standard delete checks on items.  Returns
 * false if cancel was pressed or redirects to given link on OK
 * @param {String} action The type of action being asked about:
 * @param {String} link The link to navigate to on 'yes'
 * @param {String} formId The Id of the form to submit on 'yes'
 * @param {String} onBeforeAccept This callback is called just before
 *                  navigating to a new page when the user accepts
 *                  (that is, they press 'yes').
 * 	- delete_multiple
 *  - delete_selected
 *  - delete
 *  - delete_permanent
 *  - delete_permanent_all
 * @param {String} link The link to redirect to if user chose 'yes' 
 */
function areYouSure (action,link,formId,onBeforeAccept)
{
	var message = '';
	switch (action)
	{
		case 'delete_multiple':
			message = 'Are you sure you want to delete ALL items permanently?';
			break;
		case 'delete_selected':
			message = 'Are you sure you want to delete the selected items permanently?';
			break;
		case 'delete':
			message = 'Are you sure you want to delete this item?';
			break;
		case 'delete_permanent':
			message = 'Are you sure you want to permanently delete the selected items?';
			break;
		case 'delete_permanent_all':
			message = 'Are you sure you want to permanently delete all items in the trash?';
			break;
	}
	
    var onYes = null;
    if (formId)
    {
	    onYes = function () 
        {
            if (onBeforeAccept)
            {
                onBeforeAccept();
            }
                        
            var form = YAHOO.util.Dom.get(formId);
            form.submit();            
        }
    }
    else
    {
        onYes = function () 
        {
            if (onBeforeAccept)
            {
                onBeforeAccept();
            }
            
            document.location = link
        }
    }

    
	askDialog('Confirm Action',message,onYes);	
}

function showWindow (href, name, width, height, bars, resizable)
{
	var settings = 
		'width='+width+',height='+height
		+',toolbar='+(bars?'1':'0')
		+',status=' + (bars?'1':'0')
		+',menubar=' + (bars?'1':'0')
		+',scrollbars=' + (bars?'1':'0')
		+',location=' + (bars?'1':'0')
		+',resizable=' + (resizable?'1':'0');
		
	ref = window.open (href, name, settings);
	return ref;
}

/**
 * Used by the nexus multiple selection control to selected options in
 * a standard select control to another select control 
 * @param {String} source The ID of the select object from which items are to be moved
 * @param {String} dest The ID of the select object to which items are to be moved.
 */
function moveSelectedOptions (source, dest)
{
	var obSource = YAHOO.util.Dom.get(source);
	var obDestination = YAHOO.util.Dom.get(dest);
	
	for (i=0;i<obSource.options.length;i++)
	{	
		if (obSource.options[i].selected)
		{
			// Add to destination
			var newOption = document.createElement ('option');
			newOption.text = obSource.options[i].text;
			newOption.value = obSource.options[i].value;
			newOption.id = obSource.options[i].id;
			
			// Find the right place in the destination for
			//	this item by comparing the IDs of the items.
			for (j=0;j < obDestination.options.length;j++)
			{
				if (obDestination.options[j].id > newOption.id)
				{
					break;
				}
			}
			
			if (obDestination.options.length > 0 && j >= 0)
			{
				try 
				{
					// Standards-compliant
					obDestination.add (newOption,obDestination.options[j]);						
				}
				catch (e)
				{
					// IE-specific
					obDestination.add (newOption,j);
				}
			}
			else
			{
				try
				{
					// Standards-compliant
					obDestination.add (newOption,null);					
				}
				catch(e)
				{
					// IE-specific
					obDestination.add (newOption);
				}
			}
		}
	}
	
	for (i=obSource.options.length-1;i>=0;i--)
	{
		if (obSource.options[i].selected)
		{
			obSource.remove (i);
		}
	}
}

/**
 * Does a simple toggle of the visibility of an item using a fade effect.
 * @param {String} div The id string of the div to toggle.
 */
function toggle_div(div)
{
	if (YAHOO.util.Dom.getStyle(div,'display') != 'none')
	{
		new YAHOO.widget.Effects.Fade(div, {seconds:.5});
	}
	else
	{
		new YAHOO.widget.Effects.Appear(div, {seconds:.5})
	}
}	

function encode64(input) 
{
   var output = "";
   var chr1, chr2, chr3;
   var enc1, enc2, enc3, enc4;
   var i = 0;

   do {
      chr1 = input.charCodeAt(i++);
      chr2 = input.charCodeAt(i++);
      chr3 = input.charCodeAt(i++);

      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;

      if (isNaN(chr2)) {
         enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
         enc4 = 64;
      }

      output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + 
         keyStr.charAt(enc3) + keyStr.charAt(enc4);
   } while (i < input.length);
   
   return output;
}

function onFileBoxItemUnshared (documentId,username)
{    
    var idString = 'pool_share_' + username;
    var parent = $(gCurrentContext.context);
    parent.removeChild($(idString));
    
    var children = YAHOO.util.Dom.getChildren(parent);
    if (children.length == 0)
    {
        dh.append(parent,
                    {
                        tag: 'span', 
                        id: 'noshare',
                        html: 'Not being shared'
                    });    
    }
}

function onFileBoxItemShared (documentId,username)
{    
    var idString = 'pool_share_' + username;
    var htmlString = username + '&nbsp;[<a href="javascript:void(0);" onclick="unshareFileboxItemFromUser(\''+username+'\','+documentId+',\'sharedUsers\')">x</a>]';
        
    // Add the new share
    parent = $(gCurrentContext.context);
    dh.append(parent,
                {
                    tag: 'span', 
                    id: idString,
                    html: htmlString
                });
      
    // Remove the 'Not being shared' text
    var noshareNode = $('noshare');
    if (noshareNode)
    {
        parent.removeChild(noshareNode);
    }
}

function onUserListRetrievedForFileBoxShare(users)
{
    //The second argument passed to the
    //constructor is a configuration object:
    userPanel = new YAHOO.widget.Panel("win", {
        width:"200px", 
        fixedcenter: true, 
        constraintoviewport: true, 
        underlay:"shadow", 
        close:true, 
        visible:true, 
        modal:true,
        draggable:true} );
        
    var html = '';
    userArray = eval('(' + users + ')');      
    
    for(i=0; i < userArray.length; i++)
    {
        html += '<a href="javascript:void(0);" onclick="xajax_shAjaxServer.shareFileBoxDocument('+gCurrentContext.document+',\''+userArray[i]+'\');userPanel.hide();">' + userArray[i] + '</a><br/>';
    }
    
    userPanel.setHeader("Select A User to Share With");
    userPanel.setBody(html);

    userPanel.render(document.body);
    userPanel.show();    
}
                                                            
function shareFileboxItemWithUser (documentId, contextIdentifier)
{
    gCurrentContext = {document:documentId,context:contextIdentifier};   
    xajax_shAjaxServer.getUserList('onUserListRetrievedForFileBoxShare');
}

function unshareFileboxItemFromUser(username,documentId,contextIdentifier)
{
    gCurrentContext = {document:documentId,context:contextIdentifier};   
    xajax_shAjaxServer.unshareFileBoxDocument(username,documentId);
}
