// Copyright 2000-2006 Adobe Macromedia Software LLC and its licensors. All rights reserved.

var DEBUG_FILE = dw.getConfigurationPath() + '/SHORTCUT_DEBUG.txt';

//*************** GLOBALS *****************

var helpDoc = MM.HELP_cmdKeyboardShortcuts;
var ultraDevMenuStr = "ultradev";
var PLATFORM = navigator.platform;
var OPP_PLATFORM = (PLATFORM == "Win32") ? "mac" : "win";  // Opposite platform
var CTRL_STR = (PLATFORM == "Win32") ? "Ctrl" : "Cmd";
var NEWLINE = (PLATFORM != "Win32") ? "\x0D" : "\x0D\x0A";
var FILE_CONFIG_PATH = dw.getConfigurationPath();
var FILE_MENUXML_PATH   = null;
var FILE_CUSTOM_SET = FILE_CONFIG_PATH + "/Menus/Custom Sets";
var FILE_ACTIVE_SET = FILE_CUSTOM_SET + "/active set.txt";
var ARRAY_COMMANDS_TREE = new Array();
var ARRAY_COMMANDS_TREENODES = new Array();
var ARRAY_CUSTOM_SETS;
var ACTIVE_SHORTCUT_LIST = new ShortcutList();   // ShortcutList() class defined in Shortcut.js
var CURRENT_SHORTCUT_LIST = new ShortcutList();
var MENU_DOM = null;
var TREE_CONTROL_WIDTH = 'style="width:345px"';
var TREE_COLUMN_ITEM_WIDTH = 'width="158"';
var TREE_COLUMN_ITEM_WIDTH_MAC = 'width="220"'
var TREE_COLUMN_KEY_WIDTH = 'width="140"';
var SEPARATOR_STR = "-----------------------------------------------";
var ACTIVE_SET_STR;
var YIELD_PATH = "../Shared/MM/Images/yield.png";
var STOP_PATH = "../Shared/MM/Images/stop.png";
var ALT_STR = (PLATFORM == "Win32") ? "Alt" : "Opt";
var CONFLICT_ID="";
var CAN_APPLY=true;
var LEFT_LAYER = 'left:235px;';
var RIGHT_LAYER = 'left:321px;';
var TOP_LAYER = 'top:402px;';
var LAST_VALID_COMMAND_MI = "";  //last valid command menu item
var MODIFIER_KEYS = new Array("Ctrl","Cmd","Alt","Opt","Shift");
var IBTN_duplicateBtn, IBTN_renameBtn, IBTN_saveAsTextBtn, IBTN_deleteBtn,IBTN_addBtn;
var KEYBOARD_LAYOUT = "";

//******************* API **********************

function commandButtons()
{
	return new Array("PutButtonsOnBottom", "OkButton defaultButton", MM.BTN_OK, "cmdOK()",
					 "PutButtonOnLeft", MM.BTN_Help, "displayHelp()",
					 "CancelButton", MM.BTN_Cancel, "cmdCancel()" );
}

function loadGlobals()
{
	if (FILE_MENUXML_PATH != null && MENU_DOM != null)
		return;

	FILE_MENUXML_PATH = dw.getMenuFile();
	MENU_DOM = dw.getDocumentDOM(FILE_MENUXML_PATH);
}

function cmdOK()
{
	checkLockedFiles();
	
	if (document.newShortcutEntry.value && !isSet(MENU_CURRENT_SET.getValue(), "factory"))
		updateUI("applyButton");
	
	var activeSet = CURRENT_SHORTCUT_LIST.shortcutListName;
	
	if (!isSet(MENU_CURRENT_SET.getValue(), "factory"))
		CURRENT_SHORTCUT_LIST.writeToShortcutXML(FILE_CUSTOM_SET+"/"+ MENU_CURRENT_SET.getValue(), CURRENT_SHORTCUT_LIST.shortcutListName);
	

	dreamweaver.runCommand("Processing.htm",CURRENT_SHORTCUT_LIST,FILE_ACTIVE_SET,activeSet,document);
    dw.handleKShortCuts();
	window.close();
	
	// This doesn't do anything because we're deffering the reloading
	// of menus.xml. Instead, we need to reload the snippet list
	// when we finally do reload menus.xml (see JSInterp::DoDeferredReloadExtensions()).
	//if (SNIPPETS_MODIFIED)
	//	dw.snippetPalette.reloadSnippetList();
}

function editMenuXML(shortcutList, activeSetPath, activeSet)
{
	writeToMenusXML(shortcutList);
	DWfile.write(activeSetPath, activeSet);
	dreamweaver.reloadMenus();
}

function cmdCancel()
{
    dw.handleKShortCuts();
	window.close();
}

function cmdSaveAsText()
{
	var browseURL = dreamweaver.browseForFileURL("save",LABEL_SaveAsHTML);
	
	if (browseURL)
	{
		if(browseURL.lastIndexOf(".htm")== -1)
			browseURL +=".htm";
		DWfile.write(browseURL, createHTMLContents());
	}
}

//***************** LOCAL FUNCTIONS  ******************

function initializeUI()
{
	var  i, commandsArray, menuLabel;

	if(checkLockedFiles())
	{
		window.close();
		return;
	}

	KEYBOARD_LAYOUT = dw.getCurrentKeyboardLayout();
	
	// Global UI Controls
	MENU_CURRENT_SET = new ListControl("selectCurrentSet");
	MENU_COMMANDS = new ListControl("commandsList");
	LIST_SHORTCUTS = new ListControl("itemList");
	TREE_CONTROL = findObject("theTreeControl");
	IBTN_duplicateBtn = new ImageButton("duplicateBtn","IBTN_duplicateBtn","sS",false);
	IBTN_renameBtn = new ImageButton("renameBtn","IBTN_renameBtn","sS",false);
	IBTN_saveAsTextBtn = new ImageButton("saveAsTextBtn","IBTN_saveAsTextBtn","sS",false);
	IBTN_deleteBtn = new ImageButton("deleteBtn","IBTN_deleteBtn","sS",false);
	IBTN_addBtn = new ImageButton("addBtn","IBTN_addBtn","sS",false);
	IBTN_minusBtn = new ImageButton("minusBtn","IBTN_minusBtn","sS",false);

	setCurrentSetMenu();

	// select the active set
	MENU_CURRENT_SET.setIndex(getIndexOfItem(MENU_CURRENT_SET.get('all'),ACTIVE_SET_STR));
	
	LAST_VALID_COMMAND_MI = MENU_CURRENT_SET.getValue();

	if (PLATFORM == "Win32")
	{
		commandsArray = new Array(LABEL_MainMenu, LABEL_SiteMenu, LABEL_SitePanel, SEPARATOR_STR, LABEL_HTMLWindow, LABEL_MainWindow, LABEL_SiteWindow);
	}
	else
	{
		commandsArray = new Array(LABEL_MainMenu,SEPARATOR_STR, LABEL_HTMLWindow, LABEL_MainWindow);
	}

	MENU_COMMANDS.setAll(commandsArray,commandsArray);

	// If this dialog was invoked throgh 'snippet' select snippets command by default
	var commandindex = 0;

	MENU_COMMANDS.setIndex(commandindex);



	// create treenode array
	for (i = 0; i < MENU_COMMANDS.getLen(); i++)
	{
		menuLabel = MENU_COMMANDS.get(i);
	
		if (menuLabel == LABEL_MainMenu)
			ARRAY_COMMANDS_TREENODES.push(readFromMenuXML("menubar", "DWMainWindow", ""));
		else if (menuLabel == LABEL_SiteMenu)
			ARRAY_COMMANDS_TREENODES.push(readFromMenuXML("menu", "SitePanelOptionMenu", ""));
		else if (menuLabel == LABEL_SitePanel)
			ARRAY_COMMANDS_TREENODES.push(readFromMenuXML("menubar", "DWSitePseudoMenu", ""));
		else if (menuLabel == LABEL_HTMLWindow)
			ARRAY_COMMANDS_TREENODES.push(readFromMenuXML("shortcutlist", "DWHTMLContext", "Snippets"));
		else if (menuLabel == LABEL_MainWindow)
			ARRAY_COMMANDS_TREENODES.push(readFromMenuXML("shortcutlist", "DWMainWindow", ""));
		else if (menuLabel == LABEL_SiteWindow)
			ARRAY_COMMANDS_TREENODES.push(readFromMenuXML("shortcutlist", "DWMainSite", ""));
		else
			ARRAY_COMMANDS_TREENODES.push("-");
	}

	generateTreeArray();
	setCommands();

	// Compare active and current set
	CURRENT_SHORTCUT_LIST.shortcutListName = ACTIVE_SET_STR;
	setShortcutList();
	MENU_CURRENT_SET.focus();
}

function checkKeyboardLayoutChange()
{
	var currentLayout = dw.getCurrentKeyboardLayout();
	
	if (KEYBOARD_LAYOUT != "" && KEYBOARD_LAYOUT != currentLayout)
	{
		KEYBOARD_LAYOUT = currentLayout;
		setTimeout("alert(MSG_Relaunch)",500);
	}
}

// getCustomSetList
// gets the list of custom sets. in DW4, this function returned a single array of
// filenames. it now returns an array containing two items: an array of set names,
// and an array of set filenames. this is so the set names can be localized independent
// of the filenames.
function getCustomSetList(setType)
{
  var fileObj = new File(FILE_CUSTOM_SET);
  var fileArray = new Array();
  var setNames = new Array();
  var filterFunction;
  var setDOM, setName;
  if (setType == "factory")
    filterFunction =  new Function("x", "return (x.isFile()) && ((x.getAttributes() == 'R') || (x.getContents().indexOf('factory') != -1)) && (x.getExtension()== 'xml');");
  else
    filterFunction =  new Function("x", "return (x.isFile()) && ((x.getAttributes() != 'R') && (x.getContents().indexOf('factory') == -1)) && (x.getExtension()== 'xml');");
  fileArray = fileObj.listFolder(filterFunction);
  
  for (var i=0; i < fileArray.length; i++){
    setDOM = dw.getDocumentDOM(FILE_CUSTOM_SET + "/" + fileArray[i]);
    setName = setDOM.getElementsByTagName('SHORTCUTSET')[0].getAttribute('name');
    setNames.push(setName);
  }
  return new Array(setNames,fileArray);
}


// function reads in menus.xml and creates the treecontrol
function readFromMenuXML(tagName,id, ignoreId)
{
	loadGlobals();

	var menuFile = new File(FILE_MENUXML_PATH);

	if (!menuFile.exists)
	{
		menuFile.setPath(FILE_CONFIG_PATH + '/Menus/menus.bak');
		menuFile.copyTo(FILE_MENUXML_PATH);
	}

	// Call into the C++ layer to read the menus.xml file into our desired html 
	// This call traverses the menus in the menubar node and creates treenodes
	// Returns an object with nodes, and parallel arrays of nodenames and keys
	// Since snippets are now included in the shortcut list, and should be 
	// displayed under it's own category, ignore all snippet tags found under
	// the shortcutlist.

	var treeData = dw.getMenuTree(FILE_MENUXML_PATH, tagName, id, ignoreId);

	// It's possible in theory, although highly unlikely, to get NULL back from getMenuTree(),
	// so fail gracefully and return an empty list, and bypass adding stuff to the shortcut list

	if (treeData == null)
		return (new Array());

	var nodes = treeData.nodes;

	// Use the nodename and keys stuff from the C++ call to populate our shortcutlists too

	addShortcutsFromTree(treeData);

	return nodes;
}

// function returns the NodeList for the specified tag (it assumes that menus.xml exists).
// Returns null if the tag does not exists.
function getMenuTagByID(menubarList,id)
{
  var   i;
  var found = false;
  for(i=0;i<menubarList.length; i++)
  {
    if  ((menubarList[i].nodeType==Node.ELEMENT_NODE) && (menubarList[i].getAttribute("id") == id))
    {
      found = true;
      break;
    }
  }
  return (found)?menubarList[i]:null;
}

// changes the treecontrol when user has selected a different Commands set
function setCommands()
{
	findObject("theTreeControl").innerHTML = ARRAY_COMMANDS_TREE[MENU_COMMANDS.getIndex()];
}

// changes the itemList to show the shortcuts for the select tree node
function setShortcutList()
{
  var keyStr="", index, theValue, theSelectedNode;
  theSelectedNode = TREE_CONTROL.selectedNodes[0];
  if (theSelectedNode)
  {
    theValue = theSelectedNode.value;
    index = theValue.lastIndexOf("|");
    if (index != -1)
      keyStr = theValue.substring(index+1);
  }
  if (keyStr && keyStr.indexOf("+,") != -1)
  {
    var tempObj = new Object();
    keyStr = keyStr.replace(/\+,/, "+Comma"); 
    tempObj.keysArray = keyStr.split(",");
    for (i=0;i<tempObj.keysArray.length;i++)
      if (tempObj.keysArray[i].indexOf("+Comma") != -1)
        tempObj.keysArray[i] = tempObj.keysArray[i].replace(/\+Comma/, "+,");
    LIST_SHORTCUTS.setAll(tempObj.keysArray);
  }
  else if (keyStr)
    LIST_SHORTCUTS.setAll(keyStr.split(","));
  else
    LIST_SHORTCUTS.setAll(new Array());
  LIST_SHORTCUTS.setIndex(0);
}

// updates the key column of the selected treenode
function setShortcutInTree(selectedNode,oldKey,newKey, conflictID)
{
  var  index, treeNodeValue,numUpdates,keyStr;
//  keyStr = LIST_SHORTCUTS.list.toString();
  if (selectedNode)
  {
    numUpdates=CURRENT_SHORTCUT_LIST.update(selectedNode.name, dw.convertKeyStr(newKey,"store"),dw.convertKeyStr(oldKey,"store"));
    keyStr = dw.convertKeyStr(CURRENT_SHORTCUT_LIST.getKeyByID(selectedNode.name),"display")
    treeNodeValue = selectedNode.value;
    if (treeNodeValue) {
        if (treeNodeValue.search(/\|/)!=-1){
          treeNodeValue = treeNodeValue.replace(/\|.*/,"|"+keyStr);
        }else
          treeNodeValue += "|"+keyStr;
        selectedNode.setAttribute("value",treeNodeValue);
    }
  }
  else
  {
    numUpdates=1+CURRENT_SHORTCUT_LIST.update(conflictID, dw.convertKeyStr(newKey,"store"),dw.convertKeyStr(oldKey,"store"));
  }

  if (numUpdates > 1)
  {
    ARRAY_COMMANDS_TREENODES = updateTreeNodeArray(ARRAY_COMMANDS_TREENODES);
  generateTreeArray();
//  setCommands();
  dw.forceGarbageCollection();
  }
  else
    ARRAY_COMMANDS_TREE[MENU_COMMANDS.getIndex()] = TREE_CONTROL.innerHTML;
//  document.newShortcutEntry.setAttribute("value", "");
  // *** it would be nice to set A_C_T before user changes commands set instead

}

function writeToMenusXML(theShortcutList)
{
	loadGlobals();

	var i, keyStr, keyArray=new Array(), theId, menuBarNode, menuNode, altId, tempNode, shortcutNode;
	var menuitemList, shortcutItemList, shortcutTagList, menuFile;

	menuitemList = MENU_DOM.getElementsByTagName("menuItem");
	shortcutItemList = MENU_DOM.getElementsByTagName("shortcut");
	shortcutTagList = MENU_DOM.getElementsByTagName("shortcutlist");
	

	for (i = 0; i < theShortcutList.idKeyPairList.length; i++ )
	{
		keyArray = theShortcutList.idKeyPairList[i].keysArray;
		theId = theShortcutList.idKeyPairList[i].id;

		

		if (theId && theShortcutList.changeList[theId])
		{
			
				if (theId.indexOf("DWShortcut") == -1)
				{
					menuNode = getMenuTagByID(menuitemList, theId);
	
					if (!menuNode) 
						menuNode = getMenuTagByID(shortcutItemList, theId);
				}
				else
				{
					menuNode = getMenuTagByID(shortcutItemList, theId);
	
					if (!menuNode) 
						menuNode = getMenuTagByID(menuitemList, theId);
				}
	
				if (menuNode != null && menuNode.getAttribute("key")!= keyArray[0])
				{
					if (keyArray[0])
						menuNode.setAttribute("key", keyArray[0]);
					else
						menuNode.setAttribute("key", "");
				}
			
	
			//set Alternate key			
				shortcutTagID = getTagIdFromItemId(theId, menuNode);
	
				if (shortcutTagID == "DWMainWindow1")
				{
					rightId = theId.replace(/DWMenu_/,"");
					altId = "DWShortcuts_" + rightId;
					shortcutTagID = shortcutTagID.substr(0,shortcutTagID.length-1);
				}
				else if (shortcutTagID == "DWMainSite1")
				{
					rightId = theId.replace(/DWMenu_MainSite/,"");
					altId = "DWShortcuts_MainSite" + rightId;
					shortcutTagID = shortcutTagID.substr(0,shortcutTagID.length-1);
				}
				else
				{
					altId = theId + "2";
				}
	
				if (keyArray.length > 1 && menuNode)
				{
					if (getMenuTagByID(shortcutItemList, altId) == null)   // check to see if alt already exists
					{
						tempNode = getMenuTagByID(shortcutTagList, shortcutTagID)
						
						if (tempNode)
							tempNode.innerHTML += createAltShortcutTag(menuNode, altId, dw.convertKeyStr(keyArray[1],"store"));
					}
					else
					{
						menuNode = getMenuTagByID(shortcutItemList, altId);
						
						if (menuNode)
							menuNode.setAttribute("key", keyArray[1]);
						
						if (menuNode.getAttribute("platform") == OPP_PLATFORM)
							menuNode.setAttribute("platform", "");
					}
				}
				else if ((menuNode = getMenuTagByID(shortcutItemList, altId)) != null)
				{
					if (menuNode.getAttribute("platform") != OPP_PLATFORM)
						menuNode.setAttribute("key", "");
				}
				
		}
	}
	
	menuFile = new File(FILE_MENUXML_PATH);
	menuFile.setContents(MENU_DOM.body.outerHTML, false, "utf-8/bom");
}

function createAltShortcutTag(origNode, newId, newKey)
{
  var retVal = new Array(), value;
  var attrArray  = new Array("file","command","domRequired","arguments","enabled","name")
  retVal.push(NEWLINE + "    <shortcut key=" + '"' + newKey + '"');
  for (var i=0; i<attrArray.length; i++)
  {
    if ((value = origNode.getAttribute(attrArray[i])))
      retVal.push("   "+attrArray[i]+"=" + '"' + value + '"');
  }
  retVal.push("   id=" + '"' + newId + '" />'+NEWLINE);
  return retVal.join("");
}


// Given an items it, returns the id of the menubar id
function getTagIdFromItemId(itemId, menuNode)
{
	var retVal = "";
	var parent;
	var parentId;

	if (menuNode)
	{
		parent = menuNode.parentNode;
		
		if (parent.tagName == "SHORTCUTLIST")
		{
			retVal = parent.getAttribute("id");
		}
		else
		{
			while (parent && !parentId)
			{
				if (parent.tagName == "MENUBAR")
				{
					parentId = parent.getAttribute("id");
				}
				else
				{
					parent = parent.parentNode;
				}
			}
		}
	
		if (parentId)
		{
			if (parentId =="DWMainSite")
				retVal = "DWMainSite1"
			else if (parentId =="DWMainWindow")
				retVal = "DWMainWindow1"
		}
	}

	return retVal;
}

function getAltKeyId(id)
{
 var retVal="";
 if (!id )
   return retVal;
 else if (id.indexOf("DWMenu_")!=-1)
   retVal = id.replace(/DWMenu_/,"DWShortcuts_");
 else if (id)
   retVal = id+"2";
 return retVal;
}

function isShortcutToExclude(id)
{
  var retVal=true,i, tempId;
  var idPrefixArray = new Array("DWShortcuts_Main_","DWShortcuts_Site_","DWShortcuts_HTMLSource_");
  if (id && id.indexOf("DWShortcuts")!=-1)
  {
  var tempId = (id.charAt(id.length-1)=="2") ? id.substring(0,id.length-1): "";
  if (tempId && CURRENT_SHORTCUT_LIST.getIndexByID(tempId) != -1)
    retVal = true;
  else
  {
      for (i=0;i<idPrefixArray.length;i++)
      {
        if (id && id.indexOf(idPrefixArray[i]) != -1)
        {
          retVal = false;
          break;
        }
      }
    }
  }
  else retVal=false;
  return retVal;
}

function getIndexOfItem(theArray,theItem)
{
  var index,found=false;
  for (index=0;index<theArray.length;index++)
  {
    if (theArray[index] == theItem)
    {
      found=true;
      break;
    }
  }
  return (found)? index:-1;
}

function updateUI(itemName)
{
  checkKeyboardLayoutChange();
  var newSetFile, newSetName, retVal, tempStr,errorMsg,selectedTreeNode,keyStr,oldKey,numUpdate,otherNode;
  var tempShortcutList;
  switch(itemName)
  {
    case "selectCurrentSet":
  {
    if (MENU_CURRENT_SET.get() == SEPARATOR_STR)
    {
        MENU_CURRENT_SET.pickValue(LAST_VALID_COMMAND_MI);
    }
    else
    {
      // If the last thing we were on is not a factory default and
      // it has been modified, ask the user if they want to save it.
      if (isSet(LAST_VALID_COMMAND_MI, "factory") == false &&
          (CURRENT_SHORTCUT_LIST.changeListLength() > 0 )&& 
          confirm(MSG_SaveShortcutSet))
      {
          var newSet = CURRENT_SHORTCUT_LIST.shortcutListName;
          var curSet = newSet;
          if (curSet != LAST_VALID_COMMAND_MI)
            curSet = LAST_VALID_COMMAND_MI.replace(/\.xml/, "");
          CURRENT_SHORTCUT_LIST.writeToShortcutXML(FILE_CUSTOM_SET + "/" + LAST_VALID_COMMAND_MI, curSet);
          if (newSet != curSet)
            CURRENT_SHORTCUT_LIST.shortcutListName = newSet;
      }
      
      MM.setBusyCursor();
      newSetFile = MENU_CURRENT_SET.getValue();
      if (getExtension(newSetFile) !="xml")
        newSetFile+=".xml"
      tempShortcutList = new ShortcutList();
      tempShortcutList.readFromShortcutXML(FILE_CUSTOM_SET+"/" + newSetFile);
      CURRENT_SHORTCUT_LIST.compareUpdate(tempShortcutList);
      ARRAY_COMMANDS_TREENODES = updateTreeNodeArray(ARRAY_COMMANDS_TREENODES);
      generateTreeArray();
      setCommands();
      dw.forceGarbageCollection();
      MM.clearBusyCursor();
    }
    LIST_SHORTCUTS.setAll("");
    clearField("newShortcutEntry");
    LAST_VALID_COMMAND_MI = MENU_CURRENT_SET.getValue();
    MENU_CURRENT_SET.focus()
    break;
  }
  case "duplicateBtn":
    {
    newSetName = callCommand("duplicate set",new Array(MENU_CURRENT_SET.getValue(),CURRENT_SHORTCUT_LIST));
    if (newSetName)
    {
      CURRENT_SHORTCUT_LIST.shortcutListName = newSetName;
      DWfile.write(FILE_ACTIVE_SET,newSetName);
      setCurrentSetMenu();
      MENU_CURRENT_SET.setIndex(getIndexOfItem(MENU_CURRENT_SET.get('all'),newSetName));
      updateUI("selectCurrentSet");
    }
    break;
    }
  case "renameBtn":
  {
    if (!isSet(MENU_CURRENT_SET.getValue(), "factory"))
    {
      newSetName = callCommand("rename set",MENU_CURRENT_SET.getValue());
      if (newSetName)
      {
        CURRENT_SHORTCUT_LIST.shortcutListName = newSetName;
        DWfile.write(FILE_ACTIVE_SET,newSetName);
        setCurrentSetMenu();
        MENU_CURRENT_SET.setIndex(getIndexOfItem(MENU_CURRENT_SET.get('all'),newSetName));
      }
    }
    else
      alert(MSG_CannotRenameFactorySet);
    break;
  }
  case "deleteBtn":
  {
    tempStr = CURRENT_SHORTCUT_LIST.shortcutListName;
    tempStr = tempStr.replace(/.xml/,"");
    retVal = callCommand("delete set",tempStr);
    if (retVal)
    {
      setCurrentSetMenu();
      var activeSetIndex = getIndexOfItem(MENU_CURRENT_SET.get('all'),ACTIVE_SET_STR);
      if (activeSetIndex == -1)
      {
        activeSetIndex = getIndexOfItem(MENU_CURRENT_SET.get('all'),tempStr);
        DWfile.write(FILE_ACTIVE_SET,tempStr);
      }
      MENU_CURRENT_SET.setIndex(activeSetIndex);
    }
    break;
  }
  case "commandsList":
  { // update the treecontrol
    if (MENU_COMMANDS.get() ==SEPARATOR_STR)
    {
      MENU_COMMANDS.setIndex(MENU_COMMANDS.getIndex()-1);
      updateUI("commandsList");
    }
    else
      setCommands();
    document.newShortcutEntry.setAttribute("value", "")
    updateUI("newShortcutEntry");
    LIST_SHORTCUTS.setAll("");
    break;
  }
  case "theTreeControl":
  {
    ARRAY_COMMANDS_TREE[MENU_COMMANDS.getIndex()] = TREE_CONTROL.innerHTML;
    setShortcutList();
    clearField("newShortcutEntry");
    break;
  }
  case "addBtn":
  { // node.childNodes.length
    if (!isSet(MENU_CURRENT_SET.getValue(), "factory"))
    {
        selectedTreeNode = TREE_CONTROL.selectedNodes[0];
      if (selectedTreeNode && selectedTreeNode.childNodes.length == 0 )
      {
        if ((LIST_SHORTCUTS.getLen()==0 || LIST_SHORTCUTS.get() !="" ) && LIST_SHORTCUTS.getLen() < 2)
        {
          LIST_SHORTCUTS.append();
          document.newShortcutEntry.focus();
          document.newShortcutEntry.select();
        }
      }
    }
    else
    {
      if (confirm (MSG_FactorySetCannotBeModified))
        updateUI("duplicateBtn");
    }
    break;
  }
  case "minusBtn":
  {
    if (TREE_CONTROL.selectedNodes[0])
    {
      if (!isSet(MENU_CURRENT_SET.getValue(), "factory"))
      {
        if (LIST_SHORTCUTS.getLen!=0)
        {
          selectedTreeNode = TREE_CONTROL.selectedNodes[0];
          oldKey = LIST_SHORTCUTS.get();
          
          if (oldKey)
            setShortcutInTree(selectedTreeNode,oldKey,"");
          
          LIST_SHORTCUTS.del();
          
        }
      }
      else
      {
        if (confirm (MSG_FactorySetCannotBeModified))
          updateUI("duplicateBtn");
      }
    }
    break;
  }
  case "newShortcutEntry":
  {
    if (!document.newShortcutEntry.value || !isSet(MENU_CURRENT_SET.getValue(), "factory"))
    {
      var shortcut = dw.convertKeyStr(document.newShortcutEntry.value,"store");
      errorMsg = checkKeyForProblem(document.newShortcutEntry.value);
      if(errorMsg)
      {
        findObject("warningMessage").innerHTML = errorMsg;
      }
      else 
      {
        errorMsg = checkKeyForConflict(shortcut);
        if(errorMsg)
        {
          findObject("warningMessage").innerHTML = errorMsg;
        }
        else
        {
          var key = shortcut.charAt(shortcut.lastIndexOf("+")+1);
          if (key.charCodeAt(0) > 127)
          {
            errorMsg = createWarningMsg(MSG_ShortcutWontWorkOnOtherKeyboards, "");
	        if(errorMsg)
            {
              findObject("warningMessage").innerHTML = errorMsg;
            }
          }
          else if(findObject("warningMessage").innerHTML != "")
          {
            findObject("warningMessage").innerHTML = "";
          }
        }
      }
    }
    else
    {
      if (confirm (MSG_FactorySetCannotBeModified))
        updateUI("duplicateBtn");
    }
    break;
  }
  case "applyButton":
  {
    if (CAN_APPLY)
    {
      if (!isSet(MENU_CURRENT_SET.getValue(), "factory"))
      {
        selectedTreeNode = TREE_CONTROL.selectedNodes[0];
        if (!selectedTreeNode || selectedTreeNode.childNodes.length != 0 )
          break;
        if (CONFLICT_ID && !confirm(errMsg(MSG_ReassignShortcut,getNameFromTreeArray(CONFLICT_ID),getNameFromTreeArray(document.theTreeControl.selectedNodes[0].name))))
          break;
        else
        {
          if (CONFLICT_ID)
          {
            otherNode = document.theTreeControl[CONFLICT_ID];
            if (otherNode)
              setShortcutInTree(otherNode,document.newShortcutEntry.value,"")
            else
              setShortcutInTree(null,document.newShortcutEntry.value,"",CONFLICT_ID);
          }
          if (LIST_SHORTCUTS.getLen() == 0)
            LIST_SHORTCUTS.add("");
          oldKey = LIST_SHORTCUTS.get();
          LIST_SHORTCUTS.set(document.newShortcutEntry.value);
          setShortcutInTree(selectedTreeNode,oldKey,document.newShortcutEntry.value);
        }
      }
      else
      {
        if (confirm (MSG_FactorySetCannotBeModified))
          updateUI("duplicateBtn");
      }
      document.newShortcutEntry.setAttribute("value", "")
      updateUI("newShortcutEntry");
      
    }
    dw.forceGarbageCollection();
    break;
  }
  }
}

function generateTreeControlHtml(treeNodesArray)
{
  var retVal = new Array();
  var treeControlTag = 'MM:TREECONTROL';
  var treeColumnTag = 'MM:TREECOLUMN';
  var treeColWidth = (PLATFORM=="Win32") ? TREE_COLUMN_ITEM_WIDTH : TREE_COLUMN_ITEM_WIDTH_MAC;
  retVal.push( "  <" + treeColumnTag + ' name="menuitems" ' + TREE_COLUMN_ITEM_WIDTH + '>' + NEWLINE);
  retVal.push("  <" + treeColumnTag + ' name="shortcutKeys" ' + TREE_COLUMN_KEY_WIDTH + '>' + NEWLINE);
  if (treeNodesArray)
	 retVal.push(treeNodesArray.join(""));
  return retVal.join("");
}

function generateTreeArray()
{
  var i=0;
  if (ARRAY_COMMANDS_TREE.length==0)
    ARRAY_COMMANDS_TREE.length = ARRAY_COMMANDS_TREENODES.length;
  for (i=0;i<ARRAY_COMMANDS_TREENODES.length;i++)
  {
    if (ARRAY_COMMANDS_TREENODES[i] !="-")
      ARRAY_COMMANDS_TREE[i]=generateTreeControlHtml(ARRAY_COMMANDS_TREENODES[i]);
    else
      ARRAY_COMMANDS_TREE[i] = "-";
  }
}

function updateTreeNodeArray(arrayOfTreeNodeArrays)
{
  var i, x, theNodeStr;
  for (i=0; i < arrayOfTreeNodeArrays.length; i++)
  {
    for (x=0; x <  arrayOfTreeNodeArrays[i].length; x++)
    {
      theNodeStr = updateTreeNode(arrayOfTreeNodeArrays[i][x]);
      if (theNodeStr != arrayOfTreeNodeArrays[i][x]);
        arrayOfTreeNodeArrays[i][x] = theNodeStr;
    }
  }
  return arrayOfTreeNodeArrays;
}

function updateTreeNode(treeNodeStr)
{
  var startIndex=0, keyStr, newStr, endIndex=0;
  var prefixes = new Array();
 
  // myoneyama: Oct-29-04 for #143392
  // We need to search for these prefixes to update.  Note that the logic
  // below assumes that these all start with 'name="'.
  prefixes.push('name="DW'); 

  
  for (var i = 0; i < prefixes.length; i++)
  {
    startIndex = treeNodeStr.indexOf(prefixes[i]);
    if (startIndex != -1)
      break;
  }
     
  if (startIndex != -1)
  {
	// skip past the 'name="' (six chars)
    startIndex += 6;
    endIndex = treeNodeStr.indexOf('"',startIndex);
    theId = treeNodeStr.substr(startIndex, endIndex-startIndex);

    // get keyStr for the given id
    keyStr = dw.convertKeyStr(CURRENT_SHORTCUT_LIST.getKeyByID(theId), "display");
    if(treeNodeStr.indexOf("|"+keyStr+'"') == -1 ||!keyStr && treeNodeStr.indexOf("|")!=-1)
    {
      startIndex = treeNodeStr.indexOf("|");
      if (startIndex == -1)
      {
        startIndex = treeNodeStr.indexOf('value="') + 7;
        startIndex = treeNodeStr.indexOf('"',startIndex);
      }
        endIndex = treeNodeStr.indexOf('"', startIndex);
      newStr = treeNodeStr.substr(0, startIndex);
      if (keyStr) newStr += "|";
      newStr += keyStr + treeNodeStr.substr(endIndex);  
      treeNodeStr = newStr;
    }
  }
  
  return treeNodeStr;
}

function setCurrentSetMenu()
{
  var factorySets = getCustomSetList("factory");
  var customSets = getCustomSetList("custom");
  if (customSets[0].length !=0){
    factorySets[0].push(SEPARATOR_STR);
    factorySets[1].push(SEPARATOR_STR);
  }
  var currentSetNames = factorySets[0].concat(customSets[0]);
  var currentSetFiles = factorySets[1].concat(customSets[1]);

  ACTIVE_SET_STR = DWfile.read(FILE_ACTIVE_SET);
  MENU_CURRENT_SET.setAll(currentSetNames,currentSetFiles);
}

function isKeyWithoutCtrl(theKey)
{
  var retVal=false;
  if (theKey.length == 1)
    retVal = true;
  else
  {
    index = theKey.lastIndexOf("+");
    tempStr = theKey.substring(index+1);
    if (PLATFORM=="Win32")
    {
      if (tempStr.length == 1 && theKey.indexOf("Cmd") == -1 && theKey.indexOf("Ctrl") == -1)
        retVal = true;
    }
    else 
    {
      if (tempStr.length == 1 && theKey.indexOf("Cmd") == -1)
        retVal = true;
    }
  }
  return retVal;
}

// returns error message if the given shortcut key is a problematic one for current keyboard layout
function checkKeyForProblem(newKey)
{
  var retVal = "";
  var problemId = dw.isAProblematicShortcut(newKey);
  var key = newKey.substring(newKey.lastIndexOf("+")+1);
  
  if (problemId)
  {
    if (problemId == 1)
      retVal = createWarningMsg(MSG_DeadKeyInShortcut, key);
    else if (problemId == 2)
      retVal = createWarningMsg(MSG_AltGr, "");
    else if (problemId == 3)
      retVal = createWarningMsg(MSG_UsedByIME, "");
    else if (problemId == 4 && PLATFORM != "Win32")
      retVal = createWarningMsg(MSG_NeedToRelaunch, "");
  }
  return retVal;
}
  
// returns error message if the given shortcut key is invalid
function checkKeyForConflict(newKey)
{
  var retVal, conflictId;
  if (newKey)
    conflictId = CURRENT_SHORTCUT_LIST.getIdByKey(newKey);
  if (PLATFORM == "Win32" && conflictId == "" && newKey.indexOf("Cmd") != -1)
  {
  	newKey = newKey.replace(/Cmd/,"Ctrl");
  	conflictId = CURRENT_SHORTCUT_LIST.getIdByKey(newKey);
  }
  	
  CONFLICT_ID = conflictId;
  if (isKeyWithoutCtrl(newKey))
  {
    retVal = createWarningMsg(MSG_LetterShortcutMustHaveCtrl, CTRL_STR);
    CAN_APPLY = false;
  }
  else
  {
    CAN_APPLY = true;
    if (conflictId)
      retVal = createWarningMsg(MSG_ShortcutAssigned, getNameFromTreeArray(conflictId));
    else
      retVal="";
  }
  return retVal;
}

function createWarningMsg(messageStr, errorMsgArg)
{
  var retVal = new Array();
  imagePath = YIELD_PATH;
  
  if (messageStr == MSG_LetterShortcutMustHaveCtrl)
  {
    imagePath = STOP_PATH;
  }
  
  retVal.push('<img src="'+ imagePath + '" width="13" height="13" >&nbsp;');
  retVal.push(errMsg(messageStr, errorMsgArg));
  return retVal.join("");
}


function isSet(setFileName, setType)
{
  var facSetArray = new Array(), i, retVal = false;
  facSetArray = getCustomSetList(setType)[1];
  if (setFileName.lastIndexOf(".xml") != setFileName.length-4)
    setFileName = setFileName + ".xml";
  for (i=0; i<facSetArray.length; i++)
  {
    if (facSetArray[i] == setFileName)
    {
      retVal = true;
      break;
    }
  }
  return retVal;
}

function createHTMLContents()
{
  var retVal = new Array(), i, treeNodeStr, keyStr,currLevel;
  var nextNodeStr="",isBold,tempNodeStr;
  retVal.push("<HTML>"+NEWLINE+"<HEAD>");
  retVal.push("<TITLE>" + CURRENT_SHORTCUT_LIST.shortcutListName + " Shortcut Set" + "</TITLE>" + NEWLINE);
  retVal.push("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />" + NEWLINE);
  retVal.push('<style type="text/css">\n<!--\nbody {font-family:  '  + cssfontStr + '; text-align: center}\ntable {  font-size: x-small}\n-->\n</style>')
  retVal.push("</HEAD>"+NEWLINE);
  retVal.push('<BODY BGCOLOR="#FFFFFF">');
  retVal.push('<DIV ALIGN="center">');
  retVal.push('<p><b><font size="6">'+ MENU_CURRENT_SET.get()+'</font></b></p>')
  ARRAY_COMMANDS_TREENODES = updateTreeNodeArray(ARRAY_COMMANDS_TREENODES);
  for (i=0;i<ARRAY_COMMANDS_TREENODES.length;i++)
  {
    if (ARRAY_COMMANDS_TREENODES[i]!="-")
    {
      retVal.push("<p><b>"+MENU_COMMANDS.get(i)+"</b></p>"+NEWLINE);
      retVal.push('<TABLE border = "1" cellspacing="0" cellpadding="2">'+NEWLINE);
      for (x=0;x<ARRAY_COMMANDS_TREENODES[i].length;x++)
      {
        treeNodeStr = ARRAY_COMMANDS_TREENODES[i][x];
        var nodeName = getTreeNodeValue(treeNodeStr,1);
        if (!nodeName)
          continue;
          
        for (var k=x+1;k<ARRAY_COMMANDS_TREENODES[i].length;k++)
        {
          tempNodeStr = ARRAY_COMMANDS_TREENODES[i][k];
          if (getTreeNodeValue(tempNodeStr, 1))
          {
            nextNodeStr = tempNodeStr;
            break;
          }
        }
        
        currLevel = getTreeNodeLevel(treeNodeStr);
        isBold = (nextNodeStr && (getTreeNodeLevel(nextNodeStr) > currLevel))

        retVal.push("<TR>"+NEWLINE);
        retVal.push("<TD>");
        for(var j=0; j<currLevel*4; j++)
          retVal.push("&nbsp;")
        if (isBold)
          retVal.push("<b>");
        retVal.push(nodeName)
        if (isBold)
          retVal.push("</b>");
        retVal.push("</TD>"+NEWLINE);
        keyStr = getTreeNodeValue(treeNodeStr,2);
        if (!keyStr) keyStr = "&nbsp;";
        retVal.push("<TD>"+keyStr+"</TD>"+NEWLINE);
        retVal.push("</TR>"+NEWLINE);
      }
    }
    retVal.push("</TABLE>");
  }
  retVal.push("</div>"+NEWLINE + "</BODY>"+NEWLINE+"</HTML>");
  return retVal.join("");
}

function getTreeNodeValue(treeNodeStr,column)
{
  var startIndex, endIndex, valueStr, valueArray, retVal ="";
  startIndex = treeNodeStr.indexOf('value="');
  if (startIndex == -1) return "";
  startIndex += 7;
  endIndex = treeNodeStr.indexOf('"', startIndex);
  valueStr = treeNodeStr.substring(startIndex,endIndex);
  valueArray = valueStr.split("|");
  if (valueArray.length >= column)
  retVal = valueArray[column-1];
  return retVal;
}

function getTreeNodeLevel(treeNodeStr)
{
  var startIndex, endIndex, valueStr="0", valueArray;
  startIndex = treeNodeStr.indexOf('level="');
  if (startIndex == -1) return 0;
  startIndex += 7;
  endIndex = treeNodeStr.indexOf('"', startIndex);
  valueStr = treeNodeStr.substring(startIndex,endIndex);
  return (valueStr) ? valueStr : 0;
}

function getSimpleName(filenameArray)
{
  var i;
  for (i=0;i<filenameArray.length;i++)
  {
    if (filenameArray[i].lastIndexOf(".xml") == filenameArray[i].length-4)
      filenameArray[i] = filenameArray[i].replace(/.xml/,"");
  }
  return filenameArray;
}

function getExtension(fileName)
{
  var retVal = "", index;

  index = fileName.lastIndexOf(".");
  if (index != -1)
    retVal = fileName.substring(index+1);
  return retVal;
}

function getSimpleFileName(fileName)
{
  var index; retVal = fileName;

  index = fileName.lastIndexOf(".");
  if (index != -1)
    retVal = fileName.substring(0,index);
  return retVal;
}
/*
function convertKeyStr(keyStr,location)
{
  var retVal=keyStr;
  if (PLATFORM=="Win32")
  {
    if (location === "display")
    {
      if (retVal.indexOf("Cmd")!=-1)
        retVal = retVal.replace(/Cmd/g,"Ctrl");
      if (retVal.indexOf("Opt")!=-1)
        retVal = retVal.replace(/Opt/g,"Alt");
    }
    if (location  == "store")
    {
      if (retVal.indexOf("Ctrl")!=-1)
        retVal = retVal.replace(/Ctrl/g,"Cmd");
      if (retVal.indexOf("Alt")!=-1)
        retVal = retVal.replace(/Alt/g,"Opt");
    }
  }
  return retVal;
}
*/
function getPressedKeys()
{
  var eventObj = window.event;
  var retVal = new Array();
  var theKeyCode = eventObj.keyCode;
  var charCode = dw.mapKeyCodeToChar(theKeyCode);
  var keyStr = KEY_CODES[theKeyCode];
  var modifierFound = false, nonModifier=false;

  if (eventObj.ctrlKey)
    retVal.push("Ctrl");
  if (eventObj.cmdKey)
    retVal.push("Cmd");
  if (eventObj.altKey)
    retVal.push(ALT_STR);
  if (eventObj.shiftKey)
    retVal.push("Shift");
  
  if (PLATFORM == "Win32" && theKeyCode > 127)
    keyStr = "";
    
  if (keyStr)
  retVal.push(keyStr);
  else if (charCode !=0)
    retVal.push(String.fromCharCode(charCode));

  // allow tab and shift-tab to move cursor in and out off newShortcutEntry
  if (retVal.length == 1 && keyStr == "Tab"){
		  document.theForm.applyButton.focus();
		  return false;
  }

  if (retVal.length == 2 && retVal[0]== 'Shift' && keyStr == "Tab"){
		  document.theForm.itemList.focus();
		  return false;
  }

  for (var i=0; i<retVal.length; i++)
  {
    modifierFound=false;
    for (var j=0; j<MODIFIER_KEYS.length; j++)
    {
      if (MODIFIER_KEYS[j]== retVal[i])
      {
        modifierFound = true;
        break;
      }
    }
    if (!modifierFound)
    {
      nonModifier=true;
      break;
    }
  }
  if (retVal[0] && nonModifier)
    document.newShortcutEntry.value = (retVal.length > 1) ? retVal.join("+") : retVal[0];
  else
    document.newShortcutEntry.value = "";
  return false;
}

function clearField(objName)
{
  document[objName].value = "";
  updateUI(objName);
}

function getNameFromTreeArray(id)
{
  var i,x, startIndex, endIndex, pipeIndex, idFound, retVal="";

  for (i=0; i<ARRAY_COMMANDS_TREENODES.length; i++)
  {
    for (x=0; x<ARRAY_COMMANDS_TREENODES[i].length; x++)
    {
      nodeStr = ARRAY_COMMANDS_TREENODES[i][x];
      startIndex = nodeStr.indexOf('name="') + 6;
      if (startIndex >=6)
      {
        endIndex=nodeStr.indexOf('"',startIndex);
      nodeName=nodeStr.substring(startIndex, endIndex);
      }
      if (nodeName == id)
      {
        startIndex=nodeStr.indexOf('value="') + 7;
        if (startIndex >= 7)
        {
          pipeIndex = nodeStr.indexOf("|", startIndex);
          endIndex = (pipeIndex == -1) ? nodeStr.indexOf('"',startIndex) : pipeIndex;
          retVal = nodeStr.substring(startIndex, endIndex);
        }
        idFound=true;
        break;
      }
    }
    if (idFound)
      break;
  }
  return retVal;
}

function checkLockedFiles()
{
  loadGlobals();

  retVal = false;
  fileArray = new Array(FILE_MENUXML_PATH,FILE_ACTIVE_SET);
  for (var i=0;i<fileArray.length; i++)
  {
    if (DWfile.getAttributes(fileArray[i])=="R")
    {
      alert(errMsg(MSG_ReadOnlyFile,fileArray[i]));
      retVal=true;
    }
  }
  return retVal;
}

function addShortcutsFromTree(treeData)
{
	var numElts = treeData.names.length;
	for(var i=0; i < numElts; i++){
		 CURRENT_SHORTCUT_LIST.addShortcut( treeData.names[i],  treeData.keys[i]);
	}
	return;
}

