/********************************************************************************************************
 * classes.js 
 * Description: Contains all the class definitions used in the present Agile COCOMO Tool
 * Version: 1.0 
 *
 * Revisions:   Date         Participant                What is done
 *              03/20/2004   Shaofeng Xi                Create all Class Names based on UML Deisn
 *              04/02/2004   Shaofeng Xi                Draft for Classes: Project, AnalogyParameter, Language
 *              04/10/2004   Shaofeng Xi                Draft for Classes: CostDriverCategoryList, CostDriverCategory, CostDriver
 *              04/11/2004   Shaofeng Xi                Draft for Classes: ScaleFactorList, ScaleFactor, RatingLevel, Estimation
 *              04/15/2004   Shaofeng Xi                Implement the methods in all the classes
 *		07/29/2004   Michael Chuang		Added Estimate PM methods
 *******************************************************************************************************/


//----------Javascript Class Definition----------------------------------------------Begin

/****************************************************************
Class Project
****************************************************************/
function Project() {
    //-----Constants-----------------Begin
    this.DEFAULT_VALUES = "COCOMO Default Values";      //For calibrationSource
    this.LOCAL_VALUES = "Local Values loaded for client use";       //For calibrationSource
    
    this.TYPE_COST_DRIVER = "Cost Driver";    //For Estimation's basisType
    this.TYPE_SCALE_FACTOR = "Scale Factor";  //For Estimation's basisType
    //-----Constants-----------------End
    
    
    //-----Class Member Variables----Begin
    this.projectName = "";      //String
    this.baselineValue = NaN;    //Double
    this.step1Value = NaN;    //Double (Dollars)
    this.step2Value = NaN;    //Double (PM)
    this.analogyParameter;  //AnalogyParameter Object. It's one of analogyParameterList
    this.currentSLOC = NaN;      //int
    this.currentKSLOC = NaN;      //int
    this.currentLaborRate = NaN;  //Double
    this.currentLaborRateForIdealWeek = NaN; //Double
    this.currentFunctionPoint = NaN;  //int
    this.ratioOfSLOCToUFP = NaN;  //int     The number of KSLOC per Function Point
    this.language = "" //String
    this.helpmodeon = false; //turning help mode on and off in driver factor window
    this.dollarsmodeon = false; // showing dollars estimation on or off
    this.PMmodeon = false; // showing effort estimation on or off
    this.submitted = false; //boolean
    this.allinput = false; //boolean, all input for both modes of current analogy parameter met
    this.winHandler = null; // DriverFactor popup
    this.winHandler2 = null; // ViewReport popup
    this.yesunder2000 = false; // SLOC under 2000 mode
    
    this.analogyParameterList;      //Array    It stores all possible analogyParameter objects
    this.estimationHistory = new Array();     //Array     It stores all estimation the user has created.
      
    this.currentCostDrivers;  //CostDriverCategoryList Object. A tree-view object storing all the cost drivers and their rating values
    this.currentScaleFactors; //ScaleFactorList Object. A tree-view object storing all the scale factors and their rating values
    
    this.calibrationSource = this.DEFAULT_VALUES;   //String    Possible value could be: DEFAULT_VALUES, THIRD_PARTY_VALUES, ...
    
    //-----Class Member Variables----End
    
    
    //---------Methods Referencing------------begin
    if (typeof(_Project_prototype_called) == 'undefined')  {         //Note: 'undefined' is different from null
         _Project_prototype_called = true;     //Note: This variable name can't be used in global scope. If used, change name.
         Project.prototype.loadAnalogyParameter = loadAnalogyParameter;
         Project.prototype.loadCalibrationValues = loadCalibrationValues;
         Project.prototype.getAnalogyParameter = getAnalogyParameter;
         Project.prototype.getCostDriver = getCostDriver;
         Project.prototype.getScaleFactor = getScaleFactor;
         Project.prototype.addEstimation = addEstimation;
         Project.prototype.updateEstimation = updateEstimation;
         Project.prototype.deleteEstimation = deleteEstimation;
         Project.prototype.calculateCostUpTo = calculateCostUpTo;
         Project.prototype.calculatePMUpTo = calculatePMUpTo;
    }
    //---------Methods Referencing------------end
  
    /********************************************
    @return boolean
    ********************************************/
    function loadAnalogyParameter() {
        var returnValue = false;
        var apList = new Array();
        
        apList[0] = new AnalogyParameter("AP01", "Total Cost in Dollars");
        apList[1] = new AnalogyParameter("AP02", "Total Effort in Person-Months");      
        apList[2] = new AnalogyParameter("AP03", "Productivity in Dollars / Function Point");
        apList[3] = new AnalogyParameter("AP04", "Productivity in Dollars / Lines of Code");
        apList[4] = new AnalogyParameter("AP05", "Productivity in Function Points / Person-Months");
        apList[5] = new AnalogyParameter("AP06", "Productivity in Lines of Code / Person-Months");
        apList[6] = new AnalogyParameter("AP07", "Project Velocity in Total Ideal-Person-Weeks / Iteration");
        
        this.analogyParameterList = apList;
        this.analogyParameter = apList[0];  //The initial current analogyParameter is the first one in the List.
        returnValue = true;
        
        return(returnValue);
    } //End of load AnalogyParameter
    
    /********************************************
    @return boolean
    ********************************************/
    function loadCalibrationValues(sourceType) {
        var returnValue = false;
        var costDriverCategoryList = new CostDriverCategoryList();
        var scaleFactorList = new ScaleFactorList();
        
        //try {
            if(sourceType == this.DEFAULT_VALUES) {
                if((true == costDriverCategoryList.loadCostDrivers()) && (true == scaleFactorList.loadScaleFactors())) {
                    returnValue = true;
                }
                else {
                    returnValue = false;
                }
            }
            else {
                if((true == costDriverCategoryList.loadCostDriversFromFile("FileName")) && (true == scaleFactorList.loadScaleFactorsFromFile("FileName"))) {
                    returnValue = true;
                }
                else {
                    returnValue = false;
                }
            } 
               
        //}
        //catch (exception) {
        //    returnValue = false;
        //}
        
        if(true == returnValue) {
            this.currentCostDrivers = costDriverCategoryList;
            this.currentScaleFactors = scaleFactorList;
        } 
            
        return(returnValue);  
    }  //End of loadCalibrationValues
    
    /*****************************  
    @return AnalogyParameter Object
    ******************************/
    function getAnalogyParameter(parameterValue) {
        var i;
        
        i=0;
        while((i<this.analogyParameterList.length) && (this.analogyParameterList[i].value != parameterValue)) {
          i++;
        }
        
        if(i!=this.analogyParameterList.length) {
          return(this.analogyParameterList[i]);  
        }
        else {
          return(null);
        }
    }  //End of getAnalogyParameter
    
    /***********************************************************************
    Search and return a CostDriver object from currentCostDrivers which is a CostDriverCategoryList object
    @Parameter categoryName: String
    @Parameter costDriverName: String
    @Return   a CostDriver, or null if nothing found in currentCostDrivers
    ************************************************************************/
    function getCostDriver(categoryName, costDriverName) {
        var costDriverCategoryList;
        var costDriverCategory;
        var costDriver;
        
        costDriverCategoryList = this.currentCostDrivers;  //The search will be doing with this member variable of Project
        
        costDriverCategory = costDriverCategoryList.findCostDriverCategory(categoryName);
        
        if(null != costDriverCategory) {
            costDriver = costDriverCategory.findCostDriver(costDriverName);
            if(null != costDriver) {
                return(costDriver);
            }
            else {
                return(null);
            }
        }
        else {
            return(null);
        }

    }  //End of getCostDriver
    
    /***********************************************************************
    Search and return a ScaleFactor object from currentScaleFactors which is a ScaleFactorList object
    @Parameter scaleFactorName: String
    @Return   a ScaleFactor, or null if nothing found in currentScaleFactors
    ************************************************************************/
    function getScaleFactor(scaleFactorName) {
        var scaleFactorList;
        var scaleFactor;
        
        scaleFactorList = this.currentScaleFactors;  //The search will be doing with this member variable of Project
        
        scaleFactor = scaleFactorList.findScaleFactor(scaleFactorName);
        
        if(null != scaleFactor) {
            return(scaleFactor);
        }
        else {
            return(null);
        }
    }  //End of getScaleFactor
    
    /********************************************
    @return boolean
    ********************************************/
    function addEstimation(basisType, basisObject, lastRatingLevel, currentRatingLevel) {
        var currentLength;
 
        currentLength = this.estimationHistory.push(new Estimation(basisType, basisObject, lastRatingLevel, currentRatingLevel));
        
    }  //End of addEstimation
    
    /********************************************
    @return boolean
    ********************************************/
    function updateEstimation(sequenceNo, basisType, basisObject, lastRatingLevel, currentRatingLevel) {
        var returnValue = false;
        var removedEstimation;
        
        if((sequenceNo >= 1) && (sequenceNo <= this.estimationHistory.length)) {
            this.estimationHistory[sequenceNo-1] = new Estimation(basisType, basisObject, lastRatingLevel, currentRatingLevel);  //Update one element at index "sequenceNo-1"
            returnValue = true;
        }
        else 
            returnValue = false;
        
        return(returnValue);
    }  //End of updateEstimation  
  
    /********************************************
    @parameter sequenceNo: From 1 .. Array.length
    @return boolean
    ********************************************/
    function deleteEstimation(sequenceNo) {
        var returnValue = false;
        var removedEstimation;
        
        if((sequenceNo >= 1) && (sequenceNo <= this.estimationHistory.length)) {
            removedEstimation = this.estimationHistory.splice(sequenceNo-1, 1);  //Remove one element at index "sequenceNo-1"
            returnValue = true;
        }
        else 
            returnValue = false;
        
        return(returnValue);
    }  //End of deleteEstimation 
    
    /********************************************
    @Parameter sequenceNo   Integer    The index no of an element of estimationHistory Array
    @return double or NaN   A number formatted like 121.00, 68.80
    ********************************************/
    function calculateCostUpTo(sequenceNo) {
        var returnValue = NaN;  //Double
        var estimation;
        var i;
        
        if (sequenceNo > this.estimationHistory.length) {
            returnValue = NaN;
        }
        else {
            returnValue = this.step1Value;
            for(i=0; i<sequenceNo; i++) {
                estimation = this.estimationHistory[i];
                returnValue = estimation.calculateCurrentCost(returnValue, this.currentKSLOC);
            }
        }
        
        return(returnValue);
    }  //End of calculateCostUpTo 

    /********************************************
    @Parameter sequenceNo   Integer    The index no of an element of estimationHistory Array
    @return double or NaN   A number formatted like 121.00, 68.80
    ********************************************/
    function calculatePMUpTo(sequenceNo) {
        var returnValue = NaN;  //Double
        var estimation;
        var i;
        
        if (sequenceNo > this.estimationHistory.length) {
            returnValue = NaN;
        }
        else {
            returnValue = this.step2Value;
            for(i=0; i<sequenceNo; i++) {
                estimation = this.estimationHistory[i];
                returnValue = estimation.calculateCurrentPM(returnValue, this.currentKSLOC);
            }
        }
        
        return(returnValue);
    }  //End of calculatePMUpTo 
    
}  //End of Class Project


/****************************************************************
Class AnalogyParameter
****************************************************************/
function AnalogyParameter(value, name) {
    this.value = value;
    this.name = name;
}  //End of Class AnalogyParameter


/****************************************************************
Class Language
****************************************************************/
function Language(name, typicalRatioOfSLOCToUFP) {
    this.name = name;
    this.typicalRatioOfSLOCUFP = typicalRatioOfSLOCUFP;
}  //End of Class Language

/****************************************************************
Class CostDriverCategoryList
****************************************************************/
function CostDriverCategoryList() {
    this.categoryList = new Array();  //Array      It stores all Categories for Cost Drivers.
    
    //---------Methods Referencing------------begin
    if (typeof(_CostDriverCategoryList_prototype_called) == 'undefined')  {         //Note: 'undefined' is different from null
         _CostDriverCategoryList_prototype_called = true;     //Note: This variable name can't be used in global scope. If used, change name.
         CostDriverCategoryList.prototype.loadCostDrivers = loadCostDrivers;
         CostDriverCategoryList.prototype.loadCostDriversFromFile = loadCostDriversFromFile;
         CostDriverCategoryList.prototype.findCostDriverCategory = findCostDriverCategory;
    }
    //---------Methods Referencing------------end
    
    /***************************************
    Using for preparation of data
    @return boolean
    ***************************************/
    function loadCostDrivers() {
        var returnValue = false;
        var categoryArray = new Array();
        var costDriverCategoryObj;
        var costDriverObj;
        var ratingLevelObj;
        
        /****Loading Values Example************************************************************************************
        //----------Create a new CostDriverCategory in Javascript-------------------------------------Begin
        costDriverCategoryObj = new CostDriverCategory("");
        categoryArray[0] = costDriverCategoryObj;
        
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "", "");
            costDriverObj.description = "The greater the multiplier value for "+ costDriverObj.name +", the more cost for the project.";
            costDriverCategoryObj.costDriverList[0] = costDriverObj;
                
                //--------------Create a new RatingLevel, and add to CostDriver Object----Begin
                ratingLevelObj = new RatingLevel("", "", "");
                costDriverObj.ratingList[0] = ratingLevelObj;
                //--------------Create a new RatingLevel, and add to CostDriver Object----End
                
                //--------------Create a new RatingLevel, and add to CostDriver Object----Begin
                ratingLevelObj = new RatingLevel("", "", "");
                costDriverObj.ratingList[1] = ratingLevelObj;
                //--------------Create a new RatingLevel, and add to CostDriver Object----End
                
                ...
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
            
            ...
            
        //----------Create a new CostDriverCategory in Javascript-------------------------------------End
        
        ...
        
        **************************************************************************************************************/
        
        //*************************************************************************************************************
        //********Loading Values**********************************************************************************Begin
        //*************************************************************************************************************
        
        //----------Create a new CostDriverCategory in Javascript-------------------------------------Begin
        costDriverCategoryObj = new CostDriverCategory("Product");
        categoryArray[0] = costDriverCategoryObj;
        
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Required Software Reliability", "");
            costDriverObj.description = "This the measure of the extent to which software must perform its intended function over a period of time. If the effect of a software failure is only slight inconvenience, then Reliability rating is Very low. If a failure would risk human life, then the rating is Very high.";
            costDriverCategoryObj.costDriverList[0] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("VL", 0.82, "Slight inconvenience");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("L", 0.92, "Low, easily recoverable losses");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("N", 1.00, "Moderate, easily recoverable losses");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 1.10, "High financial loss");
                costDriverObj.ratingList[3] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 1.26, "Risk to human life");
                costDriverObj.ratingList[4] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
            
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Database Size", "");
            costDriverObj.description = "This attempts to capture the effect large test data requirements have on product development. It is determined by calculating D/P , the ratio of bytes in the testing database to SLOC in the program";
            costDriverCategoryObj.costDriverList[1] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("L", 0.90, "DB bytes / Pgm SLOC < 10");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("N", 1.00, "10 <= D/P < 100");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 1.14, "100 <= D/P < 1000");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 1.28, "D/P > 1000");
                costDriverObj.ratingList[3] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
            
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Product Complexity", "");
            costDriverObj.description = "This attempts to capture the complexity in writing software code arising from the intricacy of the software’s user-interface operations, database management operations, control operation, device dependant computations and computational operations. Simpler overall structure corresponds to lower ratings of this cost driver.";
            costDriverCategoryObj.costDriverList[2] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("VL", 0.73, "Level 1");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("L", 0.87, "Level 2");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("N", 1.00, "Level 3");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 1.17, "Level 4");
                costDriverObj.ratingList[3] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 1.34, "Level 5");
                costDriverObj.ratingList[4] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("XH", 1.74, "Level 6");
                costDriverObj.ratingList[5] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
        
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Developed for Reusability", "");
            costDriverObj.description = "This driver accounts for the additional effort needed to construct components intended for re-use on current or future projects.";
            costDriverCategoryObj.costDriverList[3] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("L", 0.95, "None");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("N", 1.00, "Across project");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 1.07, "Across program");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 1.15, "Across product line");
                costDriverObj.ratingList[3] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("XH", 1.24, "Across multiple product lines");
                costDriverObj.ratingList[4] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
            
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Documentation Match to Life Cycle Needs", "");
            costDriverObj.description = "This is evaluates the suitability of the project documentation to the life-cycle needs of the project. The ratings level range from Very low (many life-cycle needs not covered) to Very high (very excessive for life-cycle needs)";
            costDriverCategoryObj.costDriverList[4] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("VL", 0.81, "Many life-cycle needs uncovered");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("L", 0.91, "Some life-cycle needs uncovered");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("N", 1.00, "Right-sized to life-cycle needs");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 1.11, "Excessive for life-cycle needs");
                costDriverObj.ratingList[3] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 1.23, "Very excessive for life-cycle needs");
                costDriverObj.ratingList[4] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
        //----------Create a new CostDriverCategory in Javascript-------------------------------------End
        
            
        //----------Create a new CostDriverCategory in Javascript-------------------------------------Begin
        costDriverCategoryObj = new CostDriverCategory("Platform");
        categoryArray[1] = costDriverCategoryObj;
        
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Execution Time Constraint", "");
            costDriverObj.description = "This is a measure of the execution time constraint imposed upon a software system expressed in terms of percentage of available execution time expected to be used by the system or sub-system consuming the execution time resource.";
            costDriverCategoryObj.costDriverList[0] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("N", 1.00, "<= 50%");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("H", 1.11, "70%");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 1.29, "85%");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("XH", 1.63, "95%");
                costDriverObj.ratingList[3] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
            
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Main Storage Constraint", "");
            costDriverObj.description = "This represents the degree of main storage constraint imposed on the software system or sub-system.";
            costDriverCategoryObj.costDriverList[1] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("N", 1.00, "<= 50%");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("H", 1.05, "70%");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 1.17, "85%");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("XH", 1.46, "95%");
                costDriverObj.ratingList[3] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
            
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Platform Volatility", "");
            costDriverObj.description = "This is a measure of the frequency of changes/updates to the development platform being used. The ratings are self explanatory.";
            costDriverCategoryObj.costDriverList[2] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("L", 0.87, "Major change every 12 mo.; minor change every 1 mo.");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("N", 1.00, "Major: 6 mo.; minor: 2 wk.");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 1.15, "Major: 2 mo.; minor: 1 wk.");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 1.30, "Major: 2 wk.; minor: 2 days");
                costDriverObj.ratingList[3] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End    
            
        //----------Create a new CostDriverCategory in Javascript-------------------------------------End
        
        
        //----------Create a new CostDriverCategory in Javascript-------------------------------------Begin
        costDriverCategoryObj = new CostDriverCategory("Personnel");
        categoryArray[2] = costDriverCategoryObj;
        
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Analyst Capability", "");
            costDriverObj.description = "This reflects the skill level of the people working on requirements, high-level design and detailed design of the project. Major factors used in rating should be analysis & design ability, efficiency & thoroughness and, ability to co-operate. It should not include the experience of the analyst which is rated using other cost drivers.";
            costDriverCategoryObj.costDriverList[0] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("VL", 1.42, "15th percentile");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("L", 1.19, "35th percentile");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("N", 1.00, "55th percentile");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 0.85, "75th percentile");
                costDriverObj.ratingList[3] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 0.71, "90th percentile");
                costDriverObj.ratingList[4] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
            
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Programmer Capability", "");
            costDriverObj.description = "This reflects the skill level of the people writing software code working as team-members. Major factors used in rating should be analysis & design ability, efficiency & thoroughness and, ability to co-operate.";
            costDriverCategoryObj.costDriverList[1] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("VL", 1.34, "15th percentile");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("L", 1.15, "35th percentile");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("N", 1.00, "55th percentile");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 0.88, "75th percentile");
                costDriverObj.ratingList[3] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 0.76, "90th percentile");
                costDriverObj.ratingList[4] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
            
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Personnel Continuity", "");
            costDriverObj.description = "This cost driver depends on the annual personnel turnover.";
            costDriverCategoryObj.costDriverList[2] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("VL", 1.29, "48% / year");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("L", 1.12, "24% / year");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("N", 1.00, "12% / year");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 0.90, "6% / year");
                costDriverObj.ratingList[3] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 0.81, "3% / year");
                costDriverObj.ratingList[4] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
            
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Application Experience", "");
            costDriverObj.description = "This cost driver depends on the level of applications experience of the team developing the software system or subsystem.";
            costDriverCategoryObj.costDriverList[3] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("VL", 1.22, "<= 2 months");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("L", 1.10, "6 months");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("N", 1.00, "1 year");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 0.88, "3 years");
                costDriverObj.ratingList[3] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 0.81, "6 years");
                costDriverObj.ratingList[4] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
            
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Platform Experience", "");
            costDriverObj.description = "This cost driver depends on the level of platform experience of the team developing the software system or subsystem.";
            costDriverCategoryObj.costDriverList[4] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("VL", 1.19, "<= 2 months");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("L", 1.09, "6 months");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("N", 1.00, "1 year");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 0.91, "3 years");
                costDriverObj.ratingList[3] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 0.85, "6 years");
                costDriverObj.ratingList[4] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
            
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Language and Tool Experience", "");
            costDriverObj.description = "This reflects the language and software tool experience level of the people developing the software system or sub-system.";
            costDriverCategoryObj.costDriverList[5] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("VL", 1.20, "<= 2 months");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("L", 1.09, "6 months");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("N", 1.00, "1 year");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 0.91, "3 years");
                costDriverObj.ratingList[3] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 0.84, "6 years");
                costDriverObj.ratingList[4] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End    
            
        //----------Create a new CostDriverCategory in Javascript-------------------------------------End
        
        
        //----------Create a new CostDriverCategory in Javascript-------------------------------------Begin
        costDriverCategoryObj = new CostDriverCategory("Project");
        categoryArray[3] = costDriverCategoryObj;
        
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Use of Software Tools", "");
            costDriverObj.description = "This drivers reflects the extent of tool support for the project including the kinds of tools available & the degree to which these tools are integrated.";
            costDriverCategoryObj.costDriverList[0] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("VL", 1.17, "Edit, code, debug");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("L", 1.09, "Simple, frontend, backend CASE, little integration");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("N", 1.00, "Basic lifecycle tools, moderately integrated");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 0.90, "Strong, mature lifecycle tools, moderately integrated");
                costDriverObj.ratingList[3] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 0.78, "Strong, mature, proactive lifecycle tools, well integrated with processes, methods, reuse");
                costDriverObj.ratingList[4] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End    
            
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Multisite Development", "");
            costDriverObj.description = "This cost driver reflects the modern-day reality of multiple teams of developers working from different locations. Ratings for this driver depend on site co-location and communication support between sites.";
            costDriverCategoryObj.costDriverList[1] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("VL", 1.22, "Collocation: International; Communication: Some phone, mail");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("L", 1.09, "Collocation: Multi-city and multi-company; Communication: Individual phone, FAX");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("N", 1.00, "Collocation: Multi-city or multi-company; Communication: Narrow-band email");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 0.93, "Collocation: Same city or metro area; Communication: Wide-band electronic communication");
                costDriverObj.ratingList[3] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 0.86, "Collocation: Same building or complex; Communication: Wide-band elect. domm..,");
                costDriverObj.ratingList[4] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("XH", 0.80, "Collocation: Fully colocated; Communication: Interactive multimedia");
                costDriverObj.ratingList[5] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
            
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------Begin
            costDriverObj = new CostDriver(costDriverCategoryObj.name, "Schedule", "");
            costDriverObj.description = "This driver measures the schedule constraint imposed on the project team developing the software. The ratings are defined in terms of % schedule stretch-out or acceleration with respect to a nominal schedule for a project requiring a given amount of effort.";
            costDriverCategoryObj.costDriverList[2] = costDriverObj;
                
                
                ratingLevelObj = new RatingLevel("VL", 1.43, "75% of nominal");
                costDriverObj.ratingList[0] = ratingLevelObj;
                
                ratingLevelObj = new RatingLevel("L", 1.14, "85% of nominal");
                costDriverObj.ratingList[1] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("N", 1.00, "100% of nominal");
                costDriverObj.ratingList[2] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("H", 1.00, "130% of nominal");
                costDriverObj.ratingList[3] = ratingLevelObj;

                ratingLevelObj = new RatingLevel("VH", 1.00, "160% of nominal");
                costDriverObj.ratingList[4] = ratingLevelObj;
                
            //--------------Create a new CostDriver, and add to CostDriverCategory Object--------End
            
        //----------Create a new CostDriverCategory in Javascript-------------------------------------End
        
        //*************************************************************************************************************
        //********Loading Values**********************************************************************************End
        //*************************************************************************************************************
        
        returnValue = true;
        
        if(true == returnValue) {
            this.categoryList = categoryArray;
        }
        
        return(returnValue);
    }
    
    /***************************************
    @return boolean
    ***************************************/  
    function loadCostDriversFromFile(fileName) {
        var returnValue = false;
        
        return(returnValue);      
    }
    
    /***************************************
    @return CostDriverCategory object
    ***************************************/
    function findCostDriverCategory(categoryName) {
        var i;
        
        i=0;
        while((i<this.categoryList.length) && (this.categoryList[i].name != categoryName)) {
            i++;
        }
        
        if(i!=this.categoryList.length) {
            return(this.categoryList[i]);  
        }
        else {
            return(null);
        }
    }
    
}  //End of Class CostDriverCategoryList


/****************************************************************
Class CostDriverCategory
****************************************************************/
function CostDriverCategory(name) {
    this.name = name;
    this.costDriverList = new Array();  //Array    It stores all the Cost Drivers in this Category
    
    //---------Methods Referencing------------begin
    if (typeof(_CostDriverCategory_prototype_called) == 'undefined')  {         //Note: 'undefined' is different from null
         _CostDriverCategory_prototype_called = true;     //Note: This variable name can't be used in global scope. If used, change name.
         CostDriverCategory.prototype.findCostDriver = findCostDriver;
    }
    //---------Methods Referencing------------end
    
    /***************************************
    @return CostDriver object
    ***************************************/
    function findCostDriver(costDriverName) {
        var i;
        
        i=0;
        while((i<this.costDriverList.length) && (this.costDriverList[i].name != costDriverName)) {
            i++;
        }
        
        if(i!=this.costDriverList.length) {
            return(this.costDriverList[i]);  
        }
        else {
            return(null);
        }
    }
}  //End of Class CostDriverCategory


/****************************************************************
Class CostDriver
****************************************************************/
function CostDriver(categoryName, name, description) {
    this.categoryName = categoryName;
    this.name = name;
    this.description = description;
    this.ratingList = new Array();  //Array     It stores all rating levels for this Cost Driver
    
    //---------Methods Referencing------------begin
    if (typeof(_CostDriver_prototype_called) == 'undefined')  {         //Note: 'undefined' is different from null
         _CostDriver_prototype_called = true;     //Note: This variable name can't be used in global scope. If used, change name.
         CostDriver.prototype.findRatingValue = findRatingValue;
    }
    //---------Methods Referencing------------end
    
    /***************************************
    @parameter ratingLevel: String   e.g. "VH", "N", "L"
    @return Double
    ***************************************/
    function findRatingValue(ratingLevel) {
        var i;
        
        i=0;
        while((i<this.ratingList.length) && (this.ratingList[i].level != ratingLevel)) {
            i++;
        }
        
        if(i!=this.ratingList.length) {
            return(this.ratingList[i].value);  
        }
        else {
            return(null);
        }
    }
}  //End of Class CostDriver


/****************************************************************
Class RatingLevel
Description: The RatingLevel class serves both CostDriver and ScaleFactor objects.
****************************************************************/
function RatingLevel(level, value, description) {
    this.level = level;  //String   e.g. "VH", "N", "L"
    this.value = value;  //Double   e.g. 1.00, 2.01
    this.description = description;  //String    e.g. "Risk to human life", "Moderate, easily recoverable losses"
}  //End of Class RatingLevel


/****************************************************************
Class ScaleFactorList
****************************************************************/
function ScaleFactorList() {
    this.scaleFactorList = new Array();  //Array     It stores all Scale Factors.
    
    //---------Methods Referencing------------begin
    if (typeof(_ScaleFactorList_prototype_called) == 'undefined')  {         //Note: 'undefined' is different from null
         _ScaleFactorList_prototype_called = true;     //Note: This variable name can't be used in global scope. If used, change name.
         ScaleFactorList.prototype.loadScaleFactors = loadScaleFactors;
         ScaleFactorList.prototype.loadScaleFactorsFromFile = loadScaleFactorsFromFile;
         ScaleFactorList.prototype.findScaleFactor = findScaleFactor;
    }
    //---------Methods Referencing------------end
    
    /***************************************
    Using for preparation of data
    @return boolean
    ***************************************/
    function loadScaleFactors() {
        var returnValue = false;
        var scaleFactorArray = new Array();
        var scaleFactorObj;
        var ratingLevelObj;
        
        /****Loading Values Example************************************************************************************
        //----------Create a new ScaleFactor in Javascript-------------------------------------Begin
        scaleFactorObj = new ScaleFactor("", "");
        scaleFactorArray[0] = scaleFactorObj;
                
            //--------------Create a new RatingLevel, and add to ScaleFactor Object----Begin
            ratingLevelObj = new RatingLevel("", "", "");
            scaleFactorObj.ratingList[0] = ratingLevelObj;
            //--------------Create a new RatingLevel, and add to ScaleFactor Object----End
            
            //--------------Create a new RatingLevel, and add to ScaleFactor Object----Begin
            ratingLevelObj = new RatingLevel("", "", "");
            scaleFactorObj.ratingList[1] = ratingLevelObj;
            //--------------Create a new RatingLevel, and add to ScaleFactor Object----End
            
            ...
            
        //----------Create a new ScaleFactor in Javascript-------------------------------------End
        
        ...
        
        **************************************************************************************************************/
        
        //*************************************************************************************************************
        //********Loading Values**********************************************************************************Begin
        //*************************************************************************************************************

        //----------Create a new ScaleFactor in Javascript-------------------------------------Begin
        scaleFactorObj = new ScaleFactor("Precedentedness", "");
        //scaleFactorObj.description = "The greater the multiplier value for "+ scaleFactorObj.name +", the more effort paid for the project.";
        scaleFactorObj.description = "This is a gauge of degree of similarity of a previously completed project to the current project. <br>E.g: If the current project is similar to previously developed projects then precedentedness is High. If no past projects are similar to the current project, then the precedentedness is Very low.";
        scaleFactorArray[0] = scaleFactorObj;
                
            //--------------Create new RatingLevels, and add to ScaleFactor Object----Begin
            ratingLevelObj = new RatingLevel("VL", "6.20", "Thoroughly unprecedented");
            scaleFactorObj.ratingList[0] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("L", "4.96", "Largely unprecedented");
            scaleFactorObj.ratingList[1] = ratingLevelObj;
            
            ratingLevelObj = new RatingLevel("N", "3.72", "Somewhat unprecedented");
            scaleFactorObj.ratingList[2] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("H", "2.48", "Generally familiar");
            scaleFactorObj.ratingList[3] = ratingLevelObj;
            
            ratingLevelObj = new RatingLevel("VH", "1.24", "Largely familiar");
            scaleFactorObj.ratingList[4] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("XH", "0.00", "Thoroughly familiar");
            scaleFactorObj.ratingList[5] = ratingLevelObj;
            //--------------Create new RatingLevels, and add to ScaleFactor Object----End
            
        //----------Create a new ScaleFactor in Javascript-------------------------------------End
        
        //----------Create a new ScaleFactor in Javascript-------------------------------------Begin
        scaleFactorObj = new ScaleFactor("Development Flexibility", "");
        //scaleFactorObj.description = "The greater the multiplier value for "+ scaleFactorObj.name +", the more effort paid for the project.";
        scaleFactorObj.description = "This is a gauge of the need for software conformance with pre-established requirements and external interface specifications. Higher need for conformance leads to lower rating levels for this scale factor.";
        scaleFactorArray[1] = scaleFactorObj;
                
            //--------------Create new RatingLevels, and add to ScaleFactor Object----Begin
            ratingLevelObj = new RatingLevel("VL", "5.07", "Rigorous");
            scaleFactorObj.ratingList[0] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("L", "4.05", "Occasional relaxation");
            scaleFactorObj.ratingList[1] = ratingLevelObj;
            
            ratingLevelObj = new RatingLevel("N", "3.04", "Some relaxation");
            scaleFactorObj.ratingList[2] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("H", "2.03", "General conformity");
            scaleFactorObj.ratingList[3] = ratingLevelObj;
            
            ratingLevelObj = new RatingLevel("VH", "1.01", "Some conformity");
            scaleFactorObj.ratingList[4] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("XH", "0.00", "General goals");
            scaleFactorObj.ratingList[5] = ratingLevelObj;
            //--------------Create new RatingLevels, and add to ScaleFactor Object----End
            
        //----------Create a new ScaleFactor in Javascript-------------------------------------End
        
        //----------Create a new ScaleFactor in Javascript-------------------------------------Begin
        scaleFactorObj = new ScaleFactor("Architecture/Risk Resolution", "");
	//scaleFactorObj.description = "The greater the multiplier value for "+ scaleFactorObj.name +", the more effort paid for the project.";
        scaleFactorObj.description = "This is a gauge of the quality of risk management to be performed through-out the project, risks with the project architecture and any measures available for resolution of such risks.";
        scaleFactorArray[2] = scaleFactorObj;
                
            //--------------Create new RatingLevels, and add to ScaleFactor Object----Begin
            ratingLevelObj = new RatingLevel("VL", "7.07", "Little");
            scaleFactorObj.ratingList[0] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("L", "5.65", "Some");
            scaleFactorObj.ratingList[1] = ratingLevelObj;
            
            ratingLevelObj = new RatingLevel("N", "4.24", "Often");
            scaleFactorObj.ratingList[2] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("H", "2.83", "Generally");
            scaleFactorObj.ratingList[3] = ratingLevelObj;
            
            ratingLevelObj = new RatingLevel("VH", "1.41", "Mostly");
            scaleFactorObj.ratingList[4] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("XH", "0.00", "Full");
            scaleFactorObj.ratingList[5] = ratingLevelObj;
            //--------------Create new RatingLevels, and add to ScaleFactor Object----End
            
        //----------Create a new ScaleFactor in Javascript-------------------------------------End
        
        //----------Create a new ScaleFactor in Javascript-------------------------------------Begin
        scaleFactorObj = new ScaleFactor("Team Cohesion", "");
        //scaleFactorObj.description = "The greater the multiplier value for "+ scaleFactorObj.name +", the more effort paid for the project.";
	        scaleFactorObj.description = "This accounts for turbulence in a project because of conflicts between stakeholders, their differing objectives and their overall lack of experience in operating as a cohesive team.";
        scaleFactorArray[3] = scaleFactorObj;
                
            //--------------Create new RatingLevels, and add to ScaleFactor Object----Begin
            ratingLevelObj = new RatingLevel("VL", "5.48", "Very difficult interactions");
            scaleFactorObj.ratingList[0] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("L", "4.38", "Some difficult interactions");
            scaleFactorObj.ratingList[1] = ratingLevelObj;
            
            ratingLevelObj = new RatingLevel("N", "3.29", "Basically cooperative interactions");
            scaleFactorObj.ratingList[2] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("H", "2.19", "Largely cooperative");
            scaleFactorObj.ratingList[3] = ratingLevelObj;
            
            ratingLevelObj = new RatingLevel("VH", "1.10", "Highly cooperative");
            scaleFactorObj.ratingList[4] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("XH", "0.00", "Seamless interactions");
            scaleFactorObj.ratingList[5] = ratingLevelObj;
            //--------------Create new RatingLevels, and add to ScaleFactor Object----End
            
        //----------Create a new ScaleFactor in Javascript-------------------------------------End
        
        //----------Create a new ScaleFactor in Javascript-------------------------------------Begin
        scaleFactorObj = new ScaleFactor("Process Maturity", "");
        //scaleFactorObj.description = "The greater the multiplier value for "+ scaleFactorObj.name +", the more effort paid for the project.";
	        scaleFactorObj.description = "These ratings are organized around the SEI CMM model.";
        scaleFactorArray[4] = scaleFactorObj;
                
            //--------------Create new RatingLevels, and add to ScaleFactor Object----Begin
            ratingLevelObj = new RatingLevel("VL", "7.80", "PMATSW-CMM Level 1 Lower");
            scaleFactorObj.ratingList[0] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("L", "6.24", "SW-CMM Level 1 Upper");
            scaleFactorObj.ratingList[1] = ratingLevelObj;
            
            ratingLevelObj = new RatingLevel("N", "4.68", "SW-CMM Level 2");
            scaleFactorObj.ratingList[2] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("H", "3.12", "SW-CMM Level 3");
            scaleFactorObj.ratingList[3] = ratingLevelObj;
            
            ratingLevelObj = new RatingLevel("VH", "1.56", "SW-CMM Level 4");
            scaleFactorObj.ratingList[4] = ratingLevelObj;

            ratingLevelObj = new RatingLevel("XH", "0.00", "SW-CMM Level 5");
            scaleFactorObj.ratingList[5] = ratingLevelObj;
            //--------------Create new RatingLevels, and add to ScaleFactor Object----End
            
        //----------Create a new ScaleFactor in Javascript-------------------------------------End
        
        //*************************************************************************************************************
        //********Loading Values**********************************************************************************End
        //*************************************************************************************************************

        returnValue = true;
        
        if(true == returnValue) {
            this.scaleFactorList = scaleFactorArray;
        }
        
        return(returnValue);
    }
    
    /***************************************
    @return boolean
    ***************************************/  
    function loadScaleFactorsFromFile(fileName) {
        var returnValue = false;
        
        return(returnValue);
    }
    
    /***************************************
    @return ScaleFactor object
    ***************************************/
    function findScaleFactor(scaleFactorName) {
        var i;
        
        i=0;
        while((i<this.scaleFactorList.length) && (this.scaleFactorList[i].name != scaleFactorName)) {
            i++;
        }
        
        if(i!=this.scaleFactorList.length) {
            return(this.scaleFactorList[i]);  
        }
        else {
            return(null);
        }
    }
    
}  //End of Class ScaleFactorList


/****************************************************************
Class ScaleFactor
****************************************************************/
function ScaleFactor(name, description) {
    this.name = name;
    this.description = description;
    this.ratingList = new Array();  //Array     It stores all rating levels for this Scale Factor
    
    //---------Methods Referencing------------begin
    if (typeof(_ScaleFactor_prototype_called) == 'undefined')  {         //Note: 'undefined' is different from null
         _ScaleFactor_prototype_called = true;     //Note: This variable name can't be used in global scope. If used, change name.
         ScaleFactor.prototype.findRatingValue = findRatingValue;
    }
    //---------Methods Referencing------------end
    
    /***************************************
    @parameter ratingLevel: String   e.g. "VH", "N", "L"
    @return Double
    ***************************************/
    function findRatingValue(ratingLevel) {
        var i;
        
        i=0;
        while((i<this.ratingList.length) && (this.ratingList[i].level != ratingLevel)) {
            i++;
        }
        
        if(i!=this.ratingList.length) {
            return(this.ratingList[i].value);  
        }
        else {
            return(null);
        }
    }
    
}  //End of Class ScaleFactor


/****************************************************************
Class Estimation
****************************************************************/
function Estimation(basisType, basisObject, lastRatingLevel, currentRatingLevel) {
    this.basisType = basisType;  //String   "Cost Driver" or "Scale Factor"
    this.basisObject = basisObject;  //CostDriver or Scale Factor object
    this.lastRatingLevel = lastRatingLevel;  //String    e.g.  "VH", "N", "L"
    this.currentRatingLevel = currentRatingLevel;  //String     e.g.  "VH", "N", "L"
    
    //---------Methods Referencing------------begin
    if (typeof(_Estimation_prototype_called) == 'undefined')  {         //Note: 'undefined' is different from null
         _Estimation_prototype_called = true;     //Note: This variable name can't be used in global scope. If used, change name.
         Estimation.prototype.calculateCurrentCost = calculateCurrentCost;
         Estimation.prototype.calculateCurrentPM = calculateCurrentPM;
    }
    //---------Methods Referencing------------end
    
    /***************************************
    @parameter lastCost: Double   The calculated Cost for the last estimation.
    @parameter currentKSLOC  Integer       The KSLOC value for the current project.
    @return Double     The current Cost
    ***************************************/
    function calculateCurrentCost(lastCost, currentKSLOC) {
        var currentCost = NaN;  //Double
        var lastRatingValue;
        var currentRatingValue;
        
        if (isNaN(lastCost)) {
            //alert("lastCost NaN");
            currentCost = NaN;
        } else {
            lastRatingValue = this.basisObject.findRatingValue(this.lastRatingLevel);
            currentRatingValue = this.basisObject.findRatingValue(this.currentRatingLevel);
            
            if ("Scale Factor" == this.basisType) {  //For "Scale Factor"
                if (isNaN(currentKSLOC)) {
	             alert("currentKSLOC NaN");
	             currentCost = NaN;
        	}
        
        	lastRatingValue = Math.pow(currentKSLOC, (0.91 + lastRatingValue/100));
                currentRatingValue = Math.pow(currentKSLOC, (0.91 + currentRatingValue/100));
            }
            
            currentCost = lastCost * (currentRatingValue / lastRatingValue);
        }
        
        return(currentCost);
    }  //End of function calculateCurrentCost

    /***************************************
    @parameter lastCost: Double   The calculated Cost for the last estimation.
    @parameter currentKSLOC  Integer       The KSLOC value for the current project.
    @return Double     The current Cost
    ***************************************/
    function calculateCurrentPM(lastPM, currentKSLOC) {
        var currentPM = NaN;  //Double
        var lastRatingValue;
        var currentRatingValue;
        
        if (isNaN(lastPM)) {
            //alert("lastPM NaN");
            currentPM = NaN;
        } else {
            lastRatingValue = this.basisObject.findRatingValue(this.lastRatingLevel);
            currentRatingValue = this.basisObject.findRatingValue(this.currentRatingLevel);
            
            if ("Scale Factor" == this.basisType) {  //For "Scale Factor"
                if (isNaN(currentKSLOC)) {
	             alert("currentKSLOC NaN");
	             currentPM = NaN;
        	}
        
        	lastRatingValue = Math.pow(currentKSLOC, (0.91 + lastRatingValue/100));
                currentRatingValue = Math.pow(currentKSLOC, (0.91 + currentRatingValue/100));
            }
            
            currentPM = lastPM * (currentRatingValue / lastRatingValue);
        }
        
        return(currentPM);
    }  //End of function calculateCurrentPM
    
}  //End of Class Estimation


//----------Javascript Class Definition----------------------------------------------End
