/* CLASS: PrjInfo
    Contains global information of a debug session.  
    It's a global data object of the PowerTool.  The following instance variables
    are defined as:
    currentLoadFile = active loadfile of the debug session.
    sourcePathsCollection = [path, path...]
    loadFilesCollection = [loadFileNameStr, ...]
    dirtyPrj = true/nil
    loadFlags = symbol | code | status | warning
    loadOnDemand = 1 | 0

    NOTES: To open the PrjInfo object. (should be saved to a global variable)
        TheProjectInfoObj := init(new(prjInfo));

    - Use the loadFilesCollection to create menu item of the previous opened
    loadfiles.
*/!!

inherit(Object, #PrjInfo, #(pathCvnDict /* paths conversion Dict */
sourcePathsCollection /* a fixed size collection */
loadFilesCollection  /* fixed size collection of opened Loadfiles */
currentLoadFile /* active LoadFile */
dirtyPrj /* boolean indicate project changed */
loadFlags /* a word = symbol | code | status | warning */
loadOnDemand /* 1 or 0 */
), 2, nil)!!

now(class(PrjInfo))!!

now(PrjInfo)!!

/* 6/10/1993 15:07  - PRIVATE
  Search for the fileSpec from the source paths collection.
*/
Def searchFileSpec(self, moduleInfoObj, fileSpec | index, tmpStr, lfPath)
{ 
  if (size(sourcePathsCollection) > 0) then
    /* Iterate over the collection */
    index := 0;
    do (sourcePathsCollection,
      {using(element)
        tmpStr := makePathString(asString(element), fileSpec);
        if exists(File, tmpStr, 0) then
          /* Reset the alias reference for the moduleInfoObj */  
          setAliasPathRef(moduleInfoObj, index);
          ^tmpStr;
        endif;
        index := index + 1;  
      });
  endif;
  /* Nothing found from the collection - So let try the loadpath */     
  if (size(loadFilesCollection) > 0) cand
     (lfPath := first(loadFilesCollection)) cand (size(lfPath) > 0) then
    tmpStr := pathParts(lfPath)[0];
    lfPath :=  makePathString(tmpStr, fileSpec);
    if exists(File, lfPath, 0) then
       /* Reset the alias reference for the moduleInfoObj - add it to the list */  
       setAliasPathRef(moduleInfoObj, addAliasPath(self, tmpStr));
       ^lfPath;
    endif;
  endif;
  ^nil;   
}!!

/* 06/10/93 10:50 - PUBLIC 
  Add the new alias path to the sourcePathsCollection.
  Return the index of the newly added path string. 
*/
Def addAliasPath(self, defPath | item index)
{ 
  dirtyPrj := #true;
  defPath:=asUpperCase(defPath); /* <Judy 7/18/97> */
  /* <Judy 7/16/97> */
  index := 0;
  do(sourcePathsCollection ,
     {using(element)
      if(asString(element)=defPath)
        remove(sourcePathsCollection, index);
      endif;
      index := index + 1;
     }  );    
  /* eof <Judy 7/16/97> */
  /* item := addToEnd(sourcePathsCollection, defPath); <Judy 7/18/97> */ 
  item:=insert(sourcePathsCollection,defPath,0); /* <Judy 7/18/97> */
  saveProjectProfile(self);
  ^item;
}
!!

/* 6/8/1993 15:18 - PUBLIC
  Return the path alias given the index location.  Return nil if index is
  invalid or the loadfile path if the sourcePathsCollection is empty.
  
*/
Def getAliasFilePath(self, moduleInfoObj, index | numItems, newStr)
{ 
  numItems := size(sourcePathsCollection);
  if index cand (numItems > 0) then
    /* Make sure that the index is not out of bound */
    if between(index, 0, numItems) then 
      ^sourcePathsCollection[index];
    else
      /* Reset the alias reference for the moduleInfoObj */  
      setAliasPathRef(moduleInfoObj, nil);      
    endif;
  endif;
  /* sourcePaths Collection is empty - try the loadfile path */
  if isLoaded(currentLoadFile) cand 
     (newStr := loadFilePath(currentLoadFile)) then
    addAliasPath(self, newStr);
    ^newStr;       
  endif;  
  ^nil;   
}
!!

/* 6/4/1993 17:16 - PUBLIC
  Replace the current sourcePathsCollection with the newColl.
*/
Def setSourcePathsCollection(self, newColl | modulesDict)
{ 
  sourcePathsCollection := deepCopy(newColl);
  /* Flush all source/mixed info that we have so far */
  if isLoaded(currentLoadFile) cand
     (modulesDict := modulesDict(currentLoadFile)) then
    do (modulesDict,
      {using(module)
        resetBrowsedInfo(module);
      });
  endif;   
  saveProjectProfile(self);      
}
!!

/* 6/4/1993 16:42 - PUBLIC
  return the current sourcePathsCollection
*/
Def sourcePathsCollection(self)
{ 
  ^sourcePathsCollection;
}
!!

/* 6/3/1993 13:43 - PUBLIC
  return the state of the PrjInfo object.
*/
Def isDirty(self)
{ 
  ^dirtyPrj;
}
!!

/* 5/21/1993 13:16 - PUBLIC 
  Added the new last loadfile to loadFilesCollection.
  Return #true if the <loadFileStr> is added, else nil.
*/
Def setLastLoadFile(self, loadFileStr)
{
  /* Search for the <loadFileStr> in the collection 
  ** If it is not there then add it in - else ignore
  */
  do (loadFilesCollection,
    {using(element)
      if (asString(element) = asString(loadFileStr))
        ^nil;
      endif;  
    });
  add(loadFilesCollection, loadFileStr);
  ^(dirtyPrj := #true);

}
!!

/* 5/21/1993 10:42 - PUBLIC
  return the last loadfiles collection.
*/
Def lastLoadFiles(self)
{ 
  ^loadFilesCollection;
}
!!

/* 8/7/1992 9:06 - PUBLIC
  Save the project Info profile control to SourceInfo of POWERVIEW.INI
*/
Def saveProjectProfile(self | appName, numAliasPath, i, val)
{ 
  appName := "SourceInfo";
  /* Save LoadFlags */
  val := ((loadFlags bitAnd 0x1) > 0); 
  saveProfileEntry(TheProfileInfoObj, appName, "LoadSymbol", 
      asString(asCBoolean(TheProfileInfoObj, val)));
  val := ((loadFlags bitAnd 0x2) > 0); 
  saveProfileEntry(TheProfileInfoObj, appName, "LoadCode", 
      asString(asCBoolean(TheProfileInfoObj, val)));
  val := ((loadFlags bitAnd 0x4) > 0); 
  saveProfileEntry(TheProfileInfoObj, appName, "LoadReportStatus", 
      asString(asCBoolean(TheProfileInfoObj, val)));
  val := ((loadFlags bitAnd 0x8) > 0); 
  saveProfileEntry(TheProfileInfoObj, appName, "LoadReportWarning", 
      asString(asCBoolean(TheProfileInfoObj, val)));
  val := ((loadFlags bitAnd 0x10) > 0); 
  saveProfileEntry(TheProfileInfoObj, appName, "LoadAsmModules", 
      asString(asCBoolean(TheProfileInfoObj, val)));
      
  saveProfileEntry(TheProfileInfoObj, appName, "LoadOnDemand", 
      asString(asCBoolean(TheProfileInfoObj, (loadOnDemand > 0))) );

  /* Save the LRU loadfiles - loadFileCollections is a fixed size queue */
  i := 0;
  if size(loadFilesCollection) > 0 then
    i := 0;
    do (loadFilesCollection, 
      {using(element)
        saveProfileEntry(TheProfileInfoObj, appName, 
            "LoadFile"+asString(i), asString(element));
        i := i + 1;
      });
  endif;

  /* Save all source path alias (max 50) - sourcePathsCollection is a fixed size queue */
  numAliasPath := size(sourcePathsCollection);
  saveProfileEntry(TheProfileInfoObj, appName, "NumAliasPath", asString(numAliasPath));
  i := 0;
  if (numAliasPath > 0) then
    do (sourcePathsCollection,
      {using(element)
        saveProfileEntry(TheProfileInfoObj, appName, "SourcePathAlias"+asString(i), 
          asString(element));
        i := i + 1;  
      });
  endif;   
}
!!

/* 8/7/1992 9:06 - PUBLIC
  Get the project info profile control from SourceInfo of POWERVIEWS.INI
*/
Def getProjectProfile(self | appName, iniVal, iniStr, i)
{ 
  appName := "SourceInfo";
  
  loadFlags := 0x0;  /* All options are OFF */
  loadOnDemand := 0;
  /* Get LoadFlags */
  /* NOTES: Load Option is ON if the following are true
  ** it is not found/defined in INI, 
  ** not in a valid range, 
  ** or it is defined as 1  
  */
  if not(iniVal := getIniValueNum(TheProfileInfoObj, appName, "LoadSymbol")) 
        cor not(between(iniVal, 0, 1)) cor (iniVal = 1) then 
    loadFlags := loadFlags bitOr 0x1;  
  endif;  

  if not(iniVal := getIniValueNum(TheProfileInfoObj, appName, "LoadCode")) 
        cor not(between(iniVal, 0, 1)) cor (iniVal = 1) then 
    loadFlags := loadFlags bitOr 0x2;  
  endif;  
  
  if not(iniVal := getIniValueNum(TheProfileInfoObj, appName, "LoadReportStatus")) 
        cor not(between(iniVal, 0, 1)) cor (iniVal = 1) then   
    loadFlags := loadFlags bitOr 0x4;  
  endif;

  if not(iniVal := getIniValueNum(TheProfileInfoObj, appName, "LoadReportWarning")) 
        cor not(between(iniVal, 0, 1)) cor (iniVal = 1) then
    loadFlags := loadFlags bitOr 0x8;  
  endif;  

  if not(iniVal := getIniValueNum(TheProfileInfoObj, appName, "LoadAsmModules")) 
        cor not(between(iniVal, 0, 1)) cor (iniVal = 1) then
    loadFlags := loadFlags bitOr 0x10;  
  endif;  

  if not(iniVal := getIniValueNum(TheProfileInfoObj, appName, "LoadOnDemand")) 
        cor not(between(iniVal, 0, 1)) cor (iniVal = 1) then
    loadOnDemand := 1;    
  endif;

  /* Get upto MAX_LRU_LOADFILES (4) loadfiles */
  i := 0;
  loop
  while (i < MAX_LRU_LOADFILES)
  begin
     if (iniStr := getIniValueStr(TheProfileInfoObj, appName, 
        "LoadFile"+asString(i))) cand (size(iniStr) > 0) then
        addToEnd(loadFilesCollection, iniStr);
     endif;        
     i := i + 1;
  endLoop;
 
  /* Get all source path alias (max 50) */
  if (iniVal := getIniValueNum(TheProfileInfoObj, appName, "NumAliasPath")) 
        cand between(iniVal, 0, MAX_SRC_PATHS) then
    i := 0;
    loop
    while (i < iniVal)
    begin
       if (iniStr := getIniValueStr(TheProfileInfoObj, appName, 
        "SourcePathAlias"+asString(i))) cand (size(iniStr) > 0) then
        addToEnd(sourcePathsCollection, iniStr);
       endif;        
       i := i + 1;
    endLoop;
  endif;
}
!!

/* 5/5/1992 11:26 - PUBLIC
  Set the currentLoadFile of the ProjectInfo.
*/
Def setCurrentLoadFile(self, newLoadFile)
{ 
  dirtyPrj := #true;
  ^(currentLoadFile := newLoadFile);
}!!

/* 5/5/1992 12:47 - PUBLIC
  Return the current loadfile of self.
*/
Def currentLoadFile(self)
{ 
  ^currentLoadFile;
}
!!

/* 7/8/1992 11:58 - PUBLIC
  Return the previous used path name (e.g. "D:\TEST\*.ext").
*/
Def prevUsedPath(self | tmpPath, tmpParts)
{ 
  /* Get the path of the LRU loadfile */
  if (size(loadFilesCollection) > 0) cand (tmpPath := first(loadFilesCollection)) 
    cand (tmpParts := pathParts(tmpPath)) then
    ^tmpParts[0]+"*."+tmpParts[2];
  endif;     
  ^nil;
}
!!

/* 6/25/1992 10:50 - PUBLIC 
  Add the new alias path to pathCvnDict[] = systemPath->AliasPath.
*/
Def addDefinedPath(self, keyPath, defPath)
{ 
  dirtyPrj := #true;
  add(pathCvnDict, keyPath, defPath);
}
!!

/* 6/4/1992 10:42 - PUBLIC
  Return the path conversion dictionary.
*/
Def pathCvnDict(self)
{ 
  ^pathCvnDict; 
}
!!

/* 6/3/1992 11:26 - PUBLIC */
Def loadOnDemand(self)
{ 
  ^loadOnDemand; 
}
!!

/* 6/3/1992 11:25 - PUBLIC */
Def loadFlags(self)
{ ^loadFlags; }
!!

/* 4/28/1992 12:07 - PUBLIC
  Set the OnDemand flag for self.
*/
Def setOnDemand(self, newFlag)
{ 
  if newFlag <> loadOnDemand then
    dirtyPrj := #true;
    ^(loadOnDemand := newFlag); 
  endif;  
}
!!

/* 06/20/92 - PUBLIC */
Def setLoadFlags(self, newLoadFlag)
{ 
  if newLoadFlag <> loadFlags then
    dirtyPrj := #true;
    ^(loadFlags := newLoadFlag) 
  endif;      
}!!

/* 6/3/1992 10:17 - PUBLIC
  Set the dirtyPrj flag
*/
Def setPrjDirty(self, flag)
{ 
  dirtyPrj := flag;
}
!!

/* 6/3/1992 9:40 - PUBLIC
  Initialize project information
*/
Def init(self)
{ 
  dirtyPrj := nil;
  currentLoadFile := init(new(LoadFileModule), nil, nil); /* Uninitialize */
  pathCvnDict := new(Dictionary, 2); /* paths to source dictionary */
  loadFilesCollection := new(FixedSizeQueue, MAX_LRU_LOADFILES); /* the last 4 loadfiles */
  sourcePathsCollection := new(FixedSizeQueue, MAX_SRC_PATHS);
  getProjectProfile(self);
}
!!
