// Public Browser OS code -- can be called by the developer's javascript.  Developer must create
// an object which contains the following member variables.  Either the OS.control or OS.callBack
// parameter must be defined.

function doDynamicOS(userContext, OS)
{
   //make sure we have an entry for the required parameters
   if ( (OS.control!=null || OS.callBack!=null) )  //do we have a control or callback to handle results
   {
      //make sure we at least have default values for all parameters
      if (OS.control==null)                     OS.control="";
      if (OS.callBack==null)                    OS.callBack="";
      if (OS.advancedSelection==null)           OS.advancedSelection="";
      if (OS.advSelCriteria==null)              OS.advSelCriteria="";
      if (OS.advSelCriteriaCallBack==null)      OS.advSelCriteriaCallBack="";
      if (OS.initialContext==null)              OS.initialContext="";
      if (OS.isOSAllowed==null)                 OS.isOSAllowed="";
      if (OS.mode==null)                        OS.mode="";
      if (OS.multiSelect==null)                 OS.multiSelect="";
      if (OS.nameFilter==null)                  OS.nameFilter="";
      if (OS.resultsPerPage==null)              OS.resultsPerPage="";
      if (OS.searchSubContainers==null)         OS.searchSubContainers="";
      if (OS.searchOnStartup==null)             OS.searchOnStartup="";
      if (OS.showSubClasses==null)              OS.showSubClasses=="";
      if (OS.typeFilter==null)                  OS.typeFilter="";
      if (OS.typeFilterCallBack==null)          OS.typeFilterCallBack="";

      //is window being sized dynamically?
      if (OS.windowWidth!=null)                 window.osWidth=OS.windowWidth;
      if (OS.windowHeight!=null)                window.osHeight=OS.windowHeight;

      //are the widths of the input well being sized dynamically?
      if (OS.queryColumnWidth!=null)            window.osQueryColumnWidth=OS.queryColumnWidth;

      //call the private doOS routine
      doOS(userContext,
           OS.control,
           OS.callBack,

           OS.advancedSelection,
           OS.advSelCriteria,
           OS.advSelCriteriaCallBack,
           OS.initialContext,
           OS.isOSAllowed,
           OS.mode,
           OS.multiSelect,
           OS.nameFilter,
           OS.resultsPerPage,
           OS.searchSubContainers,
           OS.searchOnStartup,
           OS.showSubClasses,
           OS.typeFilter,
           OS.typeFilterCallBack);
   }
}


// Private Browser OS code -- not intended for eMFrame developer use.
// These apis are not public and are subject to change without notice.

function doOS( userContext,            // user session context info
               controlName,            // name of HTML control that will receive results
               callBack,               // routine to process selected results

               advSel,                 // opt - false (default) name-search only, true advanced selection criterion
               advSelCriteria,         // opt - list of XML advanced selection criteria
               advSelCriteriaCallBack, // opt - routine to return list of XML advanced selection criteria
               initialContext,         // opt - initial container to search from ([root] default)
               isOSAllowed,            // opt - routine to determine if OS should run at all
               mode,                   // opt - search (default)or browse
               multiSelect,            // opt - false (default) single select, true multi-select
               nameFilter,             // opt - initial name filter (* default)
               resultsPerPage,         // opt - number of objects to display at a time
               searchSubContainers,    // opt - true (default) search subcontainers, false find objects in only the specified container
               searchOnStartup,        // opt - false (default) wait for user to click search button,
                                       //       true, search container on startup
               showSubClasses,         // opt - true - base and derived classes found, false (default) - only base class found
               typeFilter,             // opt - type filter (all default)
               typeFilterCallBack)     // opt - routine to return type filter
{
   // if in debug mode, make sure OSFooter.inc has been included in the task
   if (fw_isDebugEnabled && document.getElementById("OSExchangerFrame")==null)
   {
      var msg = "Developer Alert:  No OSFooter detected on this page.\n\n"+
                "You must include the file 'dev\OSFooter_inc.jsp' once after the last </form> tag\n"+
                "on any page that includes an Object Selector button.\n\n"+
                "Sample code snipits:\n"+
                "   jsp conduit:\t<jsp:include page='\<\%= c.getPath(\"dev/OSFooter_inc.jsp\") \%\>' flush=\"true\"/>\n"+
                "   iman tag library:\t<iman:osFooter/>\n"+
                "   xsl (deprecated):\t<xsl:call-template name=\"OSFooter\"/>";
      alert(msg);
   }
   
   if (controlName==null)           controlName="";
   if (callBack==null)              callBack="";

   var doOS=true;   //assume we will be running the object selector
   if (exists(isOSAllowed))
   {
      //execute specified routine to determine if search should proceed
      doOS=eval(isOSAllowed+"('"+toScript(controlName)+"')");
   }

   if (doOS)
   {
      //retrieve type filter from type filter callback, if a callback is specified
      if (exists(typeFilterCallBack))
      {
         typeFilter=eval(typeFilterCallBack+"('"+toScript(controlName)+"')");
      }
      
      //retrieve advanced selection criteria from advanced selection criteria callback, if a callback is specified
      if (exists(advSelCriteriaCallBack))
      {
         advSelCriteria=eval(advSelCriteriaCallBack+"('"+toScript(controlName)+"')");
      }
      
      //if we have advanced selection criterion, make sure we come up in advancedselection mode
      if (advSelCriteria==null || advSelCriteria.length==0)
      {
          advSelCriteria="";
      }
      else
      {
          advSel="true";  //if advanced criteria is present, startup in advance mode!
      }
      
      //call the task's preOS function
      if (exists("preOS")) preOS(controlName);

      var urlParms = "&User.context="+userContext+
                     "&OS.Control="+controlName+
                     "&OS.CallBack="+callBack+
                     "&OS.AdvancedSelection="+advSel+
                     //"&OS.AdvSelCriteria="+advSelCriteria+
                     "&OS.InitialContext="+urlEncode(initialContext)+
                     "&OS.IsOSAllowed="+isOSAllowed+
                     "&OS.Mode="+mode+
                     "&OS.MultiSelect="+multiSelect+
                     "&OS.NameFilter="+urlEncode(nameFilter)+
                     "&OS.QueryWidth="+window.osQueryColumnWidth+
                     "&OS.ResultsPerPage="+resultsPerPage+
                     "&OS.SearchSubContainers="+searchSubContainers+
                     "&OS.SearchOnStartup="+searchOnStartup+
                     "&OS.ShowSubClasses="+showSubClasses+
                     "&OS.TypeFilter="+urlEncode(typeFilter)+
                     "&OS.URLUniqueId="+Math.random();
          
      //parse and add advanced criteria to urlParms?           
      if (advSelCriteria.length>0)
      {
         var critArray = iman.commaSplit(advSelCriteria);
         var len = critArray.length;
         if (len>0)
         {
            var cnt=0;
            for (var i=0; i<len; i++)
            {
               var names = getTypeIds(critArray[i]);
               for (var j=0; j<names.length; j++)
               {
                  urlParms += "&OS.TypeFilter."+cnt+".name="+names[j];
                  urlParms += "&OS.TypeFilter."+cnt+".crit="+critArray[i];
                  cnt++;
               }
            }
            urlParms += "&OS.TypeFilter.cnt="+cnt;
         }
      }

      var url = 'webacc?taskId=fw.ObjectSelector&merge=fw.OS.ObjectSelector&error=dev.GenErr&SearchToken=SearchTokenInit'+urlParms;
      var winWidth = ((screen.availWidth<window.osWidth)?screen.availWidth:window.osWidth);
      var winHeight = ((screen.availHeight<window.osHeight)?screen.availHeight:window.osHeight);
      var leftPos = (screen.availWidth-winWidth)/2;
      var topPos =  (screen.availHeight-winHeight)/3;
      var winOpts = 'dependent, toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes,resizable=yes,left='+leftPos+',top='+topPos+',width='+winWidth+',height='+winHeight;
      
      //clear contents in an open OS window
      try
      {
         var w = window.open( "webacc?taskId=dev.Empty&merge=fw.Empty&clearOpenOS", 'ObjectSelectorWindow', winOpts);
      }
      catch (e)
      {
         //do nothing
      }
      
      //open new OS window
      //alert("doOS:  url="+url);
      var w = window.open( url, 'ObjectSelectorWindow', winOpts);
      if (w != null)
      {
         // make the window really be size winWidth,winHeight (not just the doc area) and give it focus.
         w.resizeTo(winWidth,winHeight);
      }
   }
}


function doOS( userContext,            // user session context info
               controlName,            // name of HTML control that will receive results
               callBack,               // routine to process selected results

               advSel,                 // opt - false (default) name-search only, true advanced selection criterion
               advSelCriteria,         // opt - list of XML advanced selection criteria
               advSelCriteriaCallBack, // opt - routine to return list of XML advanced selection criteria
               initialContext,         // opt - initial container to search from ([root] default)
               isOSAllowed,            // opt - routine to determine if OS should run at all
               mode,                   // opt - search (default)or browse
               multiSelect,            // opt - false (default) single select, true multi-select
               nameFilter,             // opt - initial name filter (* default)
               resultsPerPage,         // opt - number of objects to display at a time
               searchSubContainers,    // opt - true (default) search subcontainers, false find objects in only the specified container
               searchOnStartup,        // opt - false (default) wait for user to click search button,
                                       //       true, search container on startup
               showSubClasses,         // opt - true - base and derived classes found, false (default) - only base class found
               typeFilter,             // opt - type filter (all default)
               typeFilterCallBack,
               authName)     // opt - routine to return type filter
{
   // if in debug mode, make sure OSFooter.inc has been included in the task
   if (fw_isDebugEnabled && document.getElementById("OSExchangerFrame")==null)
   {
      var msg = "Developer Alert:  No OSFooter detected on this page.\n\n"+
                "You must include the file 'dev\OSFooter_inc.jsp' once after the last </form> tag\n"+
                "on any page that includes an Object Selector button.\n\n"+
                "Sample code snipits:\n"+
                "   jsp conduit:\t<jsp:include page='\<\%= c.getPath(\"dev/OSFooter_inc.jsp\") \%\>' flush=\"true\"/>\n"+
                "   iman tag library:\t<iman:osFooter/>\n"+
                "   xsl (deprecated):\t<xsl:call-template name=\"OSFooter\"/>";
      alert(msg);
   }
   
   if (controlName==null)           controlName="";
   if (callBack==null)              callBack="";

   var doOS=true;   //assume we will be running the object selector
   if (exists(isOSAllowed))
   {
      //execute specified routine to determine if search should proceed
      doOS=eval(isOSAllowed+"('"+toScript(controlName)+"')");
   }

   if (doOS)
   {
      //retrieve type filter from type filter callback, if a callback is specified
      if (exists(typeFilterCallBack))
      {
         typeFilter=eval(typeFilterCallBack+"('"+toScript(controlName)+"')");
      }
      
      //retrieve advanced selection criteria from advanced selection criteria callback, if a callback is specified
      if (exists(advSelCriteriaCallBack))
      {
         advSelCriteria=eval(advSelCriteriaCallBack+"('"+toScript(controlName)+"')");
      }
      
      //if we have advanced selection criterion, make sure we come up in advancedselection mode
      if (advSelCriteria==null || advSelCriteria.length==0)
      {
          advSelCriteria="";
      }
      else
      {
          advSel="true";  //if advanced criteria is present, startup in advance mode!
      }
      
      //call the task's preOS function
      if (exists("preOS")) preOS(controlName);

      var urlParms = "&User.context="+userContext+
                     "&OS.Control="+controlName+
                     "&OS.CallBack="+callBack+
                     "&OS.AdvancedSelection="+advSel+
                     //"&OS.AdvSelCriteria="+advSelCriteria+
                     "&OS.InitialContext="+urlEncode(initialContext)+
                     "&OS.IsOSAllowed="+isOSAllowed+
                     "&OS.Mode="+mode+
                     "&OS.MultiSelect="+multiSelect+
                     "&OS.NameFilter="+urlEncode(nameFilter)+
                     "&OS.QueryWidth="+window.osQueryColumnWidth+
                     "&OS.ResultsPerPage="+resultsPerPage+
                     "&OS.SearchSubContainers="+searchSubContainers+
                     "&OS.SearchOnStartup="+searchOnStartup+
                     "&OS.ShowSubClasses="+showSubClasses+
                     "&OS.TypeFilter="+urlEncode(typeFilter)+
                     "&OS.URLUniqueId="+Math.random()+
                     "&OS.AuthName="+authName;
      
      //parse and add advanced criteria to urlParms?           
      if (advSelCriteria.length>0)
      {
         var critArray = iman.commaSplit(advSelCriteria);
         var len = critArray.length;
         if (len>0)
         {
            var cnt=0;
            for (var i=0; i<len; i++)
            {
               var names = getTypeIds(critArray[i]);
               for (var j=0; j<names.length; j++)
               {
                  urlParms += "&OS.TypeFilter."+cnt+".name="+names[j];
                  urlParms += "&OS.TypeFilter."+cnt+".crit="+critArray[i];
                  cnt++;
               }
            }
            urlParms += "&OS.TypeFilter.cnt="+cnt;
         }
      }

      var url = 'webacc?taskId=fw.ObjectSelector&merge=fw.OS.ObjectSelector&error=dev.GenErr&SearchToken=SearchTokenInit'+urlParms;
      var winWidth = ((screen.availWidth<window.osWidth)?screen.availWidth:window.osWidth);
      var winHeight = ((screen.availHeight<window.osHeight)?screen.availHeight:window.osHeight);
      var leftPos = (screen.availWidth-winWidth)/2;
      var topPos =  (screen.availHeight-winHeight)/3;
      var winOpts = 'dependent, toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes,resizable=yes,left='+leftPos+',top='+topPos+',width='+winWidth+',height='+winHeight;
		
      //clear contents in an open OS window
      try
      {
         var w = window.open( "webacc?taskId=dev.Empty&merge=fw.Empty&clearOpenOS", 'ObjectSelectorWindow', winOpts);
      }
      catch (e)
      {
         //do nothing
      }
      
      //open new OS window
      //alert("doOS:  url="+url);
      var w = window.open( url, 'ObjectSelectorWindow', winOpts);
      if (w != null)
      {
         // make the window really be size winWidth,winHeight (not just the doc area) and give it focus.
         w.resizeTo(winWidth,winHeight);
      }
   }
}


function returnFromOS(osControl, osResults, osCallBack)
{
   //alert("entering returnFromOS... argument count = "+arguments.length);

   var callPostOS = true;

   try
   {
      if (osControl==null) osControl="";
      if (osCallBack==null) osCallBack="";
      if (osResults==null) osResults="";
      //alert("osControl="+osControl+"\nosCallBack="+osCallBack+"\nosResults="+osResults);
      
      if (arguments.length==0 || osResults.length==0)
      {
         //no arguments or result
         //alert("nothing to do...");
         callPostOS = false;
         return;  //no parameters -- nothing to do
      }

      if ( osControl.length==0 && osCallBack.length==0 )     //no place to send the result?
      {
         alert("returnFromOS:  ERROR -- Neither a control nor a callback routine has been specified."+
            "\n\nCannot return the selected object(s) = "+osResults);
         return;   //call the task's postOS function and return
      }
      
      if (osControl=="OS-FINISH-ERROR: Control name not retrievable; anchor uninitialized or reinitialized.")
      {
         return;  ////call the task's postOS function and return
      }

      //we must have a result, create an unencoded array of result strings
      var osResultsArray = osResults.split(',');
      for (i=0; i<osResultsArray.length; i++)
      {
         osResultsArray[i] = urlDecode(osResultsArray[i]);
      }

      //return the results to the callback or control
      if (osCallBack.length>0)
      {
         if (exists(osCallBack))
         {
            //let the callback routine process the os results


            var command = osCallBack+"('"+toScript(osControl)+"',osResultsArray)";

            try
            {
               eval( command );
            }
            catch(e)
            {
               //specified callback does not exist
               alert("returnFromOS:  ERROR -- Specified task callback '"+osCallBack+"' failed."+
                     "\n\nCannot return the selected object(s) = "+osResults +
                     "\n\nException = "+e);
            }
         }
         else
         {
            //specified callback does not exist
            alert("returnFromOS:  ERROR -- Specified task callback '"+osCallBack+"' does not exist."+
                  "\n\nCannot return the selected object(s) = "+osResults);
         }
      }
      else
      {
         //just store the os results in the specified control
         var results = "";
         for (i=0; i<osResultsArray.length; i++)
         {
            if (results.length != 0)
            {
               results += "+";
            }
            results += osResultsArray[i];
         }
         if (!setElementValue(osControl, results))
         {
            //couldn't save result in specified control
            alert("returnFromOS:  ERROR -- Attempt to save the result in control '"+osControl+"' failed."+
                  "\n\nCannot return the selected object(s) = "+osResults);
         }
      }
   }
   finally
   {
      //call the tasks postOS function
      //alert("trying to call postOS");
      if(callPostOS)
      {
         if (exists("postOS")) postOS(osControl);
      }
   }
}


//search all forms for the specified named element and set its value
function setElementValue(elementName, elementValue)
{
   if (elementName!=null && elementName.length>0)
   {  
      for (var i=0; i<document.forms.length; i++)
      {	
      	 if (document.forms[i].elements[elementName]!= null)
         {	
            document.forms[i].elements[elementName].value = elementValue;
           return true;
         }
      }
   }
   return false;
}

//get the ids of the ds-types from the advanced selection XML string
function getTypeIds(crit)
{
   //get ids <id>name1</id><id>name2<id2>...
   var idx1 = crit.indexOf("<types>");
   var idx2 = crit.indexOf("</types>");
   var tmp = null;
   if (idx1>-1 && idx2>-1 && idx2>idx1)
   {
      idx1 +=7;   //skip <types>
      tmp = crit.substr(idx1, idx2-idx1);
   }
   else
   {
      return new Array();  //no type ids to find
   }
   
   //split the ids into an array of name strings
   var ids = new Array();
   var cnt = 0;
   var start = 0;
   idx1 = tmp.indexOf("<id>", start);
   idx2 = tmp.indexOf("</id>", start);
   while (idx1>-1 && idx2>-1 && idx2>idx1)
   {
      idx1 += 4;  //skip <id>
      ids[cnt] = tmp.substr(idx1, idx2-idx1);
      cnt++;
      start = idx2+5;  //skip </id>
      idx1 = tmp.indexOf("<id>", start);
      idx2 = tmp.indexOf("</id>", start);
   }
   
   return ids;
}