/* * [DistrictItem.java] * * Summary: Defines tax and name information about one state district Used by AmericanTax class. * * Copyright: (c) 1999-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.0 2007-06-08 initial version * 1.1 2010-05-10 now serialised, read from resource. */ package com.mindprod.americantax; import java.io.Serializable; import java.util.Comparator; /** * Defines tax and name information about one state district Used by AmericanTax class. * * @author Roedy Green, Canadian Mind Products * @version 1.1 2010-05-10 now serialised, read from resource. * @since 2007-06-08 */ final class DistrictItem implements Serializable { /** * Defining a layout version for a class. */ private static final long serialVersionUID = 4L; private final String cityName; private final String countyName; /** * states + district sales tax rate e.g. 7% = 70,000, includes state sales tax rate. */ private final int districtTaxRate; /** * state sales tax rate e.g. 7% = 70,000 */ private final int stateTaxRate; private transient byte sortCategory; /** * constructor * * @param stateItem corresponding State object * @param countyName name of county * @param cityName;me name of city * @param districtPercent 7% = 7.0000 */ DistrictItem( final StateItem stateItem, final String countyName, final String cityName, final double districtPercent ) { // we don't internally record the state, just the state tax. this.countyName = countyName.intern(); // want as compact as possible. Time during prepare does not matter. this.cityName = cityName.intern(); // store 7% as 70,000, (includes state tax rate) // store as int for compactness and accuracy. Round in case fraction not expressible in binary. this.districtTaxRate = ( int ) ( districtPercent * 10000 + .5 ); /* store compactly as an int */ this.stateTaxRate = stateItem.getStateTaxRate(); setSortCategory(); } // end constructor /** * calculate the overall sorting category */ private void setSortCategory() { // order we want: // empty, empty 0 // city, county 1 // city, empty 2 // empty, county 3 if ( cityName.length() > 0 ) { if ( countyName.length() > 0 ) { sortCategory = 1; } else { sortCategory = 2; } } else { if ( countyName.length() > 0 ) { sortCategory = 3; } else { sortCategory = 0; } } } /** * get district sales tax rate * * @return total states plus district. 7% = 70,000 */ public int getDistrictTaxRate() { return districtTaxRate; } /** * get state sales tax rate * * @return state sales tax rate, 7% = 70,000 */ public int getStateTaxRate() { return stateTaxRate; } /** * get total sales tax rate * * @return total states plus district. 7% = 70,000 */ public int getTotalTaxRate() { return stateTaxRate + districtTaxRate; } /** * how we display a district on screen */ public String toString() { if ( cityName.length() > 0 ) { if ( countyName.length() > 0 ) { return cityName + " in " + countyName; } else { return cityName; } } else { if ( countyName.length() > 0 ) { if ( countyName.endsWith( "incomplete" ) ) { return countyName; } else { return countyName + " county"; } } else { return "state tax only"; } } } /** * sort by state/city/county. *

* Defines an alternate sort order for SalesTaxItem. */ static class DisplayOrder implements Comparator { /** * sort by category/city/county. * Defines an alternate sort order for DistrictItem with JDK 1.5+ generics. * Compare two DistrictItem Objects. * Compares city case insensitively then county case insensitively. * Informally, returns (a-b), or +ve if a comes after b. * * @param a first DistrictItem to compare * @param b second DistrictItem to compare * * @return +ve if a>b, 0 if a==b, -ve if a<b */ public final int compare( DistrictItem a, DistrictItem b ) { int diff = a.sortCategory - b.sortCategory; // to put item for state to top and counties to bottom. if ( diff != 0 ) { return diff; } diff = a.cityName.compareToIgnoreCase( b.cityName ); if ( diff != 0 ) { return diff; } return a.countyName.compareToIgnoreCase( b.countyName ); } } }