﻿/*
Create a web page that utilizes JavaScript to determine the visitor's hourly pay and hours worked per week. From there, calculate what the user can expect to make this week, including overtime.
	Make sure it fulfills these requirements:
		The user's input is captured as a number
		All hours worked above 40 are considered overtime and calculated at 1.5x the hourly wage
		The results (hourly wage, hours worked, normal hourly gross, overtime gross, and total gross) are displayed in HTML elements that were written to the browser with document.write().
*/


/*
*   Pulls the info from the weeks, input, and summary blocks and
*       presents it more nicer
*/


// div ids
var wrapperID = '';
var dataEntryID = 'dataEntry';
var inputBlockID = 'inputBlock';
var hoursBlockID = 'hoursBlock';
var summaryBlockID = 'summaryBlock';
var printViewID = 'printView';
// data element IDs
    // input block ids
var employeeNameID = 'employeeName';
var hourlyRateID = 'hourlyRate';
var otStyleID = 'otStyle';
    // summary block ids
var hoursWorkedID = 'hoursWorked';
var basePayGrossID = 'basePayGross';
var otPayGrossID = 'otPayGross';
var totalPayGrossID = 'totalPayGross';
// data elements
var weekCount = 0; // to track how many weeks have been made
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var overtimeStyle = ['weekly', 'daily'];
var baseHoursByDay = [];
var overtimeHoursByDay = [];
var payRate = 0;
var empName = '';
var baseHours = 0;
var overtimeHours = 0;
var baseGross = 0;
var overtimeGross = 0;

/*
*   Just the init - makes the first call to buildDataPage() and build the content divs
*   @ param id - the id of the div that is to hold the content
*/
function calcInit(id)
{
    wrapperID = id;
    var input = enTag('div', '', {id:inputBlockID});
    var hours = enTag('div', '', {id:hoursBlockID});
    var summary = enTag('div', '', {id:summaryBlockID});
    var holder = enTag('div', input + summary + hours, {id:dataEntryID});
	var printView = enTag('div', '', {id:printViewID});
    $(id).innerHTML = holder + printView;
    buildDataPage(true);
}

/*
*   Sets up the input block and the hour collection block
*   @ param isNew - boolean, if true, will init the sections, elsewise will just show the section
*
*/
function buildDataPage(isNew)
{
    isNew = isNew || false;
    if(isNew)
    {
        buildInputBlock();
        buildSummaryBlock();
        buildHoursBlock();
    }
    
    $(printViewID).style.display = "none";
    $(dataEntryID).style.display = "block";
}

/*
*   Makes the base input block values - only used on init
*/
function buildInputBlock()
{
    var empName = enTag('label', 'Employee Name', {for:employeeNameID});
    empName += enTag('input', '', {value:'Enter Name', id:employeeNameID, onfocus:'wipe(this.id)'});
   
    var hourRate = enTag('label', 'Hourly Rate', {for:hourlyRateID});
    hourRate += enTag('input', '', {value:'0.00', id:hourlyRateID, onfocus:'wipe(this.id)'});
    
    var otStyle = enTag('label', 'Overtime Style', {for:otStyleID});
    otStyle += enSelect(overtimeStyle, otStyleID);
    
    var inputBlock = enTag('form', empName + hourRate + otStyle);
    $(inputBlockID).innerHTML = inputBlock;
}

/*
*   Makes the summary block - only used on init
*/
function buildSummaryBlock()
{
    var hours = enTag('label', 'Hours Worked', {for:hoursWorkedID});
    hours += enTag('input', '', {value:0, id:hoursWorkedID, disabled:'disabled'});
   
    var base = enTag('label', 'Base Pay Gross', {for:basePayGrossID});
    base += enTag('input', '', {value:0, id:basePayGrossID, disabled:'disabled'});
   
    var ot = enTag('label', 'Overtime Pay Gross', {for:otPayGrossID});
    ot += enTag('input', '', {value:0, id:otPayGrossID, disabled:'disabled'});
   
    var tot = enTag('label', 'Total Pay Gross', {for:totalPayGrossID});
    tot += enTag('input', '', {value:0, id:totalPayGrossID, disabled:'disabled'});
  
    var print = enTag('a', 'Show Print View', {id:'printTag', onclick:'showPrintView()'});
    
    var sumHrs = enTag('a', 'Sum Hours', {id:'sumTag', onclick:'sumHours()'});
    
    var summ = enTag('form', hours + base + ot + tot + print + sumHrs);
    
    $(summaryBlockID).innerHTML = summ;
}

/*
*   Builds an hours block - called from init, and from the 'add week' button
*/
function buildHoursBlock()
{
    var tHead = '';
    tHead += enTag('th', 'Day');
    tHead += enTag('th', 'Hours');
    tHead += enTag('th', enTag('form',enTag('button', 'Add Week', {type:'submit'}),{onsubmit:'buildHoursBlock(); return false'}));
    tHead = enTag('tHead', tHead);
    
    var tBody = '';
    for(var i = 0; i < days.length; i++)
    {
        var rowID = weekCount + "_" + i;
        var row = enSelect(days, 'select_' + rowID, i);
        
        row += enTag('input', '', {value:0, id:'input_' + rowID, onblur:'testNumber(this.value, this.id)'});
        row = enTag('form', row);
        row = enTag('td', row, {colspan:2});
        row += enTag('td', enTag('span', '', {id:'error_' + rowID, class:'error'}));
        row = enTag('tr', row, {id:rowID});
        tBody += row;
    }
   
    tBody = enTag('tBody', tBody);
    var hoursBlock = enTag('table', tHead + tBody, {id:"hours" + weekCount, class:'hours'});
   
   // write it to screen
	var nDiv = document.createElement('div');
	nDiv.innerHTML = hoursBlock;		
	$(hoursBlockID).appendChild(nDiv);
   
    weekCount++;
}

/*
*   The workhorse: goes through all weeks, determining pay by day / week, and 
*       filling in the values in the summary block
*/
function sumHours()
{
    var hourType = $(otStyleID).value;
    var overTime = 0;
    var regularTime = 0;
    
    for(var i = 0; i < weekCount; i++)
    {
        var weekHours = 0;
        for(var j = 0; j < days.length; j++)
        {
            var rowID = "input_" + i + "_" + j;
            var num = parseFloat($(rowID).value);
            var dayHours = (isNaN(num)) ? 0 : num;
            
            weekHours += dayHours;
            
            if(hourType == 'daily')
            {
                if(dayHours > 8)
                {
                    overTime += dayHours - 8;
                    dayHours = 8;
                }
                regularTime += dayHours;
            }
        } // end daily
        if(hourType == 'weekly')
        {
            if(weekHours > 40)
            {
                overTime += weekHours - 40;
                weekHours = 40;
            }
            regularTime += weekHours;
        } // end weekly
    } // end weeks
    
    // set the values
    var pay = parseFloat($(hourlyRateID).value) || 0;
    var regPay = regularTime * pay;
    var otPay = overTime * pay;
    var totPay = regPay + otPay;
    
    $(basePayGrossID).value = toDollar(regPay);
    $(otPayGrossID).value = toDollar(otPay);
    $(hoursWorkedID).value = regularTime + overTime;
    $(totalPayGrossID).value = toDollar(totPay);
   
   return false;
}

/**
*   Iterates through the existing elements on the data page,
*       yanking values, and building up the view
*/
function showPrintView()
{
    // pull header values
	var emp = "Employee: ";
	emp += enTag('u',$(employeeNameID).value);
	var rate = "Hourly Wage: ";
	rate += enTag('u', $(hourlyRateID).value);
	
	var header = enTag('div', enTag('p', emp) + enTag('p', rate), {id:'header'});
	// pull pay values
	var hours = "Hours worked: ";
	hours += enTag('u', $(hoursWorkedID).value);
	var base = "Base Pay: ";
	base += enTag('u', $(basePayGrossID).value);
	var ot = "Overtime Pay: ";
	ot += enTag('u', $(otPayGrossID).value);
	var tot = "Total Pay: ";
	tot += enTag('u', $(totalPayGrossID).value);
	
	var pay = enTag('div', enTag('p', hours) + enTag('p', base) + enTag('p', ot) + enTag('p', tot), {id:'pay'});
	// pull hours worked
	var weeks = '';
	
	for(var i = 0; i < weekCount; i++)
	{		
	    var week = enTag('thead', enTag('th', 'Day') + enTag('th', 'Hours'));
		for(var j = 0; j < days.length; j++)
		{
			var day = enTag('td',$('select_' + i + '_' + j).value);
			var hrs = enTag('td',$('input_' + i + '_' + j).value);
			week += enTag('tr', day + hrs);
		}
		week = enTag('table', week, {class:'week'});
		weeks += week;
	}
	weeks = enTag('div', enTag('table', weeks), {id:'weeks'});
	var button = enTag('a', 'Back to data', {onclick:'buildDataPage(false)'});
	$(printViewID).innerHTML = header + pay + weeks + button;
	
	// swap visibilities
	$(dataEntryID).style.display = "none";
	$(printViewID).style.display = "block";
}

/*
*   Sees if the value is a number, and sets the error in the id.innerHTML - specific functionality to this application
*   @ param value - the value to test
*   @ param id - id of the element containing the number
*/
function testNumber(value, id)
{
    var spanID = 'error' + id.substring(id.indexOf('_'));
    
    if(isNaN(value))
    {
        $(id).value = 0;
        $(spanID).innerHTML = 'please enter a number';
    }
    else
    {
        $(spanID).innerHTML = '';
    }
}



function wipe(id)
{
    $(id).value = '';
}

/**
*   Takes a value, rounds to two decimal places, and 
*       adds on a '$'
*   @ param num - a number
*   @ return ret - string of form $00.00
*/
function toDollar(num)
{
    var num = parseFloat(num);
    
    if(isNaN(num))
    {
        return 'need a number';
    }
    else
    {
        num = parseInt(num * 100);
        num /= 100;
        var ret = '$' + num;
        return ret;
    }
}