
function GetSelectionArray()
{
  var retVal = new Array();
  retVal[retVal.length] = this.pc_periodic_oral_exam;
  retVal[retVal.length] = this.pc_bite_wing_x_rays;
  retVal[retVal.length] = this.pc_dental_cleanings;
  retVal[retVal.length] = this.pc_fluoride_treatments;
  retVal[retVal.length] = this.pc_sealants;
  retVal[retVal.length] = this.pc_space_maintainers;
  retVal[retVal.length] = this.bmc_complete_series;
  retVal[retVal.length] = this.bmc_amalgam_fillings;
  retVal[retVal.length] = this.bmc_composite_resin_fillings;
  retVal[retVal.length] = this.bmc_root_canal;
  retVal[retVal.length] = this.bmc_periodontal_surgery;
  retVal[retVal.length] = this.bmc_root_planing;
  retVal[retVal.length] = this.bmc_surgical_extraction;
  retVal[retVal.length] = this.bmc_general_anesthesia;
  retVal[retVal.length] = this.bmc_crowns;
  retVal[retVal.length] = this.bmc_fixed_bridges;
  retVal[retVal.length] = this.bmc_full_upper_or_lower_dentures;
  retVal[retVal.length] = this.bmc_inlays_and_onlays;
  retVal[retVal.length] = this.bmc_partial_dentures;
  retVal[retVal.length] = this.bmc_recement;
  retVal[retVal.length] = this.bmc_relining_dentures;
  retVal[retVal.length] = this.bmc_repairs;
  retVal[retVal.length] = this.oc_Child;
  retVal[retVal.length] = this.oc_Adult;
  return retVal;
}

function GetItemById(inId)
{
  var retVal = null;
  var myArray = this.GetSelectionArray();
  for (var i=0; i < myArray.length; i++)
  {
   var oneItem = myArray[i];
    if (myArray[i].id == inId)
    {
      retVal = myArray[i];
      break;
    }
  }
  return retVal;
}

function UserSelections()
{
  this.coverage_level_type = "";
  this.pc_periodic_oral_exam = new CostAttributes("C_1", 0);
  this.pc_bite_wing_x_rays = new CostAttributes("C_2", 0);
  this.pc_dental_cleanings = new CostAttributes("C_3", 0);
  this.pc_fluoride_treatments = new CostAttributes("C_4", 0);
  this.pc_sealants = new CostAttributes("C_5", 0);
  this.pc_space_maintainers = new CostAttributes("C_6", 0);
  this.bmc_complete_series = new CostAttributes("C_7", 0);
  this.bmc_amalgam_fillings = new CostAttributes("C_8", 0);
  this.bmc_composite_resin_fillings = new CostAttributes("C_9", 0);
  this.bmc_root_canal = new CostAttributes("C_10", 0);
  this.bmc_periodontal_surgery = new CostAttributes("C_11", 0);
  this.bmc_root_planing = new CostAttributes("C_12", 0);
  this.bmc_surgical_extraction = new CostAttributes("C_13", 0);
  this.bmc_general_anesthesia = new CostAttributes("C_14", 0);
  this.bmc_crowns = new CostAttributes("C_15", 0);
  this.bmc_fixed_bridges = new CostAttributes("C_16", 0);
  this.bmc_full_upper_or_lower_dentures = new CostAttributes("C_17", 0);
  this.bmc_inlays_and_onlays = new CostAttributes("C_18", 0);
  this.bmc_partial_dentures = new CostAttributes("C_19", 0);
  this.bmc_recement = new CostAttributes("C_20", 0);
  this.bmc_relining_dentures = new CostAttributes("C_21", 0);
  this.bmc_repairs = new CostAttributes("C_22", 0);
  this.oc_Child = new CostAttributes("C_23", 0);
  this.oc_Adult = new CostAttributes("C_24", 0);
}
UserSelections.prototype.GetSelectionArray = GetSelectionArray;
UserSelections.prototype.GetItemById = GetItemById;


function SetCopay()
{
  this.coinsurance_flag = false;
  this.categoryId = "";
}

function SetCoinsurance(inCategoryId)
{
  this.coinsurance_flag = true;
  this.categoryId = inCategoryId;
}

function SetEligible()
{
  this.eligibleInd = true;
}

function SetIneligible()
{
  this.eligibleInd = false;
}

function IsCopay()
{
  return !this.coinsurance_flag;
}

function IsCoinsurance()
{
  return this.coinsurance_flag;
}

function IsEligible()
{
  return this.eligibleInd;
}

function IsTowardsDeductible()
{
  return this.towardsDeductible;
}

function IsTowardsEmployerLimit()
{
  return this.towardsEmployerLimit;
}

function CostAttributes(inId,inAmount)
{ 
  this.id = inId;
  this.coinsurance_flag = false;
  this.categoryId = "";
  this.amount = inAmount;
  this.towardsDeductible = true;
  this.towardsEmployerLimit = true;
  this.eligibleInd = true;
}
CostAttributes.prototype.SetEligible = SetEligible;
CostAttributes.prototype.SetIneligible = SetIneligible;
CostAttributes.prototype.SetCopay = SetCopay;
CostAttributes.prototype.SetCoinsurance = SetCoinsurance;
CostAttributes.prototype.IsEligible = IsEligible;
CostAttributes.prototype.IsCopay = IsCopay;
CostAttributes.prototype.IsCoinsurance = IsCoinsurance;
CostAttributes.prototype.IsTowardsDeductible = IsTowardsDeductible;
CostAttributes.prototype.IsTowardsEmployerLimit = IsTowardsEmployerLimit;


function GetCostArray()
{
  var retVal = new Array();
  retVal[retVal.length] = this.pc_periodic_oral_exam;
  retVal[retVal.length] = this.pc_bite_wing_x_rays;
  retVal[retVal.length] = this.pc_dental_cleanings;
  retVal[retVal.length] = this.pc_fluoride_treatments;
  retVal[retVal.length] = this.pc_sealants;
  retVal[retVal.length] = this.pc_space_maintainers;
  retVal[retVal.length] = this.bmc_complete_series;
  retVal[retVal.length] = this.bmc_amalgam_fillings;
  retVal[retVal.length] = this.bmc_composite_resin_fillings;
  retVal[retVal.length] = this.bmc_root_canal;
  retVal[retVal.length] = this.bmc_periodontal_surgery;
  retVal[retVal.length] = this.bmc_root_planing;
  retVal[retVal.length] = this.bmc_surgical_extraction;
  retVal[retVal.length] = this.bmc_general_anesthesia;
  retVal[retVal.length] = this.bmc_crowns;
  retVal[retVal.length] = this.bmc_fixed_bridges;
  retVal[retVal.length] = this.bmc_full_upper_or_lower_dentures;
  retVal[retVal.length] = this.bmc_inlays_and_onlays;
  retVal[retVal.length] = this.bmc_partial_dentures;
  retVal[retVal.length] = this.bmc_recement;
  retVal[retVal.length] = this.bmc_relining_dentures;
  retVal[retVal.length] = this.bmc_repairs;
  retVal[retVal.length] = this.oc_Child;
  retVal[retVal.length] = this.oc_Adult;

  return retVal;
}

function GetDeductibleArray()
{
  var retVal = new Array();
  var tempArray = this.GetCostArray();

  for (var i=0; i < tempArray.length; i++)
  {
    var oneCost = tempArray[i];
    if (oneCost.IsTowardsDeductible())
    {
      retVal[retVal.length] = oneCost;
    }
  }
  return retVal;
}

function GetNotAgainstDeductibleArray()
{
  var retVal = new Array();
  var tempArray = this.GetCostArray();

  for (var i=0; i < tempArray.length; i++)
  {
    var oneCost = tempArray[i];
    if (!oneCost.IsTowardsDeductible())
    {
      retVal[retVal.length] = oneCost;
    }
  }
  return retVal;
}

function GetCoinsuranceArray(inCategoryId)
{
  var retVal = new Array();
  var tempArray = this.GetCostArray();
  for (var i=0; i < tempArray.length; i++)
  {
    var oneCost = tempArray[i];
    if (oneCost.coinsurance_flag && oneCost.categoryId == inCategoryId)
    {
      retVal[retVal.length] = oneCost;
    }
  }
  return retVal;
}

function GetAllCoinsuranceArray()
{
  var retVal = new Array();
  var tempArray = this.GetCostArray();
  for (var i=0; i < tempArray.length; i++)
  {
    var oneCost = tempArray[i];
    if (oneCost.coinsurance_flag)
    {
      retVal[retVal.length] = oneCost;
    }
  }
  return retVal;
}

function GetCopayArray()
{
  var retVal = new Array();
  var tempArray = this.GetCostArray();
  for (var i=0; i < tempArray.length; i++)
  {
    var oneCost = tempArray[i];
    if (!oneCost.coinsurance_flag)
    {
      retVal[retVal.length] = oneCost;
    }
  }
  return retVal;
}

function CalculateCopayCost( inUserSelections )
{
  var retVal = 0;
  var costArray = this.GetCopayArray();
  var userSelectionArray = inUserSelections.GetSelectionArray();

  for (var i=0; i < userSelectionArray.length; i++)
  {
    var oneUserSelect = userSelectionArray[i];
    if (oneUserSelect.amount > 0)
    {
      for (var j=0; j < costArray.length; j++ )
      {
        var oneCost = costArray[j];
        if (oneUserSelect.id == oneCost.id)
        {
          retVal = retVal + (oneUserSelect.amount * oneCost.amount);
        }
      }
    }
  }
  return retVal;
}

function CalculateCoinsuranceCost( inUserSelections, inCategoryId )
{
  var retVal = 0;
  var myTotal = 0;
  var costArray = this.GetCoinsuranceArray(inCategoryId);

  var userSelectionArray = inUserSelections.GetSelectionArray();

  for (var i=0; i < userSelectionArray.length; i++)
  {
    var oneUserSelect = userSelectionArray[i];
    if (oneUserSelect.amount > 0)
    {
      for (var j=0; j < costArray.length; j++ )
      {
        var oneCost = costArray[j];
        if (oneUserSelect.id == oneCost.id)
        {
          myTotal = myTotal + (oneUserSelect.amount * oneCost.amount);
        }
      }
    }
  }

  var myPercentage = this.parent_plan.GetCategoryPercentage(inCategoryId);
  retVal = myTotal * myPercentage;

  return retVal;
}

function CalculateTotalCost( inUserSelections )
{
  var retVal = 0;
  var costArray = this.GetCostArray();
  var userSelectionArray = inUserSelections.GetSelectionArray();

  for (var i=0; i < userSelectionArray.length; i++)
  {
    var oneUserSelect = userSelectionArray[i];
    if (oneUserSelect.amount > 0)
    {
      for (var j=0; j < costArray.length; j++ )
      {
        var oneCost = costArray[j];
        if (oneUserSelect.id == oneCost.id)
        {
          retVal = retVal + (oneUserSelect.amount * oneCost.amount);
        }
      }
    }
  }
  return retVal;
}

function GetServiceCostById(inId)
{
  var retVal = null;
  var myArray = this.GetCostArray();
  for (var i=0; i < myArray.length; i++)
  {
    var oneItem = myArray[i];
    if (myArray[i].id == inId)
    {
      retVal = myArray[i];
      break;
    }
  }
  return retVal;
}

function ServiceCosts(p0, p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24)
{
  this.parent_plan = p0;
  this.pc_periodic_oral_exam = new CostAttributes("C_1", p1);
  this.pc_bite_wing_x_rays = new CostAttributes("C_2",p2);
  this.pc_dental_cleanings = new CostAttributes("C_3",p3);
  this.pc_fluoride_treatments = new CostAttributes("C_4",p4);
  this.pc_sealants = new CostAttributes("C_5",p5);
  this.pc_space_maintainers = new CostAttributes("C_6",p6);
  this.bmc_complete_series = new CostAttributes("C_7",p7);
  this.bmc_amalgam_fillings = new CostAttributes("C_8",p8);
  this.bmc_composite_resin_fillings = new CostAttributes("C_9",p9);
  this.bmc_root_canal = new CostAttributes("C_10",p10);
  this.bmc_periodontal_surgery = new CostAttributes("C_11",p11);
  this.bmc_root_planing = new CostAttributes("C_12",p12);
  this.bmc_surgical_extraction = new CostAttributes("C_13",p13);
  this.bmc_general_anesthesia = new CostAttributes("C_14",p14);
  this.bmc_crowns = new CostAttributes("C_15",p15);
  this.bmc_fixed_bridges = new CostAttributes("C_16",p16);
  this.bmc_full_upper_or_lower_dentures = new CostAttributes("C_17",p17);
  this.bmc_inlays_and_onlays = new CostAttributes("C_18",p18);
  this.bmc_partial_dentures = new CostAttributes("C_19",p19);
  this.bmc_recement = new CostAttributes("C_20",p20);
  this.bmc_relining_dentures = new CostAttributes("C_21",p21);
  this.bmc_repairs = new CostAttributes("C_22",p22);
  this.oc_Child = new CostAttributes("C_23",p23);
  this.oc_Adult = new CostAttributes("C_24",p24);
}
ServiceCosts.prototype.GetDeductibleArray = GetDeductibleArray;
ServiceCosts.prototype.GetCostArray = GetCostArray;
ServiceCosts.prototype.GetCopayArray = GetCopayArray;
ServiceCosts.prototype.GetAllCoinsuranceArray = GetAllCoinsuranceArray;
ServiceCosts.prototype.GetCoinsuranceArray = GetCoinsuranceArray;
ServiceCosts.prototype.CalculateCopayCost = CalculateCopayCost;
ServiceCosts.prototype.CalculateCoinsuranceCost = CalculateCoinsuranceCost;
ServiceCosts.prototype.CalculateTotalCost = CalculateTotalCost;
ServiceCosts.prototype.GetNotAgainstDeductibleArray = GetNotAgainstDeductibleArray;
ServiceCosts.prototype.GetServiceCostById = GetServiceCostById;

function CoverageLevelCosts(p1, p2, p3, p4, p5)
{
  this.coverage_level_type = p1;
  this.people_count = p2;
  this.annual_deductible = p3;
  this.calendar_year_maximum = p4;
  this.monthly_premium = p5;
}

function CalculateGeneric(inUserSelections, inRcCosts)
{
  var myTempValue = 0;
  var retVal = true;

  var coverageCosts = this.GetCoverageCosts(inUserSelections.coverage_level_type);

  if (coverageCosts != null)
  {        
    //Get Costs Against Deductible
    var employerTotal = 0;
    var deductibleTotal = 0;
    var copayTotal = 0;
    var coinsuranceTotal = 0;
    var expensesNotCoveredTotal = 0;
    var fixedLimitTotal = 0;

    var HasItemFixedLimit = false;

    //Get All Cost Items that Go Towards Deductible
    var myCostArray = this.service_costs.GetCostArray();

    //Loop Through All Cost Items that Go Towards Deductible
    for (var i=0; i < myCostArray.length; i++)
    {
       var oneCostItem = myCostArray[i];
       var oneItemCost = oneCostItem.amount;
       var myCategoryId = oneCostItem.categoryId;
       var itemFixedLimit = null;

       //Check For Fixed Employer Limit
       if (myCategoryId != null && myCategoryId != "")
       {
         var itemFixedLimit = this.GetCategoryFixedLimit( myCategoryId );
         if (itemFixedLimit != null)
         {
           HasItemFixedLimit = true;
           fixedLimitTotal = 0;
         }
       }

       //Lookup Regular & Expected Cost For current Cost Item
       var oneExpectedCostItem = inRcCosts.GetServiceCostById( oneCostItem.id );
       var fullCost = oneExpectedCostItem.amount;

       //Get what User Selected for this Cost Item
       var oneUserItem = inUserSelections.GetItemById( oneCostItem.id );

       //Did select at least 1 service?
       if (!oneCostItem.IsEligible())
       {
         expensesNotCoveredTotal = expensesNotCoveredTotal + ( fullCost * oneUserItem.amount );                         
       }
       else if (oneUserItem.amount > 0)
       {

         //START ITEM LOOP: Loop Through Each Seperate Cost Item (ie. if user picked 10 X-Rays then loop 10 times)
         for (var c=0; c < oneUserItem.amount; c++)
         {  
           var employerAmount = 0;
           var deductibleAmount = 0;
           var copayAmount = 0;
           var coinsuranceAmount = 0;
           var expenseNotCovered = 0

           employerAmount = 0;
           employeeAmount = fullCost;

           //Check Against Deductible First
           if (oneCostItem.IsTowardsDeductible() && employeeAmount > 0 && (coverageCosts.annual_deductible > deductibleTotal) )
           {
             var deductibleRemaining = coverageCosts.annual_deductible - deductibleTotal;
             if (deductibleRemaining > employeeAmount)
             {
               deductibleAmount = employeeAmount;
               employeeAmount = 0;
             }
             else
             {
               deductibleAmount = deductibleRemaining;
               employeeAmount = employeeAmount - deductibleRemaining;
             }
           }


           if (oneCostItem.IsCopay())
           {
             //============COPAY:START             
             //See If we have met the Deductible BEFORE Employer portion "OR" Implied No Limit

             if ( employeeAmount > 0 && (!oneCostItem.IsTowardsDeductible() || ((deductibleTotal + deductibleAmount) >= coverageCosts.annual_deductible)) )
             {
               //Split Payment with Employer Now that the Deductible has been Met

               //How much Empolyer Willing To Pay?
               var amountEmployerWillingToPay = fullCost - oneItemCost;
               if (employeeAmount >= amountEmployerWillingToPay)
               {
                 employerAmount = amountEmployerWillingToPay;
                 employeeAmount = employeeAmount - amountEmployerWillingToPay;
               }
               else
               {
                 employerAmount = employeeAmount;
                 employeeAmount = 0;             
               }

               //Check if Employer asked to Pay
               if (!oneCostItem.IsTowardsEmployerLimit())
               {
                 //An implied no Limit On Employer Co-Payments Here
                 copayAmount = employeeAmount;
                 employeeAmount = 0;
               }
               else
               {
                 //Check for an Employer Portion
                 if (employerAmount > 0)
                 {
                   //Any Room Left In Employer Limit?
                   if (coverageCosts.calendar_year_maximum > employerTotal)
                   {
                     var employerLimitRemaining = coverageCosts.calendar_year_maximum - employerTotal;
                     if (employerLimitRemaining > employerAmount)
                     {
                       //Nothing, Employer pays this full Employer Amount, Employee makes Co-Payment
                       copayAmount = employeeAmount;
                       employeeAmount = 0;
                     } 
                     else
                     {                   
                       var overEmployerAmount = employerAmount - employerLimitRemaining;
                       employerAmount = employerLimitRemaining;
                       copayAmount = employeeAmount;
                       employeeAmount = overEmployerAmount;
                     }
    
                     //Check Employers Item Limit (if exists)
                     if (HasItemFixedLimit && employerAmount > 0)
                     {
                       var fixedLimitRoom = itemFixedLimit - fixedLimitTotal;
                       if (fixedLimitLimitRoom > employerAmount)
                       {
                         fixedLimitTotal = fixedLimitTotal + employerTotal;
                       }
                       else
                       {
                         var overLimit = employerAmount - fixedLimitRoom;
                         employerAmount = fixedLimitRoom;
                         employeeAmount = employeeAmount + overLimit;
                       }
                     }
                   }
                   else
                   {
                     //Employer Cannot Help At All, He's At His Maximum
                     employeeAmount = employeeAmount + employerAmount;
                     employerAmount = 0;
                   }
                 }
               }
             }
             //============COPAY: END

           }
           else
           {

             //============COINSURANCE: START
             //Get Co-Insurance Percentage For current Cost Item
             var myPercentage = this.GetCategoryPercentage( myCategoryId );

             if (myPercentage == null || myPercentage >= 1)
             {
               coinsuranceAmount =  employeeAmount;
             }
             else
             {
               //See If we have met the Deductible BEFORE Employer portion "OR" an implied No Employer Limit
               if ( employeeAmount > 0 && (!oneCostItem.IsTowardsDeductible() || ((deductibleTotal + deductibleAmount) >= coverageCosts.annual_deductible)) )
               {
                 //Reduce Amount Now
                 var originalAmount = employeeAmount;
                 var employeeAmount = originalAmount * myPercentage;
                 var employerAmount = originalAmount - employeeAmount;                    

                 if (!oneCostItem.IsTowardsEmployerLimit())
                 { 
                   //An implied no Limit On Employer Co-Insurance Here
                   coinsuranceAmount = employeeAmount;
                   employeeAmount = 0;
                 }
                 else
                 {
                   //Check for and Employer Amount
                   if (employerAmount > 0)
                   {
                     //Check for Employer Room
                     if (coverageCosts.calendar_year_maximum > employerTotal)
                     {
                       var employerLimitRemaining = coverageCosts.calendar_year_maximum - employerTotal;
                       if (employerLimitRemaining > employerAmount)
                       {  
                         coinsuranceAmount = employeeAmount;
                         employeeAmount = 0;
                       }
                       else
                       {
                         var overEmployerAmount = employerAmount - employerLimitRemaining;
                         employerAmount = employerLimitRemaining;
                         coinsuranceAmount = employeeAmount;
                         employeeAmount = overEmployerAmount;
                       }

                       //Check Employers Item Limit (if exists)
                       if (HasItemFixedLimit && employerAmount > 0)
                       {
                         var fixedLimitRoom = itemFixedLimit - fixedLimitTotal;
                         if (fixedLimitLimitRoom > employerAmount)
                         {
                           fixedLimitTotal = fixedLimitTotal + employerTotal;
                         }
                         else
                         {
                           var overLimit = employerAmount - fixedLimitRoom;
                           employerAmount = fixedLimitRoom;
                           employeeAmount = employeeAmount + overLimit;
                         }
                       }
                     }
                     else
                     {
                       //Employer Cannot Help At All
                       employeeAmount = employeeAmount + employerAmount;
                       employerAmount = 0;
                     } 
                   }
                 }
               }
             }
//============COINSURANCE: END
             
           }
		   
		   //Remaining Employee Costs are put in "Expenses Not Covered"
             expenseNotCovered = employeeAmount;   
             employeeAmount = 0;

           //Add Item Values to Total Buckets
           employerTotal = employerTotal + employerAmount;
           deductibleTotal = deductibleTotal + deductibleAmount;
           copayTotal = copayTotal + copayAmount;
           coinsuranceTotal = coinsuranceTotal + coinsuranceAmount;
           expensesNotCoveredTotal = expensesNotCoveredTotal + expenseNotCovered;

           //alert( "(ITEM) employerAmount=" + employerAmount + " deductibleAmount=" + deductibleAmount + " copayAmount=" + copayAmount + " coinsuranceAmount=" + coinsuranceAmount + " expenseNotCovered:" + expenseNotCovered );
           //alert( "(TOTALS) DEDUCTIBLE: " + deductibleTotal + " EMPLOYER TT:" + employerTotal  + " ENC:" + expensesNotCoveredTotal + " COINS:" + coinsuranceTotal + " COPAY:" + copayTotal );

           //END ITEM LOOP
         }   
       }
     } 

     this.annualDeductibles = deductibleTotal;
     this.copays = copayTotal;
     this.coinsurance = coinsuranceTotal;
     this.expenses_not_covered = expensesNotCoveredTotal;
     this.total_cost_of_care = this.annualDeductibles + this.copays + this.coinsurance + this.expenses_not_covered;
     this.annual_insurance_premium = coverageCosts.monthly_premium;
     this.estimated_total_annual_expense = this.total_cost_of_care + this.annual_insurance_premium;
   }
   else
   {
     alert("Plan: " + this.title + " No Matching Coverage found for: " + inUserSelections.coverage_level_type );
     retVal = false;
   }
   return retVal;
}

function Calculate1(inUserSelections, inRcCosts)
{
  var myTempValue = 1;
  var retVal = true;
  var coverageCosts = this.GetCoverageCosts(inUserSelections.coverage_level_type);
  if (coverageCosts != null)
  {
    this.annualDeductibles = myTempValue;
    this.copays = myTempValue;
    this.coinsurance = myTempValue;
    this.expenses_not_covered = myTempValue;
    this.total_cost_of_care = myTempValue;
    this.annual_insurance_premium = myTempValue;
    this.estimated_total_annual_expense = myTempValue;
  }
  else
  {
    alert("Plan: " + this.title + " No Matching Coverage found for: " + inUserSelections.coverage_level_type );
    retVal = false;
  }
  return retVal;
}

function Calculate_DHMO(inUserSelections, inRcCosts)
{
  var myTempValue = 4;
  var retVal = true;
  var coverageCosts = this.GetCoverageCosts(inUserSelections.coverage_level_type);

  if (coverageCosts != null)
  {
    this.annualDeductibles = 0
    this.copays = 0;
    this.coinsurance = 0;
    this.expenses_not_covered = 0;
    this.total_cost_of_care = 0;
    this.annual_insurance_premium = 0;
    this.estimated_total_annual_expense = 0;

    //Annual Premium lookup
    this.annual_insurance_premium = coverageCosts.monthly_premium;

    //Calculate Copays
    this.copays = ( inUserSelections.pc_periodic_oral_exam.amount * this.service_costs.pc_periodic_oral_exam.amount ) +
                  ( inUserSelections.pc_bite_wing_x_rays.amount * this.service_costs.pc_bite_wing_x_rays.amount ) +
                  ( inUserSelections.pc_dental_cleanings.amount * this.service_costs.pc_dental_cleanings.amount ) +
                  ( inUserSelections.pc_fluoride_treatments.amount * this.service_costs.pc_fluoride_treatments.amount ) +
                  ( inUserSelections.pc_sealants.amount * this.service_costs.pc_sealants.amount ) +
                  ( inUserSelections.pc_space_maintainers.amount * this.service_costs.pc_space_maintainers.amount ) +
                  ( inUserSelections.bmc_complete_series.amount * this.service_costs.bmc_complete_series.amount ) +
                  ( inUserSelections.bmc_amalgam_fillings.amount * this.service_costs.bmc_amalgam_fillings.amount ) +
                  ( inUserSelections.bmc_composite_resin_fillings.amount * this.service_costs.bmc_composite_resin_fillings.amount ) +
                  ( inUserSelections.bmc_root_canal.amount * this.service_costs.bmc_root_canal.amount ) +
                  ( inUserSelections.bmc_periodontal_surgery.amount * this.service_costs.bmc_periodontal_surgery.amount ) +
                  ( inUserSelections.bmc_root_planing.amount * this.service_costs.bmc_root_planing.amount ) +
                  ( inUserSelections.bmc_surgical_extraction.amount * this.service_costs.bmc_surgical_extraction.amount ) +
                  ( inUserSelections.bmc_general_anesthesia.amount * this.service_costs.bmc_general_anesthesia.amount ) +
                  ( inUserSelections.bmc_crowns.amount * this.service_costs.bmc_crowns.amount ) +
                  ( inUserSelections.bmc_fixed_bridges.amount * this.service_costs.bmc_fixed_bridges.amount ) +
                  ( inUserSelections.bmc_full_upper_or_lower_dentures.amount * this.service_costs.bmc_full_upper_or_lower_dentures.amount ) +
                  ( inUserSelections.bmc_inlays_and_onlays.amount * this.service_costs.bmc_inlays_and_onlays.amount ) +
                  ( inUserSelections.bmc_partial_dentures.amount * this.service_costs.bmc_partial_dentures.amount ) +
                  ( inUserSelections.bmc_recement.amount * this.service_costs.bmc_recement.amount ) +
                  ( inUserSelections.bmc_relining_dentures.amount * this.service_costs.bmc_relining_dentures.amount ) +
                  ( inUserSelections.bmc_repairs.amount * this.service_costs.bmc_repairs.amount ) ;


    //Calculate Co-Insurance
    this.coinsurance = ( inUserSelections.oc_Child.amount * this.service_costs.oc_Child.amount +
                         inUserSelections.oc_Adult.amount * this.service_costs.oc_Adult.amount ) * this.GetCategoryPercentage(0);

    //Cost Of Medical Care
    this.total_cost_of_care = this.annualDeductibles + this.copays + this.coinsurance + this.expenses_not_covered;
    this.estimated_total_annual_expense =  this.total_cost_of_care + this.annual_insurance_premium;
  }
  else
  {
    alert("Plan: " + this.title + " No Matching Coverage found for: " + inUserSelections.coverage_level_type );
    retVal = false;
  }
  return retVal;
}

function CalculateDefault(inUserSelections, inRcCosts)
{
  alert("Plan: " + this.title + " No Calculation Formula Implemented");
  return false;
}

function GetCoverageCosts( inCoverageLevelType )
{
  var retVal = null;
  for (var i=0; i < this.coverage_costs.length; i++)
  {
    if (this.coverage_costs[i].coverage_level_type == inCoverageLevelType)
    {
      retVal = this.coverage_costs[i];
      break;
    }
  } 
  return retVal;
}

function AddCategory( inCategoryId, inPercentage, inFixedLimit, inPerPersonInd )
{
  var newPlanCategory = new PlanCategory( inCategoryId, inPercentage, inFixedLimit, inPerPersonInd );
  this.categories[this.categories.length] = newPlanCategory;
}

function GetCategory( inCategoryId )
{
  var retVal = null;
  if (this.categories.length == 0)
    alert("GetCategory() No Categories exist for this Plan: " + inCategoryId )
  else
  {
    for (var i=0; i < this.categories.length; i++)
    {
      var oneCategory = this.categories[i];
      if (oneCategory.categoryId == inCategoryId)
      {
        retVal = oneCategory;
        break;
      }
    }
  }
  return retVal;
}

function GetCategoryPercentage( inCategoryId )
{
  var retVal = 0;
  if (this.categories.length == 0)
    alert("GetCategoryPercentage() No Categories exist for this Plan: " + inCategoryId )
  else if (this.categories.length == 1)
    retVal = this.categories[0].category_percentage;
  else
  {
    for (var i=0; i < this.categories.length; i++)
    {
      var oneCategory = this.categories[i];
      if (oneCategory.categoryId == inCategoryId)
      {
        retVal = oneCategory.category_percentage;
        break;
      }
    }
  }
  return retVal;
}

function GetCategoryFixedLimit( inCategoryId )
{
  var retVal = null;
  if (this.categories.length == 0)
    alert("GetCategoryFixedLimit() No Categories exist for this Plan: " + inCategoryId )
  else
  {
    for (var i=0; i < this.categories.length; i++)
    {
      var oneCategory = this.categories[i];
      if (oneCategory.categoryId == inCategoryId)
      {
        retVal = oneCategory.category_fixed_limit;
        break;
      }
    }
  }
  return retVal;
}

function AddCoverageCosts(inCoverageCosts)
{
  onePlan.coverage_costs[onePlan.coverage_costs.length] = inCoverageCosts;
}

function SetAllServiceCostsNotTowardsDeductible()
{
  var myServiceCostArray = this.service_costs.GetCostArray();
  for (var i=0; i < myServiceCostArray.length; i++)
  {
    var oneServiceCost = myServiceCostArray[i];
    oneServiceCost.towardsDeductible = false;
  }
}

function SetAllServiceCostsNotTowardsEmployerLimit()
{
  var myServiceCostArray = this.service_costs.GetCostArray();
  for (var i=0; i < myServiceCostArray.length; i++)
  {
    var oneServiceCost = myServiceCostArray[i];
    oneServiceCost.towardsEmployerLimit = false;
  }
}

//Plan Object
function Plan(p1,p2)
{
  this.planId = p1;
  this.title = p2;
  this.annualDeductibles = 0;
  this.copays = 0;
  this.coinsurance = 0;
  this.expenses_not_covered = 0;
  this.total_cost_of_care = 0;
  this.annual_insurance_premium = 0;
  this.estimated_total_annual_expense = 0;
  this.service_costs = new ServiceCosts(this,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
  this.coverage_costs = new Array();
  this.categories = new Array();
}
Plan.prototype.Calculate = CalculateDefault;
Plan.prototype.GetCoverageCosts = GetCoverageCosts;
Plan.prototype.AddCoverageCosts = AddCoverageCosts;
Plan.prototype.AddCategory = AddCategory; 
Plan.prototype.GetCategoryPercentage = GetCategoryPercentage; 
Plan.prototype.GetCategoryFixedLimit = GetCategoryFixedLimit; 
Plan.prototype.GetCategory = GetCategory; 
Plan.prototype.SetAllServiceCostsNotTowardsDeductible = SetAllServiceCostsNotTowardsDeductible;
Plan.prototype.SetAllServiceCostsNotTowardsEmployerLimit = SetAllServiceCostsNotTowardsEmployerLimit;

function PlanCategory( p1, p2, p3, p4)
{
  this.categoryId = p1;
  this.category_percentage = p2;
  this.category_fixed_limit = p3;
  this.per_person_ind = p4;
}


