/*

    Copyright 2003-2007 Purdue University. 

    Developed by: Peter Turbek, Department of Mathematics, Computer Science, and Statistics, Purdue University Calumet.


    This file is part of CaluMath.

    CaluMath is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    CaluMath is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/


CaluMath.PM.FORWARDSLASH='/';
CaluMath.PM.BACKSLASH='\\';


//Comment: DEFINITION OF CaluMath.PM.MAKEROBJECT
//Comment: This creates all the different objects in CaluMath, for example, definedfunction, newplot (which are axes), clickbutton etc. All of the interface menus are for users to construct CaluMath.PM.PageMakerObjects.
//Comment: I know this seems unusual. This is the only way I could find of creating the object in the CM_TopWindow, no matter what window we are in. 
//Comment: Instead of using the new command to say something like X= new CaluMath.PM.PageMakerObject, we invoke CaluMath.PM.PageMakerObject as a function. The problem is that we want all these objects constructed in the CM_TopWindow, however with inserted text, the window that is invoking CaluMath.PM.PageMakerObject is not the top window. If objects are construced in different windows, problems arise. This comes into play when someone inserts a special object inside an HTML object. For example, if someone is constructing a paragraph and wants to put a special span tag inside it, they open up a new window that deals just with the span tag. If the CaluMath.PM.PageMaker associated to the span were constructed in the new window, then when the new window is closed, there is no guarantee we can reference the CaluMath.PM.PageMaker object (in Mozilla it seems you can, but in IE it seems that you can't). By constructing all the CaluMath.PM.PageMakerObject in the top window, we are assured that they can be referenced later. 
//Comment: Note that although CaluMath.PM.PageMakerObject creates all the CaluMathPageMakerObjects, it is not actually a constructor function; it actually calls the constructor function CaluMath.PM.PageMakerObjectCreator and then add properties to the object created by it.  

CaluMath.PM.PageMakerObject=function(){

   //Comment: argument[0] is the type
   //Comment: arguments[1] is the cm_optionsarray
   //Comment: arguments[2] is the cm_requiredarray
   //Comment: arguments[3] is the childarray
   //Comment: Most often, the item is usead as follows: CaluMath.PM.PageMakerObject("definedfunction") creates a definedfunction object. However, when a previously created page is being parsed, we need to recreated the objects that have been created in that page. This is done as follows. At the end of the previously saved page is a JavaScript string encapsulating all the information of the page, namely all the items that have been created, all of the cm_requiredarry and cm_optionsarray (which give the ["property name", "value"] pairs of information about the object, and the relationship between the objects, for example, which object is a child of which object. These are precisely the arguments of the CaluMath.PM.PageMakerObject function, so the way the previous page string is saved automatically means children are created correctly and each object has the correct cm_requiredarray and cm_optionsarray. //

   //Comment: The line below forces the objects to be created in the CM_TopWindow. 
   var temp=CM_TopWindow.CaluMath.Html.Eval("new CaluMath.PM.PageMakerObjectCreator('"+arguments[0]+"')");
   CM_TopWindow.CaluMath.PM.EveryObjectArray.push(temp);
   var args1=arguments[1];
   var args2=arguments[2];
   var args3=arguments[3];
   var temparray= CM_TopWindow.Array();
   if(args1 != null){
      var args1length=args1.length;
      for(var i=0; i<args1length; i++){
         if(args1[i].cm_constructorname != "Array"){
            temparray[i]=args1[i];
         }
         else{
            temparray[i]=CM_TopWindow.Array(args1[i][0],args1[i][1]);
         };
      };
   };
   temp.cm_optionsarray=temparray;
   var temparray= CM_TopWindow.Array();
   if(args2 != null){
      var args2length=args2.length;
      for(var i=0; i<args2length; i++){
         if(args2[i].cm_constructorname != "Array"){
            temparray[i]=args2[i];
         }
         else{
            temparray[i]=CM_TopWindow.Array(args2[i][0],args2[i][1]);
         };
      };
   };
   temp.cm_requiredarray=temparray;

   if(args3 ==null){
      temp.childarray= CM_TopWindow.Array();
   }
   else{
     temp.childarray=args3;
   };
   
   temp.forremovalarray= CM_TopWindow.Array();
   
//   CM_TopWindow.tempfunctionfordeletion=null;

   var temptype=temp.type;
   if(temptype=="htmltext" || temptype=="text" || temptype=="coordinates"){
      if(temp.cm_getsetting("name").length>0 && CM_TopWindow.ImportMode != "yes"){
         CM_TopWindow.CaluMath.PM.PageMakerObjectParent[temp.cm_getsetting("name")]=temp;
      };
   };
   return temp;
};




//COMMENT: STATEMENTS FOR TOPWINDOW==WINDOW ONLY 
//Comment: This counts the HTML Elements that are created and associated to a CaluMath.PM.PageMakerObject. Each will be given the id htmlelement+HTMLElementIndex.
if(CM_TopWindow==window){
   CaluMath.PM.HTMLElementIndex=0;
   CaluMath.PM.TextIndex=0;
   CaluMath.PM.SectionIndex=0; 
   CaluMath.PM.ParagraphIndex=0; 
   CaluMath.PM.TitleIndex=0; 
   CaluMath.PM.ContainerIndex=0; 
   CaluMath.PM.MathTextIndex=0; 

   //Comment: CaluMath.PM.OpenWindowIndex is used when windows are opened to give each a unique taget name. This is required because Opera overwrites windows unless they have a different name. 
   CaluMath.PM.OpenWindowIndex=0; 


   //Comment: By default, this is what a Web Browser will display for a constructed page. It can be modified by the user using Name Web Page  
   CaluMath.PM.PageName="A CaluMath Page"

   //Comment: This is used in determining paths for files such as images or links that the user wants to add to a Web Page. 
   CaluMath.PM.PageMakerTargetFilePrefix=decodeURI(document.location.pathname).replace(/CaluMath_Page_Maker.html$/,'');

   //Comment: An Html title is a small pop-up balloon that gives tips. CaluMath.PM.UseTitles will allow for the creation of these to guide users with filling out required and optional entries in tables. 
   //Comment: CaluMath.PM.UseStatus does the same except it uses Status Bar. Some users may not have the Status Bar visible however and some browsers may no longer allow the Status Bar to display text created with JavaScript.

   CaluMath.PM.UseTitles=true;
   CaluMath.PM.UseStatus=true; 

   //Comment: PlotNameIndex is used to construct default names for things like tangents or points
   CaluMath.PM.PlotNameIndex=0;

   //Comment: The main structure of the created HTML page is contained in the CaluMath.PM.PageMakerObjectArray. It is an array of object; each object corresponds to some HTML tag or CaluMath.PM.Math object. To write an HTML page, CaluMath.PM.PageMakerObjectArray is examined entry by entry and the objects are written in the order they appear in the array. 
   //Comment: Some objects are not stored directly as entries in  CaluMath.PM.PageMakerObjectArray however. For example, a CaluMath.PM.Plot (which is a set of axes) is an entry in CaluMath.PM.PageMakerObjectArray. However a graph of a function on the set of axes is a child of the CaluMath.PM.Plot, so it is not directly in CaluMath.PM.PageMakerObjectArray, but is a child of an element in CaluMath.PM.PageMakerObjectArray. This makes sense since, if you delete the axes, you would want to automatically delete the points and graphs of functions on the graph (without this, major JavaScript errors would occur). For things like tangents, points, graphs of functions, there is a natural place to store the object as a child of some other object. This is done automatically. Paragraphs and Titles are normally elements of CaluMath.PM.PageMakerObjectArray. So most objects have a natural place where they are stored. However, sometimes things should not be stored in their normal place. For example, if you have a button, there is an object, called a buttonaction, that controls what happens when you click on the button. If you want a point to be graphed when you click on the button, then the point should be a child of the buttonaction. Similarly if you have an conditional (basically an if statement, or if/else pair, then the comparison for the if would be a child of the conditional, and any statemets to be executed if the comparison is true would also be a child of the conditional. 
   //Comment: But when a page designer wants to create a point, the program needs to know if this is a point that should go in its normal place or if the page designer is in the middle of a button action or conditional or other such object that will force the point to be a child of that object. The way this is done is by creating a CaluMath.PM.InsertionObject and appending it to the CM_TopWindow.CaluMath.PM.InsertionArray. If this array does not have lenght 0, then objects are supposed to be children of the last object in the array. The fact that it is an array, allows for multiple levels of children. For example, a buttonaction can contain a conditional. New objects are children of the conditional until the page designer says the conditional is finished. At this point the conditional is removed from the CM_TopWindow.CaluMath.PM.InsertionArray which will expose the buttonaction as the last element in the array. Then new objects will be children of the buttonaction until that is completed.
   //Comment: Do note that most objects have two children automatically. The first is a text object that is used to identify the object during CM_EditMode. For example, if a page designer wants to edit a plot of a point, they would click on the text object that is the child of the point plot. This text object appears in the HTML document only when it is written in CM_EditMode or when the page is being re-arranged. The second child has a type of script (or something specific like scriptbuttonaction where children to the object are actually put. This allows the script object to control HTML code or CaluMath.PM.Math code that might be needed to enclose all the children. 

   CM_TopWindow.CaluMath.PM.CSSTextStyleString= '\n.cm_math{white-space:nowrap}\n.cm_mathformula{white-space:nowrap}'; 

};  //Comment: This is the end of the conditional CM_TopWindow==window above. We only want the above created for the CM_TopWindow. 
//COMMENT: END OF TOPWINDOW==WINDOW SECTION

//COMMENT: TYPE OF OBJECTS THAT CAN GO IN CM_TopWindow.CaluMath.PM.InsertionArray. 
//Comment: This gives the types of objects that could be objects in CM_TopWindow.CaluMath.PM.InsertionArray. These are things that would require text or graphs, etc. to not be put in their normal places, but associated instead with buttonactions, conditional statements and such things. 

CaluMath.PM.TopWindowInsertionArrayObjectPossibilities=["buttonaction", "conditional", "routine", "compositeobject", "newwindow", "forloop"];

//Comment: This function takes the possible CM_TopWindow.InsertionArray object types above and puts the String "script" in front of them. This is the gives the type for the childarray[1] of each object.  
CaluMath.PM.MakeTopWindowInsertionArrayScriptObjectPossibilities= function(){
   CaluMath.PM.TopWindowInsertionArrayScriptObjectPossibilities = new Array();
   var CM_TopWindowInsertionArrayObjectPossibilitieslength = CaluMath.PM.TopWindowInsertionArrayObjectPossibilities.length;
   for(var i=0; i< CM_TopWindowInsertionArrayObjectPossibilitieslength; i++){
      CaluMath.PM.TopWindowInsertionArrayScriptObjectPossibilities[i]= "script"+CaluMath.PM.TopWindowInsertionArrayObjectPossibilities[i];
   };
   return CaluMath.PM.TopWindowInsertionArrayScriptObjectPossibilities;
};

//Comment: We execute the function to actually create the script list. 
CaluMath.PM.MakeTopWindowInsertionArrayScriptObjectPossibilities();
  
//COMMENT: THIS IS A LIST OF ALL THE TYPES OF LISTS THAT ARE KEPT. FOR EXAMPLE, THESE ARE WRITTEN TO A WEB PAGE WHEN THE USER CLICKS ON THE LISTS BUTTON. THE ALTERNATENAMES VERSION IS WHAT THE USER ACTUALLY SEES WHEN HE/SHE VIEW THE LIST. CaluMath.PM.ListOfLists IS THE ACTUAL INTERNAL NAMES OF THE LIST ENTRIES. 
//COMMENT: ALL OF THE LISTS ARE IN THE OBJECT CaluMath.PM.PlotlistObject. SOME OTHER LISTS ARE KEPT AS OBJECTS OF OTHER LISTS.

CaluMath.PM.ListOfLists=["newplot", "definedconstant", "variablename", "nameclickedpoint", "namedraggedvalue", "nameanimationvalue", "definedfunction","discretefunction","allfunctions", "animationplot", "mathtext", "graph",   "textplot", "iframe", "links", "images", "namedobject", "staticobject", "table", "functiontable", "tablefromdata", "discretefunctionconstructiontable", "list", "button", "boxes",     "buttonaction", "forloop", "newwindow", "addtonewwindow", "textbox",  "comparison", "conditional",  "routine",  "executeroutine", "textstylesheet", "focus", "slidingscale"]; 
CaluMath.PM.ListOfListsAlternateNames=["Axes", "Constants", "Named Objects", "Name Clicked Points", "Name Dragged Value", "Name Animation Value", "Functions","Discrete Functions","All Functions", "Animations", "Math Text", "Graphs",  "Text Plot", "IFrames", "Links", "Images", "Objects With Names",  "Static Objects", "Tables", "Function Tables", "Table From Lists", "Discrete Function Construction Table", "Lists",  "Buttons", "Boxes and Drop Down Menus",  "Button Actions", "For Loops", "New Windows", "Add To New Windows", "Text Boxes", "Comparison", "Conditionals",  "Routines" ,  "Execute Routine", "Default Settings", "Focus Objects", "Sliding Scale"]; 
//CM_NotViewAbleListOfListsMembers=["namedobject", "cansupportbuttonsname"]
CaluMath.PM.NotViewAbleListOfListsMembers=["namedobject"]

//CaluMath.PM.ListsSubordinateToCM_ParentObjectArray=["draggedobjectslist","slidingscalelist"];
CaluMath.PM.ListsSubordinateToCM_ParentObjectArray=["draggedobjectslist"];

//Comment: CaluMath.PM.MakeLists is invokes in a few lines after the creation of CaluMath.PM.PlotlistObject. 
CaluMath.PM.MakeLists= function(){
   var CM_ListOfListslength=CaluMath.PM.ListOfLists.length;
   for(var i=0; i<CM_ListOfListslength; i++){
      CaluMath.PM.PlotlistObject[CaluMath.PM.ListOfLists[i]+"list"] = new Array();
   };
   var tempobject= CaluMath.PM.PageMakerObject("CM_MainWindow");
   CaluMath.PM.SetPageMakerObjectRequired(tempobject,"name", "CM_MainWindow");
   CaluMath.PM.PlotlistObject.newwindowlist.push(["CM_MainWindow","CM_MainWindow",tempobject]);
   CaluMath.PM.PlotlistObject.CM_MainWindow=new Object();
   CaluMath.PM.PlotlistObject.CM_MainWindow.iframelist=new Array();
   CaluMath.PM.PlotlistObject.CM_MainWindow.namedobjectlist=new Array();
   CaluMath.PM.PlotlistObject.CM_MainWindow.staticobjectlist=new Array();
   CaluMath.PM.PlotlistObject["CM_ParentObject"]= new Array();
   for(var i=0; i<CaluMath.PM.ListsSubordinateToCM_ParentObjectArray.length; i++){
      CaluMath.PM.PlotlistObject["CM_ParentObject"][CaluMath.PM.ListsSubordinateToCM_ParentObjectArray[i]]= new Array();
   };
};


//COMMENT: ANOTHER TOPWINDOW==WINDOW OR ELSE SECTION
//Comment: CaluMath.PM.PageMakerObjects contain the settings and properties of the HTML objects created. We want them all to be created in the primary window. Each CaluMath.PM.PageMakerObject is an object of CaluMath.PM.PageMakerObjectParent and is indexed by the element's name when in an Edit Window or a Window of lists of objects. 
//Comment: Usually the element's name (except for text objects) is something like htmlelement365. Then CaluMath.PM.PageMakerObjectParent["htmlelement365"] refers to the object. When an Edit Window is written, the object will have some HTML text with the id="htmlelement365". When this is clicked, it is instructed to look at CaluMath.PM.PageMakerObjectParent["htmlelement365"] and that object is recreated to be edited.   . Each CaluMath.PM.PageMakerObject is  
//Coment: If it is not the top window, then in the new window we want to create all of the constants and variablenames and functions that have been created so far, so the user can refer to them in the page without error. For example, we would want to allow the user to write "Note that f gives the values f(3)=cm_evalm(f(3))" in a paragraph without an error because f is really defined in the Main window and not this secondary window.
if(CM_TopWindow==window){
   CM_TopWindow.CaluMath.PM.PageMakerObjectParent= new Object();
}
else{
   if(CM_TopWindow.CaluMath.PM.PlotlistObject != null && CM_TopWindow.CaluMath.PM.PlotlistObject.definedconstantlist != null){
      for(var i=0; i< CM_TopWindow.CaluMath.PM.PlotlistObject.definedconstantlist.length; i++){
         window[CM_TopWindow.CaluMath.PM.PlotlistObject.definedconstantlist[i][0]]=CM_TopWindow[CM_TopWindow.CaluMath.PM.PlotlistObject.definedconstantlist[i][0]];
      };
   };
   if(CM_TopWindow.CaluMath.PM.PlotlistObject != null && CM_TopWindow.CaluMath.PM.PlotlistObject.variablenamelist != null){
      for(var i=0; i< CM_TopWindow.CaluMath.PM.PlotlistObject.variablenamelist.length; i++){ 
         window[CM_TopWindow.CaluMath.PM.PlotlistObject.variablenamelist[i][0]]=CM_TopWindow[CM_TopWindow.CaluMath.PM.PlotlistObject.variablenamelist[i][0]];
      };
   };
   if(CM_TopWindow.CaluMath.PM.PlotlistObject != null && CM_TopWindow.CaluMath.PM.PlotlistObject.definedfunctionlist != null){
      for(var i=0; i< CM_TopWindow.CaluMath.PM.PlotlistObject.definedfunctionlist.length; i++){ 
         window[CM_TopWindow.CaluMath.PM.PlotlistObject.definedfunctionlist[i][0]]=CM_TopWindow[CM_TopWindow.CaluMath.PM.PlotlistObject.definedfunctionlist[i][0]];
      };
   };
};

CM_TopWindow.CaluMath.PM.EmptyString="";
CaluMath.PM.EmptyString="";

CM_TopWindow.CaluMath.PM.SpaceString=" ";
CaluMath.PM.SpaceString=" ";

//Comment: This is an array that contains, in order, the CaluMath.PM.PageMakerObjects (which yield the HTML objects) created. 
CaluMath.PM.PageMakerObjectArray= new Array();

//Comment: These are list of objects. They contain information that is put into the dropdown menus. For example, if you want to create a graph of a function, the dropdown menu that allows you to do this needs to know what functions have been created already (you can't graph a function unless the function has been defined already). This explains the definedfunctionlist.  The axes different sets of axes that are draw already also appear in a dropdown menu, hence the newplotlist which is used to populate the dropdownmenu. The names of all of the lists are a concatenation of the object name and the word list. 

CaluMath.PM.PlotlistObject= new Object();
CaluMath.PM.MakeLists();


//COMMENT: GRAPHLIST DEFINED HERE 
//Comment: This is for any type of graph. It is used in remove graphs buttonaction. I NEED TO CHECK THIS MORE.
CaluMath.PM.PlotlistObject.graphlist=new Array();


//COMMENT: SECTION DEALING WITH CaluMath.PM.CHECKFORNORMALOBJECT AND CaluMath.PM.AUTOMATICALLYPLACEOBJECTASCHILD. 

//Comment: This returns whether the object is "normal" or whether it is embedded in something like a buttonaction, or conditional or newwindow CaluMath.PM.Math code. In these latter cases, for example we would not want to have script tags or div tags, because the parent object would create these tags. 
//Comment: We return true if the object should be placed in its normal place, in other words, not as a child of the last object of CaluMath.PM.InsertionArray. False is returned otherwise. We actually calculate a true value if the object is not normal, and then return the opposite of this.
//Comment: Note that this calls CaluMath.PM.AssignParents, so for efficiency, when CaluMath.PM.CheckForNormalObject is called, you probably won't need to call CaluMath.PM.AssignParents right after. 
//Comment: The cases where the object won't be normal are 
//   1) When CaluMath.PM.InsertionArray doesn't have length 0. This means that all objects are to be placed as children of the last object of the CaluMath.PM.InsertionArray.
//   2) We are in CM_EditMode and the is an object such as a buttonaction or conditional. These types are in the array CaluMath.PM.TopWindowInsertionArrayObjectPossibilities. 

CaluMath.PM.CheckForNormalObject= function(){
   //Comment: firstvalue below is true if the object is NOT normal. 
   var tempobject=arguments[0];
   CaluMath.PM.AssignParents();
   var firstvalue=false;
   if(CM_TopWindow.CaluMath.PM.InsertionArray.length !=0){
      //Comment: This corresponds to case 1) above. 
      firstvalue=true;
   };
   if(firstvalue){
      //Comment: We are saying that the object is not normal. 
      return !firstvalue;
   }
   else{
      var secondvalue= (CM_TopWindow.CM_EditMode ==true && tempobject.parent != null);
      //Comment: If we are in CM_EditMode then if it is not normal, the parent of the object is an object (that at one time was an object in the CaluMath.PM.InsertionArray). If this is the case, then we want to check that the object is of the correct type, for example a buttonaction, or conditional, etc. These types are given in the CaluMath.PM.TopWindowInsertionArrayObjectPossibilities array. 
      if(secondvalue==true){
         var thirdvalue=false;
         var CM_TopWindowInsertionArrayObjectPossibilitieslength=CaluMath.PM.TopWindowInsertionArrayObjectPossibilities.length;
         thirdvalueloop:
         for(var i=0; i< CM_TopWindowInsertionArrayObjectPossibilitieslength; i++){ 
            if(tempobject.parent.type == CaluMath.PM.TopWindowInsertionArrayObjectPossibilities[i]){
               thirdvalue=true;
               break thirdvalueloop;
            }
         };
         //Comment: So if thirdvalue is true, it means that we are in edit mode and satisfy case 2) above. 
         return !thirdvalue;
      }
      else{
         return true;
      };
   };
};

//Comment: I don't think this does anything valuable anymore. At one time it hard-coded tags at the time of the creation of the objects. But this is not done anymore. However, I believe this is still called regularly in the creation of objects (probably for no purpose).
CaluMath.PM.SetWriteTag = function(){ 
   var tempobject=arguments[0];
   if(CaluMath.PM.CheckForNormalObject(tempobject)){
      tempobject.cm_setrequired("writetag","yes"); 
   }; 

};



//Comment: This function takes two arguments, a dropdown menu and a string representing the label name of one of the options. The function makes the label be selected. This allows us to offer reasonable choices for the user without the user having to set options they are not interested in. 


//COMMENT: SECTION DEALING WITH CREATING SELECTMENUS AND DEFAULTOPTIONS FOR THEM

CaluMath.PM.MakeDefaultOption=function(){
   var selectmenu= arguments[0];
   var wantedlabel=arguments[1];
   var type=arguments[2];
   if(wantedlabel != null && wantedlabel.length != 0){
      if(type==null || type=="label"){
         var options=selectmenu.options;
         var optionslength= options.length;
         for(var i=0; i<optionslength; i++){
            if(options[i].label==wantedlabel){
//alert([options[i],wantedlabel]);
//              selectmenu.selectedIndex=i;
              return options[i].selected=true;
            };
         };
      }
      else{ //alerttest([selectmenu, wantedlabel,type]);
         var options=selectmenu.options;
         var optionslength= options.length;
         for(var i=0; i<optionslength; i++){
            if(options[i].value==wantedlabel){
//alert([options[i],wantedlabel]);
//              selectmenu.selectedIndex=i;
              return options[i].selected=true;
            };
         };
      };
   };
};

//Comment: This function takes a HTML select node and adds options for each element of a list. Typically the list is something such as stylelist, or attributelist,  but it does not need to be one of these. If the list has an entry that is an array, the first element becomes the label of the option and the second becomes the value of the option. If the list entry is not an array, both the label and value is the list entry. 
CaluMath.PM.MakeSelectMenu= function(){
if(CM_TopWindow.checkmenus=="yes"){
//   alerttest(arguments[0]);
};
//alerttest([arguments[0].type, arguments[1]]);
  var selectmenu=arguments[0];
  selectmenu.options.length=0;
  var list= arguments[1];
  var listlength=list.length;
  for(var i=0; i<listlength; i++){ 
     var pElement =document.createElement("option");
     if(list[i] != null && list[i].cm_constructorname=="Array"){
        pElement.setAttribute("id",list[i][0]+"option");
        if(list[i][1] != null){
           pElement.setAttribute("value", list[i][1]);
        }
        else{
           pElement.setAttribute("value", list[i][0]);
        };
        pElement.setAttribute("label", list[i][0]);
        if(list[i][2] != null){
//           pElement.cm_object=list[i][2];
        };
        selectmenu.add(pElement,undefined);   
     //Comment:  Unfortunately Mozilla wants to have text appended for the entries. This causes an error in IE. This is a workaround.
        if(pElement.childNodes.length==0){
           var qElement = document.createTextNode(list[i][0]);
           pElement.appendChild(qElement);
        };
     }
     else{
        pElement.setAttribute("id",list[i]+"option");
        pElement.setAttribute("value", list[i]);
        pElement.setAttribute("label", list[i]);
        selectmenu.add(pElement,undefined);   
     //Comment: Unfortunately Mozilla wants to have text appended for the entries. This causes an error in IE. This is a workaround.
        if(pElement.childNodes.length==0){
           var qElement = document.createTextNode(list[i]);
           pElement.appendChild(qElement);
        };
     };
  };
};

//COMMENT: ABOVE IS END OF SECTION DEALING WITH CREATING SELECTMENUS AND DEFAULTOPTIONS FOR THEM



   CaluMath.PM.PageMakerDefaultMaker= function(){

//     CM_TopWindow["CaluMath.PM.PageMaker"+arguments[0]+"Default"]= this;
     CM_TopWindow["CaluMath"]["PM"]["PageMaker"+arguments[0]+"Default"]= this;
     this.type=arguments[0];
     CaluMath.PM.PageMakerDefaultMaker.DefaultArray.push(this);  
   };

CaluMath.PM.PageMakerDefaultMaker.DefaultArray=new Array();

CaluMath.PM.PageMakerDefaultMaker.prototype.toString = function(){
   return "CaluMath.PM.PageMaker"+this.type+"Default";
};

if(CM_TopWindow==window){

//Comment: To add a new type of object you must:
// 1) Create a new object here:
// 2) Create an addto list in the cm_addtolists.js file. 
// 3) Create a default object (which has the settings for the various drop down menus that are used in the creation of the object in an HTML page).
// 4) Create a section in either the CaluMath.PM.MATHBUTTON.onclick or CaluMath.PM.WriteAndEdit. 
// 5) Determine if any special instructions need to be issued in CaluMath.PM.WriteNewWindowString (which writes the actual HTML code to a new window) or 
//    CaluMath.PM.WriteNewWindowStringEditMode (which writes the actual HTML code to a new window in Edit Mode) or
//    CaluMath.PM.PageMakerObjectToString (which appends a string in the last script of the actual HTML code written to a new window. This string contains all the information about the objects created and their properties and is used when the page is saved to a file. When a saved file is loaded, it is read by CaluMath.PM.ParsePageMakerPage, so that the objects and their settings can be recreated).  

new CaluMath.PM.PageMakerDefaultMaker("definedconstant");
new CaluMath.PM.PageMakerDefaultMaker("variablename");
new CaluMath.PM.PageMakerDefaultMaker("definedfunction");
new CaluMath.PM.PageMakerDefaultMaker("newplot");
new CaluMath.PM.PageMakerDefaultMaker("rescaleaxes");
new CaluMath.PM.PageMakerDefaultMaker("functionplot");
new CaluMath.PM.PageMakerDefaultMaker("arcplot");
new CaluMath.PM.PageMakerDefaultMaker("labelvertex");
new CaluMath.PM.PageMakerDefaultMaker("labelallvertices");
new CaluMath.PM.PageMakerDefaultMaker("tangent");
new CaluMath.PM.PageMakerDefaultMaker("highlight");
new CaluMath.PM.PageMakerDefaultMaker("pointplot");
new CaluMath.PM.PageMakerDefaultMaker("linearplot");
new CaluMath.PM.PageMakerDefaultMaker("addlinearplotsegment");
new CaluMath.PM.PageMakerDefaultMaker("textplot");
new CaluMath.PM.PageMakerDefaultMaker("movetextplot");
new CaluMath.PM.PageMakerDefaultMaker("labelplot");
//new CaluMath.PM.PageMakerDefaultMaker("standardbutton");
new CaluMath.PM.PageMakerDefaultMaker("linebreak");
new CaluMath.PM.PageMakerDefaultMaker("removegraph");
new CaluMath.PM.PageMakerDefaultMaker("removehtml");
new CaluMath.PM.PageMakerDefaultMaker("nameclickedpoint");
new CaluMath.PM.PageMakerDefaultMaker("comparison");
new CaluMath.PM.PageMakerDefaultMaker("conditional");
new CaluMath.PM.PageMakerDefaultMaker("addtoconditional");
new CaluMath.PM.PageMakerDefaultMaker("routine");
new CaluMath.PM.PageMakerDefaultMaker("addtoroutine");
new CaluMath.PM.PageMakerDefaultMaker("executeroutine");
new CaluMath.PM.PageMakerDefaultMaker("cm_alert");
new CaluMath.PM.PageMakerDefaultMaker("focusobject");
new CaluMath.PM.PageMakerDefaultMaker("link");
new CaluMath.PM.PageMakerDefaultMaker("image");
new CaluMath.PM.PageMakerDefaultMaker("functiontable");
new CaluMath.PM.PageMakerDefaultMaker("table");
new CaluMath.PM.PageMakerDefaultMaker("tablefromdata");
new CaluMath.PM.PageMakerDefaultMaker("discretefunctionconstructiontable");
new CaluMath.PM.PageMakerDefaultMaker("tablerow");
new CaluMath.PM.PageMakerDefaultMaker("tablecell");
new CaluMath.PM.PageMakerDefaultMaker("inserttablecolumn");
new CaluMath.PM.PageMakerDefaultMaker("inserttablerow");
new CaluMath.PM.PageMakerDefaultMaker("deletetablecolumn");
new CaluMath.PM.PageMakerDefaultMaker("deletetablerow");
new CaluMath.PM.PageMakerDefaultMaker("iframecontainer");

new CaluMath.PM.PageMakerDefaultMaker("list");
new CaluMath.PM.PageMakerDefaultMaker("listitem");
new CaluMath.PM.PageMakerDefaultMaker("insertlistitem");
new CaluMath.PM.PageMakerDefaultMaker("deletelistitem");


new CaluMath.PM.PageMakerDefaultMaker("coordinates");
new CaluMath.PM.PageMakerDefaultMaker("webpagename");

new CaluMath.PM.PageMakerDefaultMaker("arrow");
new CaluMath.PM.PageMakerDefaultMaker("bracket");
new CaluMath.PM.PageMakerDefaultMaker("pointbrackets3");
new CaluMath.PM.PageMakerDefaultMaker("pointbrackets2");
new CaluMath.PM.PageMakerDefaultMaker("pointbrackets1");
new CaluMath.PM.PageMakerDefaultMaker("splitfunction");
new CaluMath.PM.PageMakerDefaultMaker("discretefunctionplot");
new CaluMath.PM.PageMakerDefaultMaker("discretefunctionfrompointsarray");
new CaluMath.PM.PageMakerDefaultMaker("animationplot");
new CaluMath.PM.PageMakerDefaultMaker("startbutton");
new CaluMath.PM.PageMakerDefaultMaker("stopbutton");
new CaluMath.PM.PageMakerDefaultMaker("resetbutton");
new CaluMath.PM.PageMakerDefaultMaker("stepbutton");
new CaluMath.PM.PageMakerDefaultMaker("changedirectionbutton");
new CaluMath.PM.PageMakerDefaultMaker("allanimationbutton");
new CaluMath.PM.PageMakerDefaultMaker("increasespeedbutton");
new CaluMath.PM.PageMakerDefaultMaker("decreasespeedbutton");
new CaluMath.PM.PageMakerDefaultMaker("animationoutput");
new CaluMath.PM.PageMakerDefaultMaker("compositeanimation");

new CaluMath.PM.PageMakerDefaultMaker("tangentclickbutton");
new CaluMath.PM.PageMakerDefaultMaker("highlightclickbutton");
new CaluMath.PM.PageMakerDefaultMaker("pointclickbutton");
new CaluMath.PM.PageMakerDefaultMaker("removeclickbutton");
new CaluMath.PM.PageMakerDefaultMaker("endremoveclickbutton");
new CaluMath.PM.PageMakerDefaultMaker("calculatorbutton");
new CaluMath.PM.PageMakerDefaultMaker("javascriptbutton");
new CaluMath.PM.PageMakerDefaultMaker("enterbutton");
new CaluMath.PM.PageMakerDefaultMaker("input");
new CaluMath.PM.PageMakerDefaultMaker("output");
new CaluMath.PM.PageMakerDefaultMaker("select");
new CaluMath.PM.PageMakerDefaultMaker("buttonaction");
new CaluMath.PM.PageMakerDefaultMaker("forloop");
new CaluMath.PM.PageMakerDefaultMaker("addtoforloop");
new CaluMath.PM.PageMakerDefaultMaker("newwindow");
new CaluMath.PM.PageMakerDefaultMaker("inputtext");
new CaluMath.PM.PageMakerDefaultMaker("inputarea");
new CaluMath.PM.PageMakerDefaultMaker("button");
new CaluMath.PM.PageMakerDefaultMaker("clickbutton");
new CaluMath.PM.PageMakerDefaultMaker("boxes");
new CaluMath.PM.PageMakerDefaultMaker("dropdownmenu");
new CaluMath.PM.PageMakerDefaultMaker("addtoboxordropdown");
new CaluMath.PM.PageMakerDefaultMaker("addtobuttonaction");
new CaluMath.PM.PageMakerDefaultMaker("addtonewwindow");
new CaluMath.PM.PageMakerDefaultMaker("iframe");
new CaluMath.PM.PageMakerDefaultMaker("changelinks");
new CaluMath.PM.PageMakerDefaultMaker("changeimages");
new CaluMath.PM.PageMakerDefaultMaker("buttonactionnext");
new CaluMath.PM.PageMakerDefaultMaker("hideandunhide");
new CaluMath.PM.PageMakerDefaultMaker("hideandunhidegraph");
new CaluMath.PM.PageMakerDefaultMaker("gettextboxvalue");
new CaluMath.PM.PageMakerDefaultMaker("puttextboxvalue");
new CaluMath.PM.PageMakerDefaultMaker("getboxindex");
new CaluMath.PM.PageMakerDefaultMaker("putboxindex");
new CaluMath.PM.PageMakerDefaultMaker("search");
new CaluMath.PM.PageMakerDefaultMaker("putfocus");
new CaluMath.PM.PageMakerDefaultMaker("javascript");
new CaluMath.PM.PageMakerDefaultMaker("textstylesheet");
new CaluMath.PM.PageMakerDefaultMaker("endinsertionarray");

new CaluMath.PM.PageMakerDefaultMaker("changebuttontype");
//new CaluMath.PM.PageMakerDefaultMaker("moveobject");
new CaluMath.PM.PageMakerDefaultMaker("importpage");
new CaluMath.PM.PageMakerDefaultMaker("comment");
new CaluMath.PM.PageMakerDefaultMaker("addhtml");
new CaluMath.PM.PageMakerDefaultMaker("headhtml");
new CaluMath.PM.PageMakerDefaultMaker("htmltext");
new CaluMath.PM.PageMakerDefaultMaker("clipboard");
new CaluMath.PM.PageMakerDefaultMaker("clipboardplaceholder");

new CaluMath.PM.PageMakerDefaultMaker("activatedragpoint");
new CaluMath.PM.PageMakerDefaultMaker("activatecapturedragpath");
new CaluMath.PM.PageMakerDefaultMaker("deactivatecapturedragpath");
new CaluMath.PM.PageMakerDefaultMaker("deactivatedragpoint");
new CaluMath.PM.PageMakerDefaultMaker("namedraggedvalue");
new CaluMath.PM.PageMakerDefaultMaker("dragroutine");
new CaluMath.PM.PageMakerDefaultMaker("slidingscale");
new CaluMath.PM.PageMakerDefaultMaker("activateslidingscale");
new CaluMath.PM.PageMakerDefaultMaker("deactivateslidingscale");

new CaluMath.PM.PageMakerDefaultMaker("deactivateclickableaxes");

new CaluMath.PM.PageMakerDefaultMaker("nameanimationvalue");
new CaluMath.PM.PageMakerDefaultMaker("animationroutine");

new CaluMath.PM.PageMakerDefaultMaker("updatablefunctionplot");
new CaluMath.PM.PageMakerDefaultMaker("updatefunctionplot");
new CaluMath.PM.PageMakerDefaultMaker("updatetangentplot");
new CaluMath.PM.PageMakerDefaultMaker("updateblanksegments");
new CaluMath.PM.PageMakerDefaultMaker("movepoint");

new CaluMath.PM.PageMakerDefaultMaker("activatedragrectangle");
new CaluMath.PM.PageMakerDefaultMaker("deactivatedragrectangle");
new CaluMath.PM.PageMakerDefaultMaker("activatestretchrectangle");
new CaluMath.PM.PageMakerDefaultMaker("deactivatestretchrectangle");
new CaluMath.PM.PageMakerDefaultMaker("activateviewrectangle");
new CaluMath.PM.PageMakerDefaultMaker("deactivateviewrectangle");
new CaluMath.PM.PageMakerDefaultMaker("rectangleplot");
new CaluMath.PM.PageMakerDefaultMaker("moverectangle");
new CaluMath.PM.PageMakerDefaultMaker("updateareabetweenfunctionsplot");


CaluMath.PM.ClipBoard= CaluMath.PM.PageMakerObject("clipboard");
CaluMath.PM.ClipBoard.childarray=[CaluMath.PM.PageMakerObject("clipboardplaceholder")];
CaluMath.PM.ClipBoard.childarray[0].parent=CaluMath.PM.ClipBoard;

};

if(window.CM_TopWindow != window){ 
   CaluMath.PM.PageMakerhtmltextDefault= CM_TopWindow.CaluMath.PM.PageMakerhtmltextDefault;
};


CaluMath.PM.HelpLinkonclickFunction= function(){
   if(window.CM_CurrentHelpWindow != null && CaluMath.PM.CurrentHelpWindow.open){
      CaluMath.PM.CurrentHelpWindow.close();
   };

   CaluMath.PM.CurrentHelpWindow=window.open(this.getAttribute("href"), "CM_HelpWindow","width="+Math.round((3/4)*window.screen.width) +",height="+Math.round((2/3)*window.screen.height)+",scrollbars=yes, resizable=yes"); 
   CaluMath.PM.CurrentHelpWindow.moveTo(Math.round((1/6)*window.screen.width),Math.round((1/8)*window.screen.height)); 
   CaluMath.PM.CurrentHelpWindow.focus();
   return false;
};


//COMMENT: SECTION DEALING WITH MAKING OPTIONS IN TABLES WITH CaluMath.PM.MAKEOPTIONS

CaluMath.PM.StatusOnMouseOverFunction= function(){
   defaultStatus=this.cm_tempmessage;
   return true;
};

CaluMath.PM.StatusOnMouseOutFunction= function(){
   defaultStatus=''; 
   return true;
};

CaluMath.PM.MakeTableCaption=function(){
   //Comment: This puts the captions (labels) for each or the required or options elements in the Table. This is also used in CaluMath.PM.UpdateIndividualOption.
   var temparray= arguments[0];
   var tempspan=arguments[1];
 
   if(temparray[4].cm_constructorname=="String"){
       var temptext= document.createTextNode(temparray[4]);
   }
   else{
       if(temparray[4][0].cm_constructorname=="String"){
          var temptext= document.createTextNode(temparray[4][0]);
       }
       else{
          var temptext= document.createElement("a")
          temptext.setAttribute("href", temparray[4][0][1]);
          temptext.setAttribute("target", "helpwindow");
          var linktext= document.createTextNode(temparray[4][0][0]);
          temptext.appendChild(linktext);
          temptext.onclick=CaluMath.PM.HelpLinkonclickFunction;
       };
 
       if(temparray[4][1]!= null && CaluMath.PM.UseTitles){
          tempspan.setAttribute("title", temparray[4][1]);
       }
       if(temparray[4][2]!= null && CaluMath.PM.UseStatus){
          if(temparray[4][2]=="same"){
             var tempmessage=temparray[4][1]; 
             tempspan.cm_tempmessage=tempmessage; 
             tempspan.onmouseover=CaluMath.PM.StatusOnMouseOverFunction;
             tempspan.onmouseout=CaluMath.PM.StatusOnMouseOutFunction;
          }
          else{
             var tempmessage=temparray[4][2]; 
             tempspan.cm_tempmessage=tempmessage; 
             tempspan.onmouseover=CaluMath.PM.StatusOnMouseOverFunction;
             tempspan.onmouseout=CaluMath.PM.StatusOnMouseOutFunction;
          };
       };
   };
   return temptext;
};





CaluMath.PM.MakeOptions= function(){
/*
//Comment: CaluMath.PM.PageMakernewplotDefault, CaluMath.PM.PageMakernewplotDefault, etc. are objects that provide information about the input tables and default values that are to be constructed to make CaluMath.PM.NewPlot and CaluMath.PM.functionplot. So far, (but this could change) there are required tables and option tables. The required table has entries that are required. The arguments for CaluMath.PM.MakeOptions are an object like CaluMath.PM.PageMakernewplotDefault and a type of table, like options or required. Before this function can be called, an array which is the optionsarray or requiredarray property object of the object must already exist. As of now, the form of the array is [argument[0]: "the actual option property that CaluMath.PM.Math understands for the option (such as xlabelfactor or fontsize), argument[1]: whether the table entry corresponding to this is a drop-down menu or a text input, argument[2]: in the former case, the third entry is an array of values for the drop down menu. In the latter case it is the size of the text box. argument[3]: the default value (or "") for a text box with no default value. argument[4]: The text label of the input. This label should make sense to the user. argument[5]: this optional entry is the function that checks whether the input is valid or not. Current examples are CaluMath.PM.IsNumber, CaluMath.PM.IsEvalMath, and CaluMath.PM.IsNonEmptyString. These values return either true or false and will not cause an error for any string input. Since they are applied only to the input in a textbox (where the user could put inappropriate entries), which is always a string, they will never yield errors.   

//Comment: The function CaluMath.PM.MakeOptions has an optional third argument, which is the number of columns in the table that is constructed. 

//Comment: The arguments are (tempobject, type (either "options" or "required"), and optional number of columns). The function creates tempobject[type], meaning tempobject.required or tempobject.options. It creates tempobject[type].table, which is the table that contains the inputs for the user for the type of fields (option fields or required fields). It looks through each entry in tempobject[type+"array"] (which must, as stated above, be constructed before the function is called), and constructs an object in  tempobject[type] for each option or required property. It constructs a drop down menu or text box (input) for each item and puts in the default value. For that object, it also construct the array property, which is the array in tempobject[type+"array"] that cooresponds to the information concerning that option or required property. 

//Comment: An example is CaluMath.PM.MakeOptions(CaluMath.PM.PageMakernewplotDefault, "options",5). It creates the object CaluMath.PM.PageMakernewplotDefault.options and  takes the array CaluMath.PM.PageMakernewplotDefault.optionsarray, which is an array consisting of arrays, and looks at the first entry of each array, for example "fontsize". It creates the object CaluMath.PM.PageMakernewplotDefault.options.fontsize and sets CaluMath.PM.PageMakerObjetPlot.options.fontsize.defaultvalue=16. It sets CaluMath.PM.PageMakerObjetPlot.options.fontsize.array to be [fontsize,menu,6,8,10,11,12,14,16,18,20,22,24,26,28,30,32,34,36,40,44,48,52,16,Font Size], which is the entry of CaluMath.PM.PageMakernewplotDefault.optionsarray corresponding to "fontsize". It creates the table CaluMath.PM.PageMakernewplotDefault.options.table which contains all the inputs for the options. It associates the HTML drop down menu with CaluMath.PM.PageMakernewplotDefault.options.fontsize.menu, so we can access the user input. If the entry corresponds to a text box, it associates the text box CaluMath.PM.PageMakernewplotDefault.options.xstart.input, (for example) to the property "xstart". 
*/

   var tempobject= arguments[0];
   var type=arguments[1];
   var numberofcolumns = arguments[2];
   if(numberofcolumns ==null){
      var numberofcolumns = tempobject.cm_numberofcolumns;
   };
   if(numberofcolumns ==null){
      numberofcolumns=5;
   };
   if(tempobject.settingsnames==null){
      tempobject.settingsnames=new Array();
   };
   var temparray= tempobject["make"+type+"array"](); 

   if(type == "options" && CaluMath.PM.CurrentOnlyForListMenu != null){
      CaluMath.PM.CurrentOnlyForListMenu.onchange=null;
   };

   if(tempobject[type] != null && tempobject[type].table != null && tempobject.type != "conditional" && !CM_TopWindow.CM_EditMode){  
      tempobject[type].table.parentNode.removeChild(tempobject[type].table);
      
   }
   else{
      tempobject[type]=new Object();
   };
   var tempobjectoptions=tempobject[type]; 
   var temparraylength= temparray.length;

   var temptable= document.createElement("table");
   temptable.setAttribute("border", "1");
   temptable.setAttribute("cellspacing", "1");
   var tempbody= document.createElement("tbody");
   tempbody.style.backgroundColor="#b1946c";   //"#F0F0F0";
   document.getElementById("displayleft").appendChild(temptable);

   temptable.appendChild(tempbody);
   tempobject[type].table= temptable;
   temptable.style.display="none";
  
   var numberofrows= 3*Math.ceil(temparraylength/numberofcolumns);
   var rows=new Array();

   for(var j=0; j< numberofrows; j++){
      rows[j]=document.createElement("tr");
      tempbody.appendChild(rows[j]);
   };


   var temptablearray= new Array();
   for(var j=0; j< numberofrows; j++){
      temptablearray[j]=new Array();
      if(j%3 !=2){
         for(var t=0; t<2*numberofcolumns; t++){
            temptablearray[j][t]=document.createElement("td");
            if(t%2 ==1){
               temptablearray[j][t].style.width="30px";
            };  
            temptablearray[j][t].style.textAlign="center";
            rows[j].appendChild(temptablearray[j][t]);
         };
      }
      else{
         for(var t=0; t<2*numberofcolumns; t++){
            temptablearray[j][t]=document.createElement("td");
            temptablearray[j][t].style.height="20px";
            if(t%2 ==1){
               temptablearray[j][t].style.width="30px";
            };  
            temptablearray[j][t].style.textAlign="center";
            rows[j].appendChild(temptablearray[j][t]);
         };
      };
   };


   for(var i=0; i<temparraylength; i++){  
      if(!tempobject.settingsnames.cm_contains(temparray[i][0])){ 
         tempobject.settingsnames=tempobject.settingsnames.concat(temparray[i][0]);
      };
      tempobjectoptions[temparray[i][0]] = new Object();
      tempobjectoptions[temparray[i][0]].type = temparray[i][1];
      tempobjectoptions[temparray[i][0]].array = temparray[i];
      if(tempobjectoptions[temparray[i][0]].type == "menu"){
         tempobjectoptions[temparray[i][0]].menu= document.createElement("select"); 
         if(temparray[i][2].cm_constructorname=="Array"){
            CaluMath.PM.MakeSelectMenu(tempobjectoptions[temparray[i][0]].menu,temparray[i][2]);
            CaluMath.PM.MakeDefaultOption(tempobjectoptions[temparray[i][0]].menu,temparray[i][3]);
            if( temparray[i][0]=="cm_onlyforlists"){
               CaluMath.PM.CurrentOnlyForListMenu=tempobjectoptions[temparray[i][0]].menu; 

               tempobjectoptions[temparray[i][0]].menu.onchange=function(){
                  alert("Use Only For Lists is an Advanced Technique that has to do with Programming and CaluMath. Only select yes if you know what you are doing.");
                  this.selectedIndex=0;
                  this.onchange=null;
               };
               CaluMath.Html.MemoryLeakArray.push(tempobjectoptions[temparray[i][0]].menu);

            };
         }
         else if(temparray[i][2].cm_constructorname=="String"){
            if(!temparray[i][2].match(/\,concat\,/)){
               if(temparray[i][3].replace(/\s*/g,"").length >0 ){
                  if(CaluMath.PM.PlotlistObject[temparray[i][3].replace(/\s*/g,"")][0] != null){
                     CaluMath.PM.MakeSelectMenu(tempobjectoptions[temparray[i][0]].menu,CaluMath.PM.PlotlistObject[CaluMath.PM.PlotlistObject[temparray[i][3].replace(/\s*/g,"")][0][0]][temparray[i][2].replace(/\s*/g,"")]);
                  }
                  else if(CaluMath.PM.PlotlistObject[temparray[i][3].replace(/\s*/g,"")][0] == null && temparray[i][3].replace(/\s*/g,"")=="newplotlist" ){
                     CaluMath.PM.MakeSelectMenu(tempobjectoptions[temparray[i][0]].menu,CaluMath.PM.PlotlistObject["CM_ParentObject"][temparray[i][2].replace(/\s*/g,"")]);
                  }
               }
               else{
                  CaluMath.PM.MakeSelectMenu(tempobjectoptions[temparray[i][0]].menu,CaluMath.PM.PlotlistObject[temparray[i][2].replace(/\s*/g,"")]);
               }
            }
            else{
               var forconcatenation= temparray[i][2].split(/\,concat\,/);
               if(temparray[i][3].replace(/\s*/g,"").length >0){
                  if(CaluMath.PM.PlotlistObject[temparray[i][3].replace(/\s*/g,"")] != null && CaluMath.PM.PlotlistObject[temparray[i][3].replace(/\s*/g,"")][0] != null && CaluMath.PM.PlotlistObject[temparray[i][3].replace(/\s*/g,"")][0][0] != null && CaluMath.PM.PlotlistObject[CaluMath.PM.PlotlistObject[temparray[i][3].replace(/\s*/g,"")][0][0]][forconcatenation[1].replace(/\s*/g,"")] != null){
                     CaluMath.PM.MakeSelectMenu(tempobjectoptions[temparray[i][0]].menu,eval(forconcatenation[0]).concat(CaluMath.PM.PlotlistObject[CaluMath.PM.PlotlistObject[temparray[i][3].replace(/\s*/g,"")][0][0]][forconcatenation[1].replace(/\s*/g,"")]));
                  }
                  else{
                      CaluMath.PM.MakeSelectMenu(tempobjectoptions[temparray[i][0]].menu,eval(forconcatenation[0]));
                  };
               }
               else if(CaluMath.PM.PlotlistObject[forconcatenation[1].replace(/\s*/g,"")] != null){
                   CaluMath.PM.MakeSelectMenu(tempobjectoptions[temparray[i][0]].menu,eval(forconcatenation[0]).concat(CaluMath.PM.PlotlistObject[forconcatenation[1].replace(/\s*/g,"")]));
               }
               else{
                   CaluMath.PM.MakeSelectMenu(tempobjectoptions[temparray[i][0]].menu,eval(forconcatenation[0]));
               };
            }
         }
         else{
            return alert("There is a problem. Your entry in CaluMath.PM.PageMaker"+tempobject.type+"Default should be either an Array or a string name for the type of list you want displayed as an option for "+temparray[i][0]+".");
         }
         CaluMath.PM.MakeDefaultOption(tempobjectoptions[temparray[i][0]].menu,temparray[i][3]);

         tempobjectoptions[temparray[i][0]].defaultvalue=temparray[i][3];
         var tempspan= document.createElement("span");
         tempspan.style.fontSize="16px";
         var temptext= CaluMath.PM.MakeTableCaption(temparray[i],tempspan); 
         tempspan.appendChild(temptext); 
         tempobjectoptions[temparray[i][0]].caption= temptext; 
         temptablearray[3*Math.floor(i/numberofcolumns)+1][2*(i%numberofcolumns)].appendChild(tempobjectoptions[temparray[i][0]].menu);
         temptablearray[3*Math.floor(i/numberofcolumns)][2*(i%numberofcolumns)].appendChild(tempspan);
      }
      else if (tempobjectoptions[temparray[i][0]].type == "input"){
         tempobjectoptions[temparray[i][0]].input= document.createElement("input");

         if(!((tempobject.type== "link" || tempobject.type== "image" || tempobject.type== "changeimages" || tempobject.type== "changelinks" || tempobject.type== "importpage") && temparray[i][0] == "address")){
            tempobjectoptions[temparray[i][0]].input.setAttribute("type", "text");
            tempobjectoptions[temparray[i][0]].input.value=temparray[i][3];
         }
         else{
            try{
               tempobjectoptions[temparray[i][0]].input.setAttribute("type", "file");
            }
            catch(e){ //CaluMath.Html.NullFunction();
               try{
                  tempobjectoptions[temparray[i][0]].input= document.getElementById("loadfile").cloneNode(true);
                  tempobjectoptions[temparray[i][0]].input.style.display='';
                  document.body.appendChild(tempobjectoptions[temparray[i][0]].input);
               }
               catch(e){ //CaluMath.Html.NullFunction();
               };
            };
         };

         tempobjectoptions[temparray[i][0]].input.setAttribute("size", temparray[i][2]);
         tempobjectoptions[temparray[i][0]].defaultvalue=temparray[i][3];
         var tempspan= document.createElement("span");
         tempspan.style.fontSize="16px";
         var temptext= CaluMath.PM.MakeTableCaption(temparray[i],tempspan); 
         tempspan.appendChild(temptext);
         tempobjectoptions[temparray[i][0]].caption= temptext; 
         temptablearray[3*Math.floor(i/numberofcolumns)+1][2*(i%numberofcolumns)].appendChild(tempobjectoptions[temparray[i][0]].input);
         temptablearray[3*Math.floor(i/numberofcolumns)][2*(i%numberofcolumns)].appendChild(tempspan);
      };
   };
};

CaluMath.PM.UpdateIndividualOption= function(){
   var tempobject= arguments[0];
   var type=arguments[1];
   var temparray= arguments[2];
   var tempobjectoptions=tempobject[type];
   if(temparray[1]=="menu"){
     if(tempobjectoptions[temparray[0]] != null && tempobjectoptions[temparray[0]].menu != null){
         oldmenu=tempobjectoptions[temparray[0]].menu;
     }
     else if(tempobjectoptions[temparray[0]] != null && tempobjectoptions[temparray[0]].input!= null){
         oldmenu=tempobjectoptions[temparray[0]].input;
     }
     else{
alerttest("Undefined in UpdateIndividualOption, so we are exiting:"+arguments[0]+" , "+arguments[1]+", "+arguments[2]);
        return   ;
     }
     tempobjectoptions[temparray[0]].menu= document.createElement("select"); 
     oldmenu.parentNode.replaceChild(tempobjectoptions[temparray[0]].menu,oldmenu);
     oldcaption=tempobjectoptions[temparray[0]].caption;

      tempobjectoptions[temparray[0]].caption= CaluMath.PM.MakeTableCaption(temparray,tempobjectoptions[temparray[0]].caption.parentNode);
     oldcaption.parentNode.replaceChild(tempobjectoptions[temparray[0]].caption,oldcaption);
     CaluMath.PM.MakeSelectMenu(tempobjectoptions[temparray[0]].menu,temparray[2]);
     CaluMath.PM.MakeDefaultOption(tempobjectoptions[temparray[0]].menu,temparray[3]);
     tempobjectoptions[temparray[0]].defaultvalue=temparray[3];
     tempobjectoptions[temparray[0]].array=temparray;
   }
   else if(temparray[1]=="input"){
      if(tempobjectoptions[temparray[0]].menu != null){
          oldinput=tempobjectoptions[temparray[0]].menu;
      }
      else if(tempobjectoptions[temparray[0]].input!= null){
         oldinput=tempobjectoptions[temparray[0]].input;
      };
      tempobjectoptions[temparray[0]].input= document.createElement("input");
      tempobjectoptions[temparray[0]].input.setAttribute("type", "text");
      tempobjectoptions[temparray[0]].input.setAttribute("size", temparray[2]);
      tempobjectoptions[temparray[0]].input.value=temparray[3];
      tempobjectoptions[temparray[0]].defaultvalue=temparray[3];
      oldinput.parentNode.replaceChild(tempobjectoptions[temparray[0]].input,oldinput);
      oldcaption=tempobjectoptions[temparray[0]].caption;
      tempobjectoptions[temparray[0]].caption= CaluMath.PM.MakeTableCaption(temparray,tempobjectoptions[temparray[0]].caption.parentNode);
      oldcaption.parentNode.replaceChild(tempobjectoptions[temparray[0]].caption,oldcaption);
   };
};
 
//COMMENT: ABOVE IS END OF SECTION DEALING WITH MAKING OPTIONS IN TABLES WITH CaluMath.PM.MAKEOPTIONS


//Comment: All objects are created in the main window. However the settings array for an object is not if it is created in a secdary window (the only case of this is for text objects). Therefore we must make a copy of the settings array. The copy is an array in CM_TopWindow. This is then assigned the settings property of the object. 
CaluMath.PM.CopyArray=function(){
   var oldarray=arguments[0];
   var oldarraylength=oldarray.length;

   if(CM_TopWindow==window){
      return oldarray;
   }
   else{
     var newarray= CM_TopWindow.Array();
     for(var i=0; i<oldarraylength; i++){
        if(oldarray[i].cm_constructorname != "Array"){
           newarray[i]=oldarray[i];
        }
        else{
           newarray[i]=CM_TopWindow.Array(oldarray[i][0],oldarray[i][1]);
        };
     };
     return newarray;
   };
};

//Comment: This makes visible input and output boxes to allow interactive JavaScript code to be evaluated. //
if(CM_TopWindow==window){

CaluMath.Html.MakeJavaScriptEvaluationMenuVisible = function(){
   if(window.CM_TopWindow==null){ alert("window.CM_TopWindow==null"); return};
      if(CM_TopWindow.window.event != null){ 
         if(CM_TopWindow.window.event.keyCode==26 && CM_TopWindow.window.event.ctrlKey && event.shiftKey){ 
            document.getElementById("inputandoutputcontainer").style.display="";
            document.getElementById("input").focus();
            window.scrollBy(0,50);
         }
         else if(CM_TopWindow.window.event.keyCode==26 && CM_TopWindow.window.event.ctrlKey){ 
            CaluMath.PM.DisplayPageControls(); 
         };
         CM_TopWindow.document.onkeypress=CaluMath.Html.MakeJavaScriptEvaluationMenuInVisible;
      }
      else{
         if(arguments[0].charCode ==90 && arguments[0].ctrlKey && arguments[0].shiftKey){ // && arguments[0].shiftKey){
            document.getElementById("inputandoutputcontainer").style.display="";
            document.getElementById("input").focus();
            window.scrollBy(0,50);
         };
         if(arguments[0].charCode ==122 && arguments[0].ctrlKey){
            CaluMath.PM.DisplayPageControls(); 
         };
         CM_TopWindow.document.onkeypress=CaluMath.Html.MakeJavaScriptEvaluationMenuInVisible;
      };
};

CaluMath.Html.MakeJavaScriptEvaluationMenuInVisible = function(){
   if(window.CM_TopWindow==null){ alert("window.CM_TopWindow==null"); return};
      if(CM_TopWindow.window.event != null){ 
         if(CM_TopWindow.window.event.keyCode==26 && CM_TopWindow.window.event.ctrlKey && event.shiftKey){ 
            document.getElementById("inputandoutputcontainer").style.display="none";
         }
         else if(CM_TopWindow.window.event.keyCode==26 && CM_TopWindow.window.event.ctrlKey){ 
            CaluMath.PM.DisplayPageControls(); 
         };
         CM_TopWindow.document.onkeypress=CaluMath.Html.MakeJavaScriptEvaluationMenuVisible;
      }
      else{
         if(arguments[0].charCode ==90 && arguments[0].ctrlKey && arguments[0].shiftKey){ // && arguments[0].shiftKey){
            document.getElementById("inputandoutputcontainer").style.display="none";
         };
         if(arguments[0].charCode ==122 && arguments[0].ctrlKey){
            CaluMath.PM.DisplayPageControls(); 
         };
         CM_TopWindow.document.onkeypress=CaluMath.Html.MakeJavaScriptEvaluationMenuVisible;
      };
};

CM_TopWindow.document.onkeypress=CaluMath.Html.MakeJavaScriptEvaluationMenuVisible;

/*
   CM_TopWindow.document.onkeypress=function(){ 
   if(window.CM_TopWindow==null){ alert("window.CM_TopWindow==null"); return};
      if(CM_TopWindow.window.event != null){ 
         if(CM_TopWindow.window.event.keyCode==26 && CM_TopWindow.window.event.ctrlKey && event.shiftKey){ 
            document.getElementById("inputandoutputcontainer").style.display="block";
         }
         else if(CM_TopWindow.window.event.keyCode==26 && CM_TopWindow.window.event.ctrlKey){ 
            CaluMath.PM.DisplayPageControls(); 
         };
      }
      else{
         if(arguments[0].charCode ==90 && arguments[0].ctrlKey && arguments[0].shiftKey){ // && arguments[0].shiftKey){
            document.getElementById("inputandoutputcontainer").style.display="block";
         };
         if(arguments[0].charCode ==122 && arguments[0].ctrlKey){
            CaluMath.PM.DisplayPageControls(); 
         };
      };
   };
*/

};




cm_onunload=function(){
   var temparray=document.getElementsByTagName("input");
   var temparraylength=temparray.length;
   for(var i=0; i<temparraylength; i++){
      temparray[i].onclick=null;
   };
   var temparray=document.getElementsByTagName("a");
   var temparraylength=temparray.length;
   for(var i=0; i<temparraylength; i++){
      temparray[i].onclick=null;
   };
   CM_EditMode=null; CaluMath.PM.InEditMode=null; CaluMath.PM.InsertInto=null; CaluMath.PM.InsertIntoIndex=null; cm_readytodocm_onload=null; CM_InsertCanceled=null; finishinsertbuttonElement=null; cancelinsertbuttonElement=null;
   CaluMath.PM.TEXTTEMPINSERTWINDOW=null;

};


