package com.mindprod.htmlmacros;

import com.mindprod.common11.BigDate;

import java.io.File;

/**
 * Calculate Age from birthdate.
 *
 * @author Roedy Green
 * @version 1.0, 2005-03-19
 */
@SuppressWarnings( { "UnusedDeclaration" } )
public final class Age implements Macro
    {
// ------------------------------ FIELDS ------------------------------

    private static final String USAGE = "Age macro needs date yyyy-mm-dd [years/months/days]";
// -------------------------- PUBLIC INSTANCE  METHODS --------------------------
    /**
     * Generate Age from birthdate . expands <!-- macro Age 1948-02-04 --> to age in years. or <!-- macro Age 1948-02-04
     * years --> <!-- macro Age 1948-02-04 months --> <!-- macro Age 1948-02-04 days -->
     *
     * @param parms              date as ISO string.
     * @param fileBeingProcessed File being processed.
     * @param quiet              true if no progress messages
     * @return expanded macro text
     */
    public String expandMacro( String[] parms,
                               File fileBeingProcessed,
                               boolean quiet )
        {
        if ( !quiet )
            {
            System.out.print( "A" );
            }

        if ( !( 1 <= parms.length && parms.length <= 2 ) )
            {
            throw new IllegalArgumentException( USAGE );
            }
        try
            {
            String dateString = parms[ 0 ];
            int year = Integer.parseInt( dateString.substring( 0, 4 ) );
            int month = Integer.parseInt( dateString.substring( 5, 7 ) );
            int day = Integer.parseInt( dateString.substring( 8, 10 ) );
            BigDate birthDate = new BigDate( year, month, day );

            final int granularity;
            if ( parms.length > 1 )
                {
                final String units = parms[ 1 ];
                if ( units.equalsIgnoreCase( "years" ) )
                    {
                    granularity = 0;
                    }
                else if ( units.equalsIgnoreCase( "months" ) )
                    {
                    granularity = 1;
                    }
                else if ( units.equalsIgnoreCase( "days" ) )
                    {
                    granularity = 2;
                    }
                else
                    {
                    throw new IllegalArgumentException( USAGE );
                    }
                }
            else
                {
                granularity = -1;
                }
            return expand( birthDate, granularity );
            }
        catch ( StringIndexOutOfBoundsException e )
            {
            throw new IllegalArgumentException( USAGE );
            }

        catch ( NumberFormatException e )
            {
            throw new IllegalArgumentException( USAGE );
            }
        }

// -------------------------- OTHER METHODS --------------------------

    /**
     * guts of Age macro expansion
     *
     * @param birthDate   person's birth date whose age you want expanded
     * @param granularity -1 = years without wording 0=years 1=months 2=days
     * @return age in years
     */
    private String expand( BigDate birthDate, int granularity )
        {
        // compute age as of timezone where macros expanded at elapsedTime macros
        // expanded.
        final BigDate today = BigDate.localToday();
        final int[] ymd = BigDate.age( birthDate, today );
        final int ageInYears = ymd[ 0 ];
        int ageInMonths = ymd[ 1 ];
        int ageInDays = ymd[ 2 ];

        switch ( granularity )
            {
            case -1:
            case 0:
                /* truncate if only want accurate to year */
                ageInMonths = 0;
                ageInDays = 0;
                break;

            case 1:
                ageInDays = 0;
                break;

            case 2:
                break;
            }
        StringBuilder sb = new StringBuilder( 30 );
        if ( ageInYears != 0 )
            {
            sb.append( ageInYears );
            if ( granularity != -1 )
                {
                sb.append( " year" );
                if ( ageInYears > 1 )
                    {
                    sb.append( "s" );
                    }
                }
            }

        if ( ageInMonths != 0 )
            {
            if ( ageInYears != 0 )
                {
                if ( ageInDays != 0 )
                    {
                    sb.append( ", " );
                    }
                else
                    {
                    sb.append( " and " );
                    }
                }

            sb.append( ageInMonths );
            sb.append( " month" );
            if ( ageInMonths > 1 )
                {
                sb.append( "s" );
                }
            }

        if ( ageInDays != 0 )
            {
            if ( ageInYears != 0 || ageInMonths != 0 )
                {
                sb.append( " and " );
                }
            sb.append( ageInDays );
            sb.append( " day" );
            if ( ageInDays > 1 )
                {
                sb.append( "s" );
                }
            }
        Tools.checkStringBuilderEstimate( sb, 1, 30 );

        return sb.toString();
        }
    }