protected void update()
    {
	secTimer = System.currentTimeMillis() - slast;
	minTimer = System.currentTimeMillis() - mlast;
	hrTimer = System.currentTimeMillis() - hlast;
	ampmTimer = System.currentTimeMillis() - ampmlast;
        date = String.format("%tr", new Date());

	// This loop is more efficient because it only updates the blocks that need to be updated
	// For example, hour won't get updated every single second
	
	// update seconds after every 1000 ms
	if(secTimer > 900){
	    second10s = Integer.toBinaryString(Integer.parseInt(date.substring(6, 7)));
            updateBlocks(second10s, panel.getSecond10s());

	    second1s = Integer.toBinaryString(Integer.parseInt(date.substring(7, 8)));
	    updateBlocks(second1s, panel.getSecond1s());
	    slast = System.currentTimeMillis();

	    playSound();

	}
	
	
	// update minute after every 60,000 ms
	if((minTimer > 1000 * 60 - 100) || (refresh == true)){
	    minute10s = Integer.toBinaryString(Integer.parseInt(date.substring(3, 4)));
	    updateBlocks(minute10s, panel.getMinute10s());
	    minute1s = Integer.toBinaryString(Integer.parseInt(date.substring(4, 5)));
	    updateBlocks(minute1s, panel.getMinute1s());
	    mlast = System.currentTimeMillis();
	}
	
	// update hour after 3,600,000 ms
	if((hrTimer > 1000 * 60 * 60 - 100) || (refresh == true)){
	    hour = Integer.toBinaryString(Integer.parseInt(date.substring(0, 2)));
	    updateBlocks(hour, panel.getHour()); 
	    hlast = System.currentTimeMillis();
	    }
        
	// update am/pm after 12 hours (3,600,000 * 12)
	if((ampmTimer > 1000 * 60 * 60 * 12 - 100) || (refresh == true)){
	    if(date.charAt(9)=='A')
		AM_PM = "1";
	    else AM_PM = "0";
	    updateAmPmBlocks(AM_PM, panel.getAmPm());
	    refresh = false;
	}
	
        //tell the thread to sleep before reiterating
        try
	    {
		Thread.sleep(500);
	    }

	catch(InterruptedException ex)
	    {
		ex.printStackTrace();
	    }
        update();
    }