
//Annual update - Replace the year in the following line with the current year
var cCurrentYear = 2010;
var cFirstYear = 1953;
var tRetire = 1;
var tDeath = 2;
var tDisability = 3;

var cWageBase = new Array();
var cNAE = new Array();
var cCOLA = new Array();

//Annual update - Replace cEarningsLimit in the following line with data on 
//http://www.pacificlifeandannuity.com/Channel/Educational+Information/Calculators/Social+Security+Benefits.htm
cEarningsLimit = 14880;

cWageBase[1953]=3600;
cWageBase[1954]=3600;
cWageBase[1955]=4200;
cWageBase[1956]=4200;
cWageBase[1957]=4200;
cWageBase[1958]=4200;
cWageBase[1959]=4800;
cWageBase[1960]=4800;
cWageBase[1961]=4800;
cWageBase[1962]=4800;
cWageBase[1963]=4800;
cWageBase[1964]=4800;
cWageBase[1965]=4800;
cWageBase[1966]=6600;
cWageBase[1967]=6600;
cWageBase[1968]=7800;
cWageBase[1969]=7800;
cWageBase[1970]=7800;
cWageBase[1971]=7800;
cWageBase[1972]=9000;
cWageBase[1973]=10800;
cWageBase[1974]=13200;
cWageBase[1975]=14100;
cWageBase[1976]=15300;
cWageBase[1977]=16500;
cWageBase[1978]=17700;
cWageBase[1979]=22900;
cWageBase[1980]=25900;
cWageBase[1981]=29700;
cWageBase[1982]=32400;
cWageBase[1983]=35700;
cWageBase[1984]=37800;
cWageBase[1985]=39600;
cWageBase[1986]=42000;
cWageBase[1987]=43800;
cWageBase[1988]=45000;
cWageBase[1989]=48000;
cWageBase[1990]=51300;
cWageBase[1991]=53400;
cWageBase[1992]=55500;
cWageBase[1993]=57600;
cWageBase[1994]=60600;
cWageBase[1995]=61200;
cWageBase[1996]=62700;
cWageBase[1997]=65400;
cWageBase[1998]=68400;
cWageBase[1999]=72600;
cWageBase[2000]=76200;
cWageBase[2001]=80400;
cWageBase[2002]=84900;
cWageBase[2003]=87000;
cWageBase[2004]=87900;
cWageBase[2005]=90000;
cWageBase[2006]=94200;
cWageBase[2007]=97500;
cWageBase[2008]=102000;
cWageBase[2009]=106800;
cWageBase[2010]=106800;

cNAE[1953]=3139.44;
cNAE[1954]=3155.64;
cNAE[1955]=3301.44;
cNAE[1956]=3532.36;
cNAE[1957]=3641.72;
cNAE[1958]=3673.8;
cNAE[1959]=3855.8;
cNAE[1960]=4007.12;
cNAE[1961]=4086.76;
cNAE[1962]=4291.4;
cNAE[1963]=4396.64;
cNAE[1964]=4576.32;
cNAE[1965]=4658.72;
cNAE[1966]=4938.36;
cNAE[1967]=5213.44;
cNAE[1968]=5571.76;
cNAE[1969]=5893.76;
cNAE[1970]=6186.24;
cNAE[1971]=6497.08;
cNAE[1972]=7133.8;
cNAE[1973]=7580.16;
cNAE[1974]=8030.76;
cNAE[1975]=8630.92;
cNAE[1976]=9226.48;
cNAE[1977]=9779.44;
cNAE[1978]=10556.03;
cNAE[1979]=11479.46;
cNAE[1980]=12513.46;
cNAE[1981]=13773.1;
cNAE[1982]=14531.34;
cNAE[1983]=15239.24;
cNAE[1984]=16135.07;
cNAE[1985]=16822.51;
cNAE[1986]=17321.82;
cNAE[1987]=18426.51;
cNAE[1988]=19334.04;
cNAE[1989]=20099.55;
cNAE[1990]=21027.98;
cNAE[1991]=21811.6;
cNAE[1992]=22935.42;
cNAE[1993]=23132.67;
cNAE[1994]=23753.53;
cNAE[1995]=24705.66;
cNAE[1996]=25913.9;
cNAE[1997]=27426;
cNAE[1998]=28861.44;
cNAE[1999]=30469.84;
cNAE[2000]=32154.82;
cNAE[2001]=32921.92;
cNAE[2002]=33252.09;
cNAE[2003]=34064.95;
cNAE[2004]=35648.55;
cNAE[2005]=36952.94;
cNAE[2006]=38651.41;
cNAE[2007]=40405.48;
cNAE[2008]=41334.97;
cNAE[2009]=cNAE[2008]*1.04;
cNAE[2010]=cNAE[2009]*1.04;

cCOLA[1979]=0.065;
cCOLA[1980]=0.099;
cCOLA[1981]=0.143;
cCOLA[1982]=0.112;
cCOLA[1983]=0.074;
cCOLA[1984]=0.035;
cCOLA[1985]=0.035;
cCOLA[1986]=0.031;
cCOLA[1987]=0.013;
cCOLA[1988]=0.042;
cCOLA[1989]=0.04;
cCOLA[1990]=0.047;
cCOLA[1991]=0.054;
cCOLA[1992]=0.037;
cCOLA[1993]=0.03;
cCOLA[1994]=0.026;
cCOLA[1995]=0.028;
cCOLA[1996]=0.026;
cCOLA[1997]=0.029;
cCOLA[1998]=0.021;
cCOLA[1999]=0.013;
cCOLA[2000]=0.024;
cCOLA[2001]=0.035;
cCOLA[2002]=0.026;
cCOLA[2003]=0.014;
cCOLA[2004]=0.021;
cCOLA[2005]=0.027;
cCOLA[2006]=0.041;
cCOLA[2007]=0.033;
cCOLA[2008]=0.023;
cCOLA[2009]=0.058;
cCOLA[2010]=0.0;

//constructor
function createSocSec(CurrentPay,
                      BirthYear, 
                      ProjectedLastWorkYear,  
                      SalInc,                 
                      Inflation)              

{
    this.mCurrentPay = Number(CurrentPay); 
    this.mBirthYear  = Number(BirthYear); 
    this.mProjectedLastWorkYear = Number(ProjectedLastWorkYear);
    this.mSalInc = Number(SalInc);                 
    this.mInflation = Number(Inflation);              
    
    this.mMyFamilyMax = 0;
    this.mPIAOverride = false;
    this.mPIAOverrideAmt = 0;
    this.mFullPIA = 0;
    this.mPIAYear = 0;
    this.mAdjustedPIA = 0;
    this.mSpSocSec = "null";
    this.mSpRetireBenYear = 0;
    this.mSpDeathYear = 0;
    this.mRetireBenArray = new Array();
    this.mRetireMarriageArray = new Array();
    this.mRetireSurvArray = new Array();
    this.mRetireBestArray = new Array();

    //09-02-2008 enhancement
    this.mBenefitStartAge = 62;

    //methods
    this.WageBase = WageBase;
    this.IndexedPay = IndexedPay;
    this.NAE = NAE
    this.COLA = COLA;
	 
    this.PIABendOne = PIABendOne;
    this.PIABendTwo =PIABendTwo;
    this.FamilyMaxOne = FamilyMaxOne;
    this.FamilyMaxTwo = FamilyMaxTwo;
    this.FamilyMaxThree = FamilyMaxThree;
    this.AIME = AIME;
    this.InitialRetireCola = InitialRetireCola;
    this.GetYear = GetYear;
    this.GetAge = GetAge;
    this.SSNRA = SSNRA;
    this.SurvivorSSNRA = SurvivorSSNRA;
    this.Reduction = Reduction;
    this.ReductionMarriage = ReductionMarriage;
    this.ReductionSurvivor = ReductionSurvivor;
    this.Credit = Credit;
    this.FamilyMax = FamilyMax;
    this.PIA = PIA;
    this.RetireBenefit = RetireBenefit;
    this.TodayDollars = TodayDollars;
    this.FutureDollars = FutureDollars;
    this.AnnualBenefit = AnnualBenefit;
    this.MarriageBenefit = MarriageBenefit;
    this.SurvivorBenefit = SurvivorBenefit;
    this.GetCOLA = GetCOLA;
    this.AddPIAOverride = AddPIAOverride;
    this.AddSpSocSec = AddSpSocSec;
    this.CalcRetireArray = CalcRetireArray;
    this.GetYear = GetYear;
    this.GetAge = GetAge;
    this.WorkingSpouseBenefit = WorkingSpouseBenefit;	

    //09-02-2008 enhancement
    this.SetBenefitStartAge = SetBenefitStartAge;

    return true;
}

//09-02-2008 enhancement
function SetBenefitStartAge(startAge)
{
    this.mBenefitStartAge = Math.min(70,Math.max(62,startAge));
}

function GetYear(age)
{
	return age + this.mBirthYear;

}

function GetAge(year)
{
	return year - this.mBirthYear;
}

function CalcRetireArray(firstAge, retireAge, deathAge, lastAge)
{
	
	for (var j=firstAge; j<=lastAge;j++)
	{
		this.mRetireBenArray[j] = 0;
		this.mRetireMarriageArray[j] = 0;
		this.mRetireSurvArray[j] = 0;
	}

	var incrFactor = 1+this.mInflation;
	var socSecStartYear = this.GetYear(Math.max(this.mBenefitStartAge,retireAge)); //09-02-2008 enhancement
	var retBen = this.RetireBenefit(socSecStartYear);

	for (var j=this.GetAge(socSecStartYear);j<deathAge;j++)
	{
		this.mRetireBenArray[j] = retBen;
		retBen *= incrFactor;
	}
		
	if (this.mSpSocSec != "null")
	{
		//marriage benefit
		var spAge62Year = this.mSpSocSec.mBirthYear+62;
		var marStartYear = Math.max(this.mSpRetireBenYear,socSecStartYear);
		var marBen = this.MarriageBenefit(this.mSpSocSec.mFullPIA,
		                                  spAge62Year,
		                                  marStartYear);
		for (var j=this.GetAge(marStartYear); j<deathAge;j++)
		{
			this.mRetireMarriageArray[j] = marBen;
			marBen *= incrFactor;
		}
		
		//widow(er) benefit
		var survBen = this.SurvivorBenefit(this.mSpSocSec.mFullPIA, 
		                                  spAge62Year, 
		                                  this.mSpSocSec.mAdjustedPIA, 
					    	  this.mSpDeathYear);
		for (var j=this.GetAge(this.mSpDeathYear); j<deathAge;j++)
		{
			this.mRetireSurvArray[j] = survBen;
			survBen *= incrFactor;
		}
	} 
	
	for (var j=firstAge; j<=lastAge;j++)
	{
		this.mRetireBestArray[j] = Math.max(this.mRetireBenArray[j],
		                           	    Math.max(this.mRetireMarriageArray[j],
						 	     this.mRetireSurvArray[j]));
	}
	
	return true;
}

function AddSpSocSec(spSocSec, spRetireAge, spDeathAge)
{
	this.mSpSocSec = spSocSec;
	this.mSpRetireBenYear = this.mSpSocSec.mBirthYear + Math.max(this.mSpSocSec.mBenefitStartAge,spRetireAge); //09-02-2008 enhancement
	this.mSpDeathYear = this.mSpSocSec.mBirthYear + spDeathAge;
	this.mSpSocSec.RetireBenefit(this.mSpRetireBenYear);
	return true;
}

function WageBase(Year)
{
var UnroundedWageBase;

  if (Year > cCurrentYear) 
	{
	  UnroundedWageBase = cWageBase[cCurrentYear] * Math.pow(1+this.mInflation,Year-cCurrentYear);
      return Math.round(UnroundedWageBase/600)*600;
    }
  else
    return cWageBase[Year];
}

function IndexedPay(PayYear, IndexYear)
{
var IndexFactor;
var Pay;

  IndexYear = Math.min(IndexYear,this.mBirthYear+60);

  if (PayYear > this.mProjectedLastWorkYear)
	{  
    return 0
 }
  else 
	{
    if (PayYear < IndexYear) 
	  {
      IndexFactor = this.NAE(IndexYear) / this.NAE(PayYear)
	  }
    else
      {
      IndexFactor = 1.0;
      }

    if (PayYear > cCurrentYear) 
	  {
      Pay = this.mCurrentPay * Math.pow(1+this.mSalInc,PayYear-cCurrentYear)
	  }
    else
	  {
      Pay = this.mCurrentPay * this.NAE(PayYear) / this.NAE(cCurrentYear);
	  }
    Pay = Math.min(Pay,this.WageBase(PayYear));

    return Pay * IndexFactor;
	}
}

function NAE(Year)
{
  if (Year <= cCurrentYear)
	{
    return cNAE[Year]
	}
  else
	{
    return cNAE[cCurrentYear] * Math.pow(1+this.mInflation,Year-cCurrentYear);
    }
}

function COLA(Year)
{
  if (Year <= cCurrentYear)
    {
    return cCOLA[Year]
	}
  else
    {
    return this.mInflation;
    }
}

function PIABendOne(Year)
{
  return Math.round(180 * this.NAE(Year-2) / this.NAE(1977));
}

function PIABendTwo(Year)
{
  return Math.round(1085 * this.NAE(Year-2) / this.NAE(1977));
}

function FamilyMaxOne(Year)
{
  return Math.round(230 * this.NAE(Year-2) / this.NAE(1977));
}

function FamilyMaxTwo(Year)
{
  return Math.round(332 * this.NAE(Year-2) / this.NAE(1977));
}

function FamilyMaxThree(Year)
{
  return Math.round(433 * this.NAE(Year-2) / this.NAE(1977));
}

function AIME(BenType, Year)
{
  var StartYear;
  var  EndYear;
  var j;
  var Result;

  EndYear = Math.min(Year-1,this.mProjectedLastWorkYear);
  StartYear = Math.min(EndYear,Math.max(EndYear-34,Math.max(cFirstYear,this.mBirthYear+21)));

  Result = 0;
  for (j = StartYear; j <= EndYear; j++)
	{
	  Result = Result + this.IndexedPay(j,Year-2);
    }

  if (BenType == tRetire) 
	{
    Result = Result/35/12
	}
  else
    {
    Result = Result/(EndYear-StartYear+1)/12;
    }

  return Math.floor(Result*10)/10;
}

function InitialRetireCola(Year)
{
  return this.GetCOLA(this.GetYear(63),Year);
}

function GetYear(Age)
{
  return this.mBirthYear + Age;
}

function GetAge(Year)
{
  return Year - this.mBirthYear;
}

function SSNRA()
{
  if (this.mBirthYear < 1938)
	{
    return 65
	}
  else if (this.mBirthYear < 1943) 
    {
    return 65+(this.mBirthYear-1937)/6
	}
  else if (this.mBirthYear < 1955)
    {
    return 66
	}
  else if (this.mBirthYear < 1960)
    {
    return 66+(this.mBirthYear-1954)/6
	}
  else
    {
    return 67;
    }
}

function SurvivorSSNRA()
{
  if (this.mBirthYear < 1940)
	{
	  return 65
    }
  else if (this.mBirthYear < 1945) 
	{
      return 65+(this.mBirthYear-1939)/6
    }
  else if (this.mBirthYear < 1957)
	{
    return 66
    }
  else if (this.mBirthYear < 1962)
	{
    return 66+(this.mBirthYear-1956)/6
    }
  else
	{
    return 67;
    }
}

function Reduction(BenefitAge)
{
  if (BenefitAge < this.SSNRA())
    {
    var Accrual = new createAccrual();
    Accrual.AddRate(0.20/3,3);
    Accrual.AddRate(0.05,0);
    return Accrual.Calc(this.SSNRA()-BenefitAge);
	}
	else
	{
      return 0;
	} 
}

function ReductionMarriage(BenefitAge)
{
  if (BenefitAge < this.SSNRA())
	{
    var Accrual = new createAccrual();
    Accrual.AddRate(0.25/3,3);
    Accrual.AddRate(0.05,0);
    return Accrual.Calc(this.SSNRA()-BenefitAge);
	}
	else
	{
    return 0;
    }
}

function ReductionSurvivor(BenefitAge)
{
  if (BenefitAge < this.SurvivorSSNRA())
	{
    var Accrual = new createAccrual();
    Accrual.AddRate((1-0.715)/(this.SurvivorSSNRA()-60),3);
    return Accrual.Calc(this.SurvivorSSNRA()-BenefitAge);
	}
	else
	{
    return 0;
	}
}

function Credit(BenefitAge)
{
  var Result;

  if (BenefitAge > 70)
	{
    BenefitAge = 70;
	}

  if (BenefitAge > this.SSNRA())
	{
    if (this.mBirthYear > 1942)
	  {
        Result = 0.08
	  }
    else if (this.mBirthYear < 1925)
	  {
      Result = 0.03
	  }
    else
	  {
      Result = 0.08-((1944-this.mBirthYear) / 2)*0.005;
	  }
    Result = Result * (BenefitAge - this.SSNRA());
	}
	else
	{
      Result = 0;
	}
  return Result;
}


function FamilyMax(MyPIA,PIAYear)
{
	var familymaxresult;
	var Accrual = new createAccrual();
	familymaxresult = this.FamilyMaxOne(PIAYear);
    Accrual.AddRate(1.5,this.FamilyMaxOne(PIAYear));
    Accrual.AddRate(2.72,this.FamilyMaxTwo(PIAYear));
    Accrual.AddRate(1.34,this.FamilyMaxThree(PIAYear));
    Accrual.AddRate(1.75,0);
    return Math.floor(Accrual.Calc(MyPIA)*10)/10;
}

function PIA(BenType, Year)
{
  var MyAIME;
  var PIAYear;
  var Result;

  if (BenType == tRetire)
  {
    PIAYear = this.mBirthYear+62
	}
  else
    {
    PIAYear = Math.min(this.mBirthYear+62,Year);
    }

  if (this.mPIAOverride)
	{
    Result = this.mPIAOverrideAmt;
	}
  else 
    {
	MyAIME = this.AIME(BenType,Year);
    var Accrual = new createAccrual();
    Accrual.AddRate(0.9,this.PIABendOne(PIAYear));
    Accrual.AddRate(0.32,this.PIABendTwo(PIAYear));
    Accrual.AddRate(0.15,0);
    Result = Math.floor(Accrual.Calc(MyAIME)*10)/10;
	}
	this.mMyFamilyMax = this.FamilyMax(Result,PIAYear);

	return Result;
}

function TodayDollars(FutureBenefit, Year)
{
  var Result;
  Result = FutureBenefit / Math.pow(1+this.mInflation,Year-cCurrentYear);
  Result = Math.round(100*Result)/100;
  return Result;
}

function FutureDollars(TodayBenefit,Year)
{
  var Result;
  Result = TodayBenefit * Math.pow(1+this.mInflation,Year-cCurrentYear);
  Result = Math.round(100*Result)/100;
  return Result;
}

function AnnualBenefit(MonthlyBenefit)
{
  return 12 * MonthlyBenefit;
}

function RetireBenefit(RetireYear)
{
  var RetireAge;
  var Result;

  RetireAge = this.GetAge(RetireYear);
  if (RetireAge < 62)
    {
    this.mFullPIA = 0;
    this.mPIAYear = 0;
    this.mAdjustedPIA = 0;
    Result = 0;
	}
	else 
	{
    this.mPIAYear = this.mBirthYear + 60;
    this.mFullPIA = this.PIA(tRetire,RetireYear);
    this.mAdjustedPIA = this.mFullPIA * (1-this.Reduction(RetireAge)) * (1+this.Credit(RetireAge));
    this.mAdjustedPIA = Math.round(100*this.mAdjustedPIA)/100;
    Result = this.mAdjustedPIA * (1+this.InitialRetireCola(RetireYear));
    Result = Math.round(100*Result)/100;
    }
  return Result;
}

function MarriageBenefit(SpousePIA,SpousePIAYear,StartBenefitYear)
{
  var RetireAge;
  var Result;

  RetireAge = this.GetAge(StartBenefitYear);
  if (RetireAge < 62)
    {
    Result = 0
    }
  else 
    {
    Result = 0.5 * SpousePIA;
    Result = Result * (1-this.ReductionMarriage(RetireAge));
    Result = Result * (1+this.GetCOLA(SpousePIAYear,StartBenefitYear));
    Result = Math.round(Result*100)/100;
    }
  return Result;
}

function SurvivorBenefit(SpousePIA, SpousePIAYear, SpouseAdjustedPIA, StartBenefitYear)
{
  var RetireAge;
  var Result;

  RetireAge = this.GetAge(StartBenefitYear);
  if (RetireAge < 62)
    {
    Result = 0
	}
  else 
    {
    Result = SpouseAdjustedPIA;
    Result = Result * (1-this.ReductionSurvivor(RetireAge));
    Result = Math.min(Result, Math.max(SpouseAdjustedPIA,0.825 * SpousePIA));
    Result = Result * (1+this.GetCOLA(SpousePIAYear,StartBenefitYear));
    Result = Math.round(Result*100)/100;
    }
  return Result;
}

function GetCOLA(BeginYear, EndYear)
{  
  var j;
  var Result;
  Result = 1.0;
  for (j = BeginYear; j <= EndYear; j++)
    {
    Result = Result * (1+this.COLA(j));      //added 1/16/2003
    }
  Result = Result - 1;
  return Result;
}

function AddPIAOverride(BenType, TodayDolPIA)
{  
  TodayDolPIA = Number(TodayDolPIA);
  
  var PIAYear;

  this.mPIAOverride = true;
  if (BenType == tRetire)
    {
    PIAYear = this.mBirthYear + 60;
    if (PIAYear > cCurrentYear)
	  {
      this.mPIAOverrideAmt = this.FutureDollars(TodayDolPIA,PIAYear)
	  }
    else
	  {
      this.mPIAOverrideAmt = TodayDolPIA;
	  }
	}
  else
    {
    this.mPIAOverrideAmt = TodayDolPIA;
	}

  this.mPIAOverrideAmt = Math.floor(this.mPIAOverrideAmt*10)/10;
  return true;
}

function WorkingSpouseBenefit(MyPIA, SpouseEarnings)
{
  var reduction = Math.max(SpouseEarnings-cEarningsLimit,0)/2;
  return Math.max(MyPIA*12*0.75-reduction,0)/12;
}	
