public class NackaCC6YearPlacementReportModel extends ReportModel {

	private final static int COLUMN_SIZE = 2;
	
	private final static int ROW_METHOD_FAMILY_DAYCARE_COMMUNE = 1;
	private final static int ROW_METHOD_PROVIDER_COMMUNE = 2;
	private final static int ROW_METHOD_FAMILY_DAYCARE_PRIVATE = 3;
	private final static int ROW_METHOD_PROVIDER_PRIVATE = 4;
	private final static int ROW_METHOD_SUM = 5;

	private final static int COLUMN_METHOD_COUNT = 101;
	private final static int COLUMN_METHOD_MEAN_HOURS = 102;

	private final static String QUERY_FAMILY_DAYCARE_PLACEMENTS = "family_daycare_placements";
	private final static String QUERY_PROVIDER_PLACEMENTS = "provider_placements";
	private final static String QUERY_FAMILY_DAYCARE_MEAN_HOURS = "family_daycare_mean_hours";
	private final static String QUERY_PROVIDER_MEAN_HOURS = "provider_mean_hours";
	private final static String QUERY_FAMILY_DAYCARE_MEAN_HOURS2 = "family_daycare_mean_hours2";
	private final static String QUERY_PROVIDER_MEAN_HOURS2 = "provider_mean_hours2";
	
	private final static int COMMUNE = 1;
	private final static int PRIVATE = 2;
	
	private final static String KEY_REPORT_TITLE = KP + "title_nacka_child_care_6_year_placements";

	private Map _communeSchoolsByArea = null;
	private Map _privateSchoolsByArea = null;
	
	/**
	 * Constructs this report model.
	 * @param reportBusiness the report business instance for calculating cell values
	 */
	public NackaCC6YearPlacementReportModel(ReportBusiness reportBusiness) {
		super(reportBusiness);
		this._communeSchoolsByArea = new TreeMap();
		this._privateSchoolsByArea = new TreeMap();
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#initReportSize()
	 */
	protected void initReportSize() {
		int rowSize = 0;
		try {
			ReportBusiness rb = getReportBusiness();
			Collection schoolTypes = new ArrayList();
			schoolTypes.add(new Integer(rb.getAfterSchool6TypeId()));
			
			Collection communeManagementTypes = new ArrayList();
			communeManagementTypes.add("COMMUNE");
			
			Collection privateManagementTypes = new ArrayList();
			privateManagementTypes.add("COMPANY");
			privateManagementTypes.add("FOUNDATION");
			privateManagementTypes.add("OTHER");
			privateManagementTypes.add("COOPERATIVE_COMMUNE_LIABILITY");

			Collection areas = rb.getAfterSchool6Areas();
			Iterator iter = areas.iterator();
			while (iter.hasNext()) {
				SchoolArea area = (SchoolArea) iter.next();
				String areaName = area.getName();
				int areaId = ((Integer) area.getPrimaryKey()).intValue();
				
				Collection communeSchools = rb.getCommuneSchools(areaId, schoolTypes, communeManagementTypes);
				this._communeSchoolsByArea.put(areaName, communeSchools);
				rowSize += communeSchools.size();
				
				Collection privateSchools = rb.getCommuneSchools(areaId, schoolTypes, privateManagementTypes);
				this._privateSchoolsByArea.put(areaName, privateSchools);
				rowSize += privateSchools.size();
				
				rowSize += 4; // Sum + family daycare * 2
			}
			setReportSize(rowSize, COLUMN_SIZE);
		} catch (RemoteException e) {}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildRowHeaders()
	 */
	protected Header[] buildRowHeaders() {
		Header[] headers = null;
		try {
			ReportBusiness rb = getReportBusiness();
			Collection areas = rb.getAfterSchool6Areas();
			headers = new Header[areas.size()];
			int headerIndex = 0;
			Iterator areaIter = areas.iterator();
			while (areaIter.hasNext()) {
				SchoolArea area = (SchoolArea) areaIter.next();
				String areaName = area.getName();
				Collection communeSchools = (Collection) this._communeSchoolsByArea.get(areaName);
				Collection privateSchools = (Collection) this._privateSchoolsByArea.get(areaName);
				int nrOfRows = communeSchools.size() + privateSchools.size() + 7;
				Header areaHeader = new Header(areaName, Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER, nrOfRows);
				
				int childIndex = 0;
				
				Header child = new Header(KEY_COMMUNE_UNITS, Header.HEADERTYPE_ROW_LABEL);
				areaHeader.setChild(childIndex++, child);

				child = new Header(KEY_CHILDREN_IN_FAMILY_DAYCARE, Header.HEADERTYPE_ROW_NORMAL);
				areaHeader.setChild(childIndex++, child);
				
				Iterator communeSchoolIter = communeSchools.iterator();
				while (communeSchoolIter.hasNext()) {
					School school = (School) communeSchoolIter.next();
					child = new Header(school.getName(), Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL);
					areaHeader.setChild(childIndex++, child);
				}

				child = new Header(KEY_SUM, Header.HEADERTYPE_ROW_SUM);
				areaHeader.setChild(childIndex++, child);
				
				child = new Header(null, Header.HEADERTYPE_ROW_SPACER);
				areaHeader.setChild(childIndex++, child);
				
				child = new Header(KEY_PRIVATE_UNITS, Header.HEADERTYPE_ROW_LABEL);
				areaHeader.setChild(childIndex++, child);
				
				child = new Header(KEY_CHILDREN_IN_FAMILY_DAYCARE, Header.HEADERTYPE_ROW_NORMAL);
				areaHeader.setChild(childIndex++, child);

				Iterator privateSchoolIter = privateSchools.iterator();
				while (privateSchoolIter.hasNext()) {
					School school = (School) privateSchoolIter.next();
					child = new Header(school.getName(), Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL);
					areaHeader.setChild(childIndex++, child);
				}

				child = new Header(KEY_SUM, Header.HEADERTYPE_ROW_NORMAL);
				areaHeader.setChild(childIndex++, child);

				headers[headerIndex] = areaHeader;
				headerIndex++;				
			}
		} catch (RemoteException e) {}
		
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildColumnHeaders()
	 */
	protected Header[] buildColumnHeaders() {
		Header[] headers = new Header[2];
		
		headers[0] = new Header(KEY_NUMBER_OF_CHILDREN, Header.HEADERTYPE_COLUMN_HEADER);
		headers[1] = new Header(KEY_MEAN_WEEK_HOURS, Header.HEADERTYPE_COLUMN_HEADER);
		
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildCells()
	 */
	protected void buildCells() {
		for (int column = 0; column < getColumnSize(); column++) {
			int row = 0;
			int columnMethod = 0;
			Object columnParameter = null;

			switch (column) {
				case 0:
					columnMethod = COLUMN_METHOD_COUNT;
					break;
				case 1:
					columnMethod = COLUMN_METHOD_MEAN_HOURS;
					break;
			}
	
			Object rowParameter = null;
			int cellType = Cell.CELLTYPE_NORMAL;
			if (column == 1) {
				cellType = Cell.CELLTYPE_PERCENT;
			}
			try {
				ReportBusiness rb = getReportBusiness();
				Collection areas = rb.getAfterSchool6Areas();
				Iterator areaIter = areas.iterator();
				while (areaIter.hasNext()) {
					SchoolArea area = (SchoolArea) areaIter.next();
					String areaName = area.getName();
					Object areaId = area.getPrimaryKey();
					
					Cell cell = new Cell(this, row, column, ROW_METHOD_FAMILY_DAYCARE_COMMUNE,
							columnMethod, areaId, columnParameter, cellType);
					setCell(row++, column, cell);
					
					Collection communeSchools = (Collection) this._communeSchoolsByArea.get(areaName);
					Iterator communeIter = communeSchools.iterator();
					while (communeIter.hasNext()) {
						School school = (School) communeIter.next();
						rowParameter = school.getPrimaryKey();
						cell = new Cell(this, row, column, ROW_METHOD_PROVIDER_COMMUNE,
								columnMethod, rowParameter, columnParameter, cellType);
						setCell(row++, column, cell);
					}
					
					cell = new Cell(this, row, column, ROW_METHOD_SUM,
							columnMethod, rowParameter, columnParameter, cellType);
					setCell(row++, column, cell);

					cell = new Cell(this, row, column, ROW_METHOD_FAMILY_DAYCARE_PRIVATE,
							columnMethod, areaId, columnParameter, cellType);
					setCell(row++, column, cell);

					Collection privateSchools = (Collection) this._privateSchoolsByArea.get(areaName);
					Iterator privateIter = privateSchools.iterator();
					while (privateIter.hasNext()) {
						School school = (School) privateIter.next();
						rowParameter = school.getPrimaryKey();
						cell = new Cell(this, row, column, ROW_METHOD_PROVIDER_PRIVATE,
								columnMethod, rowParameter, columnParameter, cellType);
						setCell(row++, column, cell);
					}

					cell = new Cell(this, row, column, ROW_METHOD_SUM,
							columnMethod, rowParameter, columnParameter, cellType);
					setCell(row++, column, cell);
				}
			} catch (RemoteException e) {}
		}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#calculate()
	 */
	protected float calculate(Cell cell) throws RemoteException {
		float value = 0f;
		int row = cell.getRow();
		int schoolId = -1;
		if (cell.getRowParameter() != null) {
			schoolId = ((Integer) cell.getRowParameter()).intValue();
		}
		int areaId = schoolId; // if type family daycare

		switch (cell.getColumnMethod()) {
			case COLUMN_METHOD_COUNT:
				switch (cell.getRowMethod()) {
					case ROW_METHOD_FAMILY_DAYCARE_COMMUNE:
						value = getFamilyDaycarePlacementCount(areaId, COMMUNE);
						break;
					case ROW_METHOD_PROVIDER_COMMUNE:
						value = getProviderPlacementCount(schoolId);
						break;
					case ROW_METHOD_FAMILY_DAYCARE_PRIVATE:
						value = getFamilyDaycarePlacementCount(areaId, PRIVATE);
						break;
					case ROW_METHOD_PROVIDER_PRIVATE:
						value = getProviderPlacementCount(schoolId);
						break;
					case ROW_METHOD_SUM:
						int i = row - 1;
						while (i >= 0 && getCell(i, 0).getRowMethod() != ROW_METHOD_SUM) {
							value += getCell(i, 0).getFloatValue();
							i--;
						}
						break;
				}
				break;
			case COLUMN_METHOD_MEAN_HOURS:
			switch (cell.getRowMethod()) {
				case ROW_METHOD_FAMILY_DAYCARE_COMMUNE:
					value = getFamilyDaycareMeanHours(areaId, COMMUNE);
					break;
				case ROW_METHOD_PROVIDER_COMMUNE:
					value = getProviderMeanHours(schoolId);
					break;
				case ROW_METHOD_FAMILY_DAYCARE_PRIVATE:
					value = getFamilyDaycareMeanHours(areaId, PRIVATE);
					break;
				case ROW_METHOD_PROVIDER_PRIVATE:
					value = getProviderMeanHours(schoolId);
					break;
				case ROW_METHOD_SUM:
					int i = row - 1;
					int rowCount = 0;
					while (i >= 0 && getCell(i, 1).getRowMethod() != ROW_METHOD_SUM) {
						float hours = getCell(i, 1).getFloatValue(); 
						value += hours;
						if (hours > 0) {
							rowCount++;
						}
						i--;
					}
					if (rowCount > 0) {
						value /= rowCount;
					}
					break;
			}
			break;
		}
		
		return value;
	}

	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#getReportTitleLocalizationKey()
	 */
	public String getReportTitleLocalizationKey() {
		return KEY_REPORT_TITLE;
	}
	
	/**
	 * Returns the number of child placements in family daycare for the specified management type.
	 */
	protected int getFamilyDaycarePlacementCount(int areaId, int managementType) throws RemoteException {
		ReportBusiness rb = getReportBusiness();
		
		int schoolType = rb.getFamilyAfterSchool6TypeId();
				
		String managementType1 = null;
		String managementType2 = null;
		String managementType3 = null;
		String managementType4 = null;
		
		switch (managementType) {
			case COMMUNE:
				managementType1 = "COMMUNE";
				managementType2 = managementType1;
				managementType3 = managementType1;
				managementType4 = managementType1;
				break;
			case PRIVATE:
				managementType1 = "COMPANY";
				managementType2 = "FOUNDATION";
				managementType3 = "OTHER";
				managementType4 = "COOPERATIVE_COMMUNE_LIABILITY";
				break;
		}
		
		PreparedQuery query = null;
		query = getQuery(QUERY_FAMILY_DAYCARE_PLACEMENTS);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCount();
			query.setChildCarePlacements();
			query.setSchoolTypeForProvider(); // parameter 1
			query.setFourManagementTypes(); // parameter 2-5
			query.setSchoolArea(); // parameter 6
			query.prepare();
			setQuery(QUERY_FAMILY_DAYCARE_PLACEMENTS, query);
		}
		query.setInt(1, schoolType);
		
		query.setString(2, managementType1);
		query.setString(3, managementType2);
		query.setString(4, managementType3);
		query.setString(5, managementType4);
		
		query.setInt(6, areaId);
		
		return query.execute();
	}
	
	/**
	 * Returns the number of child placements for the specified school.
	 */
	protected int getProviderPlacementCount(int schoolId) throws RemoteException {
		ReportBusiness rb = getReportBusiness();
		int schoolType = rb.getAfterSchool6TypeId();

		PreparedQuery query = null;
		query = getQuery(QUERY_PROVIDER_PLACEMENTS);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCount();
			query.setChildCarePlacements();
			query.setSchool(); // parameter 1
			query.setSchoolTypeForProvider(); // parameter 2
			query.prepare();
			setQuery(QUERY_PROVIDER_PLACEMENTS, query);
		}
		query.setInt(1, schoolId);
		query.setInt(2, schoolType);
		
		return query.execute();
	}
	
	/**
	 * Returns the mean week hours in family daycare for the specified management type.
	 */
	protected float getFamilyDaycareMeanHours(int areaId, int managementType) throws RemoteException {
		ReportBusiness rb = getReportBusiness();
		
		int schoolType = rb.getFamilyAfterSchool6TypeId();
				
		String managementType1 = null;
		String managementType2 = null;
		String managementType3 = null;
		String managementType4 = null;
		
		switch (managementType) {
			case COMMUNE:
				managementType1 = "COMMUNE";
				managementType2 = managementType1;
				managementType3 = managementType1;
				managementType4 = managementType1;
				break;
			case PRIVATE:
				managementType1 = "COMPANY";
				managementType2 = "FOUNDATION";
				managementType3 = "OTHER";
				managementType4 = "COOPERATIVE_COMMUNE_LIABILITY";
				break;
		}
		
		PreparedQuery query = null;
		PreparedQuery query2 = null;
		query = getQuery(QUERY_FAMILY_DAYCARE_MEAN_HOURS);
		query2 = getQuery(QUERY_FAMILY_DAYCARE_MEAN_HOURS2);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectMeanChildCareWeekHoursCareTime();
			query.setChildCarePlacementsCareTime();
			query.setSchoolTypeForProvider(); // parameter 1
			query.setFourManagementTypes(); // parameter 2-5
			query.setSchoolArea(); // parameter 6
			query.prepare();
			setQuery(QUERY_FAMILY_DAYCARE_MEAN_HOURS, query);
			
			query2 = new PreparedQuery(getConnection());
			query2.setSelectMeanChildCareWeekHoursCareTimeString();
			query2.setChildCarePlacementsCareTimeString();
			query2.setSchoolTypeForProvider(); // parameter 1
			query2.setFourManagementTypes(); // parameter 2-5
			query2.setSchoolArea(); // parameter 6
			query2.prepare();
			setQuery(QUERY_FAMILY_DAYCARE_MEAN_HOURS2, query2);			
		}
		query.setInt(1, schoolType);		
		query.setString(2, managementType1);
		query.setString(3, managementType2);
		query.setString(4, managementType3);
		query.setString(5, managementType4);		
		query.setInt(6, areaId);

		query2.setInt(1, schoolType);		
		query2.setString(2, managementType1);
		query2.setString(3, managementType2);
		query2.setString(4, managementType3);
		query2.setString(5, managementType4);		
		query2.setInt(6, areaId);

		return (query.executeFloat() + query2.executeFloat()) / 2;
	}
	
	/**
	 * Returns the number of child placement mean hours for the specified school.
	 */
	protected float getProviderMeanHours(int schoolId) throws RemoteException {
		ReportBusiness rb = getReportBusiness();
		int schoolType = rb.getAfterSchool6TypeId();

		PreparedQuery query = null;
		PreparedQuery query2 = null;
		query = getQuery(QUERY_PROVIDER_MEAN_HOURS);
		query2 = getQuery(QUERY_PROVIDER_MEAN_HOURS2);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectMeanChildCareWeekHoursCareTime();
			query.setChildCarePlacementsCareTime();
			query.setSchool(); // parameter 1
			query.setSchoolTypeForProvider(); // parameter 2
			query.prepare();
			setQuery(QUERY_PROVIDER_MEAN_HOURS, query);
			
			query2 = new PreparedQuery(getConnection());
			query2.setSelectMeanChildCareWeekHoursCareTimeString();
			query2.setChildCarePlacementsCareTimeString();
			query2.setSchool(); // parameter 1
			query2.setSchoolTypeForProvider(); // parameter 2
			query2.prepare();
			setQuery(QUERY_PROVIDER_MEAN_HOURS2, query2);

		}
		query.setInt(1, schoolId);
		query.setInt(2, schoolType);

		query2.setInt(1, schoolId);
		query2.setInt(2, schoolType);
		
		return (query.executeFloat() + query2.executeFloat()) / 2;
	}
	
} public class NackaCC7_9YearPlacementReportModel extends ReportModel {

	private final static int COLUMN_SIZE = 2;
	
	private final static int ROW_METHOD_FAMILY_DAYCARE_COMMUNE = 1;
	private final static int ROW_METHOD_PROVIDER_COMMUNE = 2;
	private final static int ROW_METHOD_FAMILY_DAYCARE_PRIVATE = 3;
	private final static int ROW_METHOD_PROVIDER_PRIVATE = 4;
	private final static int ROW_METHOD_SUM = 5;

	private final static int COLUMN_METHOD_COUNT = 101;
	private final static int COLUMN_METHOD_MEAN_HOURS = 102;

	private final static String QUERY_FAMILY_DAYCARE_PLACEMENTS = "family_daycare_placements";
	private final static String QUERY_PROVIDER_PLACEMENTS = "provider_placements";
	private final static String QUERY_FAMILY_DAYCARE_MEAN_HOURS = "family_daycare_mean_hours";
	private final static String QUERY_PROVIDER_MEAN_HOURS = "provider_mean_hours";
	private final static String QUERY_FAMILY_DAYCARE_MEAN_HOURS2 = "family_daycare_mean_hours2";
	private final static String QUERY_PROVIDER_MEAN_HOURS2 = "provider_mean_hours2";
	
	private final static int COMMUNE = 1;
	private final static int PRIVATE = 2;
	
	private final static String KEY_REPORT_TITLE = KP + "title_nacka_child_care_7_9_year_placements";

	private Map _communeSchoolsByArea = null;
	private Map _privateSchoolsByArea = null;
	
	/**
	 * Constructs this report model.
	 * @param reportBusiness the report business instance for calculating cell values
	 */
	public NackaCC7_9YearPlacementReportModel(ReportBusiness reportBusiness) {
		super(reportBusiness);
		this._communeSchoolsByArea = new TreeMap();
		this._privateSchoolsByArea = new TreeMap();
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#initReportSize()
	 */
	protected void initReportSize() {
		int rowSize = 0;
		try {
			ReportBusiness rb = getReportBusiness();
			Collection schoolTypes = new ArrayList();
			schoolTypes.add(new Integer(rb.getAfterSchool7_9TypeId()));
			
			Collection communeManagementTypes = new ArrayList();
			communeManagementTypes.add("COMMUNE");
			
			Collection privateManagementTypes = new ArrayList();
			privateManagementTypes.add("COMPANY");
			privateManagementTypes.add("FOUNDATION");
			privateManagementTypes.add("OTHER");
			privateManagementTypes.add("COOPERATIVE_COMMUNE_LIABILITY");

			Collection areas = rb.getAfterSchool7_9Areas();
			Iterator iter = areas.iterator();
			while (iter.hasNext()) {
				SchoolArea area = (SchoolArea) iter.next();
				String areaName = area.getName();
				int areaId = ((Integer) area.getPrimaryKey()).intValue();
				
				Collection communeSchools = rb.getCommuneSchools(areaId, schoolTypes, communeManagementTypes);
				this._communeSchoolsByArea.put(areaName, communeSchools);
				rowSize += communeSchools.size();
				
				Collection privateSchools = rb.getCommuneSchools(areaId, schoolTypes, privateManagementTypes);
				this._privateSchoolsByArea.put(areaName, privateSchools);
				rowSize += privateSchools.size();
				
				rowSize += 4; // Sum + family daycare * 2
			}
			setReportSize(rowSize, COLUMN_SIZE);
		} catch (RemoteException e) {}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildRowHeaders()
	 */
	protected Header[] buildRowHeaders() {
		Header[] headers = null;
		try {
			ReportBusiness rb = getReportBusiness();
			Collection areas = rb.getAfterSchool7_9Areas();
			headers = new Header[areas.size()];
			int headerIndex = 0;
			Iterator areaIter = areas.iterator();
			while (areaIter.hasNext()) {
				SchoolArea area = (SchoolArea) areaIter.next();
				String areaName = area.getName();
				Collection communeSchools = (Collection) this._communeSchoolsByArea.get(areaName);
				Collection privateSchools = (Collection) this._privateSchoolsByArea.get(areaName);
				int nrOfRows = communeSchools.size() + privateSchools.size() + 7;
				Header areaHeader = new Header(areaName, Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER, nrOfRows);
				
				int childIndex = 0;
				
				Header child = new Header(KEY_COMMUNE_UNITS, Header.HEADERTYPE_ROW_LABEL);
				areaHeader.setChild(childIndex++, child);

				child = new Header(KEY_CHILDREN_IN_FAMILY_DAYCARE, Header.HEADERTYPE_ROW_NORMAL);
				areaHeader.setChild(childIndex++, child);
				
				Iterator communeSchoolIter = communeSchools.iterator();
				while (communeSchoolIter.hasNext()) {
					School school = (School) communeSchoolIter.next();
					child = new Header(school.getName(), Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL);
					areaHeader.setChild(childIndex++, child);
				}

				child = new Header(KEY_SUM, Header.HEADERTYPE_ROW_SUM);
				areaHeader.setChild(childIndex++, child);
				
				child = new Header(null, Header.HEADERTYPE_ROW_SPACER);
				areaHeader.setChild(childIndex++, child);
				
				child = new Header(KEY_PRIVATE_UNITS, Header.HEADERTYPE_ROW_LABEL);
				areaHeader.setChild(childIndex++, child);
				
				child = new Header(KEY_CHILDREN_IN_FAMILY_DAYCARE, Header.HEADERTYPE_ROW_NORMAL);
				areaHeader.setChild(childIndex++, child);

				Iterator privateSchoolIter = privateSchools.iterator();
				while (privateSchoolIter.hasNext()) {
					School school = (School) privateSchoolIter.next();
					child = new Header(school.getName(), Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL);
					areaHeader.setChild(childIndex++, child);
				}

				child = new Header(KEY_SUM, Header.HEADERTYPE_ROW_NORMAL);
				areaHeader.setChild(childIndex++, child);

				headers[headerIndex] = areaHeader;
				headerIndex++;				
			}
		} catch (RemoteException e) {}
		
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildColumnHeaders()
	 */
	protected Header[] buildColumnHeaders() {
		Header[] headers = new Header[2];
		
		headers[0] = new Header(KEY_NUMBER_OF_CHILDREN, Header.HEADERTYPE_COLUMN_HEADER);
		headers[1] = new Header(KEY_MEAN_WEEK_HOURS, Header.HEADERTYPE_COLUMN_HEADER);
		
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildCells()
	 */
	protected void buildCells() {
		for (int column = 0; column < getColumnSize(); column++) {
			int row = 0;
			int columnMethod = 0;
			Object columnParameter = null;

			switch (column) {
				case 0:
					columnMethod = COLUMN_METHOD_COUNT;
					break;
				case 1:
					columnMethod = COLUMN_METHOD_MEAN_HOURS;
					break;
			}
	
			Object rowParameter = null;
			int cellType = Cell.CELLTYPE_NORMAL;
			if (column == 1) {
				cellType = Cell.CELLTYPE_PERCENT;
			}
			try {
				ReportBusiness rb = getReportBusiness();
				Collection areas = rb.getAfterSchool7_9Areas();
				Iterator areaIter = areas.iterator();
				while (areaIter.hasNext()) {
					SchoolArea area = (SchoolArea) areaIter.next();
					String areaName = area.getName();
					Object areaId = area.getPrimaryKey();
					
					Cell cell = new Cell(this, row, column, ROW_METHOD_FAMILY_DAYCARE_COMMUNE,
							columnMethod, areaId, columnParameter, cellType);
					setCell(row++, column, cell);
					
					Collection communeSchools = (Collection) this._communeSchoolsByArea.get(areaName);
					Iterator communeIter = communeSchools.iterator();
					while (communeIter.hasNext()) {
						School school = (School) communeIter.next();
						rowParameter = school.getPrimaryKey();
						cell = new Cell(this, row, column, ROW_METHOD_PROVIDER_COMMUNE,
								columnMethod, rowParameter, columnParameter, cellType);
						setCell(row++, column, cell);
					}
					
					cell = new Cell(this, row, column, ROW_METHOD_SUM,
							columnMethod, rowParameter, columnParameter, cellType);
					setCell(row++, column, cell);

					cell = new Cell(this, row, column, ROW_METHOD_FAMILY_DAYCARE_PRIVATE,
							columnMethod, areaId, columnParameter, cellType);
					setCell(row++, column, cell);

					Collection privateSchools = (Collection) this._privateSchoolsByArea.get(areaName);
					Iterator privateIter = privateSchools.iterator();
					while (privateIter.hasNext()) {
						School school = (School) privateIter.next();
						rowParameter = school.getPrimaryKey();
						cell = new Cell(this, row, column, ROW_METHOD_PROVIDER_PRIVATE,
								columnMethod, rowParameter, columnParameter, cellType);
						setCell(row++, column, cell);
					}

					cell = new Cell(this, row, column, ROW_METHOD_SUM,
							columnMethod, rowParameter, columnParameter, cellType);
					setCell(row++, column, cell);
				}
			} catch (RemoteException e) {}
		}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#calculate()
	 */
	protected float calculate(Cell cell) throws RemoteException {
		float value = 0f;
		int row = cell.getRow();
		int schoolId = -1;
		if (cell.getRowParameter() != null) {
			schoolId = ((Integer) cell.getRowParameter()).intValue();
		}
		int areaId = schoolId; // if type family daycare

		switch (cell.getColumnMethod()) {
			case COLUMN_METHOD_COUNT:
				switch (cell.getRowMethod()) {
					case ROW_METHOD_FAMILY_DAYCARE_COMMUNE:
						value = getFamilyDaycarePlacementCount(areaId, COMMUNE);
						break;
					case ROW_METHOD_PROVIDER_COMMUNE:
						value = getProviderPlacementCount(schoolId);
						break;
					case ROW_METHOD_FAMILY_DAYCARE_PRIVATE:
						value = getFamilyDaycarePlacementCount(areaId, PRIVATE);
						break;
					case ROW_METHOD_PROVIDER_PRIVATE:
						value = getProviderPlacementCount(schoolId);
						break;
					case ROW_METHOD_SUM:
						int i = row - 1;
						while (i >= 0 && getCell(i, 0).getRowMethod() != ROW_METHOD_SUM) {
							value += getCell(i, 0).getFloatValue();
							i--;
						}
						break;
				}
				break;
			case COLUMN_METHOD_MEAN_HOURS:
			switch (cell.getRowMethod()) {
				case ROW_METHOD_FAMILY_DAYCARE_COMMUNE:
					value = getFamilyDaycareMeanHours(areaId, COMMUNE);
					break;
				case ROW_METHOD_PROVIDER_COMMUNE:
					value = getProviderMeanHours(schoolId);
					break;
				case ROW_METHOD_FAMILY_DAYCARE_PRIVATE:
					value = getFamilyDaycareMeanHours(areaId, PRIVATE);
					break;
				case ROW_METHOD_PROVIDER_PRIVATE:
					value = getProviderMeanHours(schoolId);
					break;
				case ROW_METHOD_SUM:
					int i = row - 1;
					int rowCount = 0;
					while (i >= 0 && getCell(i, 1).getRowMethod() != ROW_METHOD_SUM) {
						float hours = getCell(i, 1).getFloatValue(); 
						value += hours;
						if (hours > 0) {
							rowCount++;
						}
						i--;
					}
					if (rowCount > 0) {
						value /= rowCount;
					}
					break;
			}
			break;
		}
		
		return value;
	}

	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#getReportTitleLocalizationKey()
	 */
	public String getReportTitleLocalizationKey() {
		return KEY_REPORT_TITLE;
	}
	
	/**
	 * Returns the number of child placements in family daycare for the specified management type.
	 */
	protected int getFamilyDaycarePlacementCount(int areaId, int managementType) throws RemoteException {
		ReportBusiness rb = getReportBusiness();
		
		int schoolType = rb.getFamilyAfterSchool7_9TypeId();
				
		String managementType1 = null;
		String managementType2 = null;
		String managementType3 = null;
		String managementType4 = null;
		
		switch (managementType) {
			case COMMUNE:
				managementType1 = "COMMUNE";
				managementType2 = managementType1;
				managementType3 = managementType1;
				managementType4 = managementType1;
				break;
			case PRIVATE:
				managementType1 = "COMPANY";
				managementType2 = "FOUNDATION";
				managementType3 = "OTHER";
				managementType4 = "COOPERATIVE_COMMUNE_LIABILITY";
				break;
		}
		
		PreparedQuery query = null;
		query = getQuery(QUERY_FAMILY_DAYCARE_PLACEMENTS);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCount();
			query.setChildCarePlacements();
			query.setSchoolTypeForProvider(); // parameter 1
			query.setFourManagementTypes(); // parameter 2-5
			query.setSchoolArea(); // parameter 6
			query.prepare();
			setQuery(QUERY_FAMILY_DAYCARE_PLACEMENTS, query);
		}
		query.setInt(1, schoolType);
		
		query.setString(2, managementType1);
		query.setString(3, managementType2);
		query.setString(4, managementType3);
		query.setString(5, managementType4);
		
		query.setInt(6, areaId);
		
		return query.execute();
	}
	
	/**
	 * Returns the number of child placements for the specified school.
	 */
	protected int getProviderPlacementCount(int schoolId) throws RemoteException {
		ReportBusiness rb = getReportBusiness();
		int schoolType = rb.getAfterSchool7_9TypeId();

		PreparedQuery query = null;
		query = getQuery(QUERY_PROVIDER_PLACEMENTS);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCount();
			query.setChildCarePlacements();
			query.setSchool(); // parameter 1
			query.setSchoolTypeForProvider(); // parameter 2
			query.prepare();
			setQuery(QUERY_PROVIDER_PLACEMENTS, query);
		}
		query.setInt(1, schoolId);
		query.setInt(2, schoolType);
		
		return query.execute();
	}
	
	/**
	 * Returns the mean week hours in family daycare for the specified management type.
	 */
	protected float getFamilyDaycareMeanHours(int areaId, int managementType) throws RemoteException {
		ReportBusiness rb = getReportBusiness();
		
		int schoolType = rb.getFamilyAfterSchool7_9TypeId();
				
		String managementType1 = null;
		String managementType2 = null;
		String managementType3 = null;
		String managementType4 = null;
		
		switch (managementType) {
			case COMMUNE:
				managementType1 = "COMMUNE";
				managementType2 = managementType1;
				managementType3 = managementType1;
				managementType4 = managementType1;
				break;
			case PRIVATE:
				managementType1 = "COMPANY";
				managementType2 = "FOUNDATION";
				managementType3 = "OTHER";
				managementType4 = "COOPERATIVE_COMMUNE_LIABILITY";
				break;
		}
		
		PreparedQuery query = null;
		PreparedQuery query2 = null;
		query = getQuery(QUERY_FAMILY_DAYCARE_MEAN_HOURS);
		query2 = getQuery(QUERY_FAMILY_DAYCARE_MEAN_HOURS2);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectMeanChildCareWeekHoursCareTime();
			query.setChildCarePlacementsCareTime();
			query.setSchoolTypeForProvider(); // parameter 1
			query.setFourManagementTypes(); // parameter 2-5
			query.setSchoolArea(); // parameter 6
			query.prepare();
			setQuery(QUERY_FAMILY_DAYCARE_MEAN_HOURS, query);
			
			query2 = new PreparedQuery(getConnection());
			query2.setSelectMeanChildCareWeekHoursCareTimeString();
			query2.setChildCarePlacementsCareTimeString();
			query2.setSchoolTypeForProvider(); // parameter 1
			query2.setFourManagementTypes(); // parameter 2-5
			query2.setSchoolArea(); // parameter 6
			query2.prepare();
			setQuery(QUERY_FAMILY_DAYCARE_MEAN_HOURS2, query2);
		}
		
		query.setInt(1, schoolType);		
		query.setString(2, managementType1);
		query.setString(3, managementType2);
		query.setString(4, managementType3);
		query.setString(5, managementType4);		
		query.setInt(6, areaId);
		
		query2.setInt(1, schoolType);		
		query2.setString(2, managementType1);
		query2.setString(3, managementType2);
		query2.setString(4, managementType3);
		query2.setString(5, managementType4);		
		query2.setInt(6, areaId);
		
		return (query.executeFloat() + query2.executeFloat()) / 2;
	}
	
	/**
	 * Returns the number of child placement mean hours for the specified school.
	 */
	protected float getProviderMeanHours(int schoolId) throws RemoteException {
		ReportBusiness rb = getReportBusiness();
		int schoolType = rb.getAfterSchool7_9TypeId();

		PreparedQuery query = null;
		PreparedQuery query2 = null;
		query = getQuery(QUERY_PROVIDER_MEAN_HOURS);
		query2 = getQuery(QUERY_PROVIDER_MEAN_HOURS2);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectMeanChildCareWeekHoursCareTime();
			query.setChildCarePlacementsCareTime();
			query.setSchool(); // parameter 1
			query.setSchoolTypeForProvider(); // parameter 2
			query.prepare();
			setQuery(QUERY_PROVIDER_MEAN_HOURS, query);
			
			query2 = new PreparedQuery(getConnection());
			query2.setSelectMeanChildCareWeekHoursCareTimeString();
			query2.setChildCarePlacementsCareTimeString();
			query2.setSchool(); // parameter 1
			query2.setSchoolTypeForProvider(); // parameter 2
			query2.prepare();
			setQuery(QUERY_PROVIDER_MEAN_HOURS2, query2);
		}

		query.setInt(1, schoolId);
		query.setInt(2, schoolType);

		query2.setInt(1, schoolId);
		query2.setInt(2, schoolType);

		return (query.executeFloat() + query2.executeFloat()) / 2;
	}
	
} public class NackaCCPreSchoolPlacementReportModel extends ReportModel {

	private final static int COLUMN_SIZE = 2;
	
	private final static int ROW_METHOD_FAMILY_DAYCARE_COMMUNE = 1;
	private final static int ROW_METHOD_PROVIDER_COMMUNE = 2;
	private final static int ROW_METHOD_FAMILY_DAYCARE_PRIVATE = 3;
	private final static int ROW_METHOD_PROVIDER_PRIVATE = 4;
	private final static int ROW_METHOD_SUM = 5;

	private final static int COLUMN_METHOD_COUNT = 101;
	private final static int COLUMN_METHOD_MEAN_HOURS = 102;

	private final static String QUERY_FAMILY_DAYCARE_PLACEMENTS = "family_daycare_placements";
	private final static String QUERY_PROVIDER_PLACEMENTS = "provider_placements";
	private final static String QUERY_FAMILY_DAYCARE_MEAN_HOURS = "family_daycare_mean_hours";
	private final static String QUERY_PROVIDER_MEAN_HOURS = "provider_mean_hours";
	private final static String QUERY_FAMILY_DAYCARE_MEAN_HOURS2 = "family_daycare_mean_hours2";
	private final static String QUERY_PROVIDER_MEAN_HOURS2 = "provider_mean_hours2";
	
	private final static int COMMUNE = 1;
	private final static int PRIVATE = 2;
	
	private final static String KEY_REPORT_TITLE = KP + "title_nacka_child_care_pre_school_placements";

	private Map _communeSchoolsByArea = null;
	private Map _privateSchoolsByArea = null;
	
	/**
	 * Constructs this report model.
	 * @param reportBusiness the report business instance for calculating cell values
	 */
	public NackaCCPreSchoolPlacementReportModel(ReportBusiness reportBusiness) {
		super(reportBusiness);
		this._communeSchoolsByArea = new TreeMap();
		this._privateSchoolsByArea = new TreeMap();
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#initReportSize()
	 */
	protected void initReportSize() {
		int rowSize = 0;
		try {
			ReportBusiness rb = getReportBusiness();
			Collection schoolTypes = new ArrayList();
			schoolTypes.add(new Integer(rb.getPreSchoolTypeId()));
			schoolTypes.add(new Integer(rb.getGeneralPreSchoolTypeId()));
			
			Collection communeManagementTypes = new ArrayList();
			communeManagementTypes.add("COMMUNE");
			
			Collection privateManagementTypes = new ArrayList();
			privateManagementTypes.add("COMPANY");
			privateManagementTypes.add("FOUNDATION");
			privateManagementTypes.add("OTHER");
			privateManagementTypes.add("COOPERATIVE_COMMUNE_LIABILITY");

			Collection areas = rb.getPreSchoolOperationAreas();
			Iterator iter = areas.iterator();
			while (iter.hasNext()) {
				SchoolArea area = (SchoolArea) iter.next();
				String areaName = area.getName();
				int areaId = ((Integer) area.getPrimaryKey()).intValue();
				
				Collection communeSchools = rb.getCommuneSchools(areaId, schoolTypes, communeManagementTypes);
				this._communeSchoolsByArea.put(areaName, communeSchools);
				rowSize += communeSchools.size();
				
				Collection privateSchools = rb.getCommuneSchools(areaId, schoolTypes, privateManagementTypes);
				this._privateSchoolsByArea.put(areaName, privateSchools);
				rowSize += privateSchools.size();
				
				rowSize += 4; // Sum + family daycare * 2
			}
			setReportSize(rowSize, COLUMN_SIZE);
		} catch (RemoteException e) {}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildRowHeaders()
	 */
	protected Header[] buildRowHeaders() {
		Header[] headers = null;
		try {
			ReportBusiness rb = getReportBusiness();
			Collection areas = rb.getPreSchoolOperationAreas();
			headers = new Header[areas.size()];
			int headerIndex = 0;
			Iterator areaIter = areas.iterator();
			while (areaIter.hasNext()) {
				SchoolArea area = (SchoolArea) areaIter.next();
				String areaName = area.getName();
				Collection communeSchools = (Collection) this._communeSchoolsByArea.get(areaName);
				Collection privateSchools = (Collection) this._privateSchoolsByArea.get(areaName);
				int nrOfRows = communeSchools.size() + privateSchools.size() + 7;
				Header areaHeader = new Header(areaName, Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER, nrOfRows);
				
				int childIndex = 0;
				
				Header child = new Header(KEY_COMMUNE_UNITS, Header.HEADERTYPE_ROW_LABEL);
				areaHeader.setChild(childIndex++, child);

				child = new Header(KEY_CHILDREN_IN_FAMILY_DAYCARE, Header.HEADERTYPE_ROW_NORMAL);
				areaHeader.setChild(childIndex++, child);
				
				Iterator communeSchoolIter = communeSchools.iterator();
				while (communeSchoolIter.hasNext()) {
					School school = (School) communeSchoolIter.next();
					child = new Header(school.getName(), Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL);
					areaHeader.setChild(childIndex++, child);
				}

				child = new Header(KEY_SUM, Header.HEADERTYPE_ROW_SUM);
				areaHeader.setChild(childIndex++, child);
				
				child = new Header(null, Header.HEADERTYPE_ROW_SPACER);
				areaHeader.setChild(childIndex++, child);
				
				child = new Header(KEY_PRIVATE_UNITS, Header.HEADERTYPE_ROW_LABEL);
				areaHeader.setChild(childIndex++, child);
				
				child = new Header(KEY_CHILDREN_IN_FAMILY_DAYCARE, Header.HEADERTYPE_ROW_NORMAL);
				areaHeader.setChild(childIndex++, child);

				Iterator privateSchoolIter = privateSchools.iterator();
				while (privateSchoolIter.hasNext()) {
					School school = (School) privateSchoolIter.next();
					child = new Header(school.getName(), Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL);
					areaHeader.setChild(childIndex++, child);
				}

				child = new Header(KEY_SUM, Header.HEADERTYPE_ROW_NORMAL);
				areaHeader.setChild(childIndex++, child);

				headers[headerIndex] = areaHeader;
				headerIndex++;				
			}
		} catch (RemoteException e) {}
		
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildColumnHeaders()
	 */
	protected Header[] buildColumnHeaders() {
		Header[] headers = new Header[2];
		
		headers[0] = new Header(KEY_NUMBER_OF_CHILDREN, Header.HEADERTYPE_COLUMN_HEADER);
		headers[1] = new Header(KEY_MEAN_WEEK_HOURS, Header.HEADERTYPE_COLUMN_HEADER);
		
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildCells()
	 */
	protected void buildCells() {
		for (int column = 0; column < getColumnSize(); column++) {
			int row = 0;
			int columnMethod = 0;
			Object columnParameter = null;

			switch (column) {
				case 0:
					columnMethod = COLUMN_METHOD_COUNT;
					break;
				case 1:
					columnMethod = COLUMN_METHOD_MEAN_HOURS;
					break;
			}
	
			Object rowParameter = null;
			int cellType = Cell.CELLTYPE_NORMAL;
			if (column == 1) {
				cellType = Cell.CELLTYPE_PERCENT;
			}
			try {
				ReportBusiness rb = getReportBusiness();
				Collection areas = rb.getPreSchoolOperationAreas();
				Iterator areaIter = areas.iterator();
				while (areaIter.hasNext()) {
					SchoolArea area = (SchoolArea) areaIter.next();
					String areaName = area.getName();
					Object areaId = area.getPrimaryKey();
					
					Cell cell = new Cell(this, row, column, ROW_METHOD_FAMILY_DAYCARE_COMMUNE,
							columnMethod, areaId, columnParameter, cellType);
					setCell(row++, column, cell);
					
					Collection communeSchools = (Collection) this._communeSchoolsByArea.get(areaName);
					Iterator communeIter = communeSchools.iterator();
					while (communeIter.hasNext()) {
						School school = (School) communeIter.next();
						rowParameter = school.getPrimaryKey();
						cell = new Cell(this, row, column, ROW_METHOD_PROVIDER_COMMUNE,
								columnMethod, rowParameter, columnParameter, cellType);
						setCell(row++, column, cell);
					}
					
					cell = new Cell(this, row, column, ROW_METHOD_SUM,
							columnMethod, rowParameter, columnParameter, cellType);
					setCell(row++, column, cell);

					cell = new Cell(this, row, column, ROW_METHOD_FAMILY_DAYCARE_PRIVATE,
							columnMethod, areaId, columnParameter, cellType);
					setCell(row++, column, cell);

					Collection privateSchools = (Collection) this._privateSchoolsByArea.get(areaName);
					Iterator privateIter = privateSchools.iterator();
					while (privateIter.hasNext()) {
						School school = (School) privateIter.next();
						rowParameter = school.getPrimaryKey();
						cell = new Cell(this, row, column, ROW_METHOD_PROVIDER_PRIVATE,
								columnMethod, rowParameter, columnParameter, cellType);
						setCell(row++, column, cell);
					}

					cell = new Cell(this, row, column, ROW_METHOD_SUM,
							columnMethod, rowParameter, columnParameter, cellType);
					setCell(row++, column, cell);
				}
			} catch (RemoteException e) {}
		}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#calculate()
	 */
	protected float calculate(Cell cell) throws RemoteException {
		float value = 0f;
		int row = cell.getRow();
		int schoolId = -1;
		if (cell.getRowParameter() != null) {
			schoolId = ((Integer) cell.getRowParameter()).intValue();
		}
		int areaId = schoolId; // if type family daycare

		switch (cell.getColumnMethod()) {
			case COLUMN_METHOD_COUNT:
				switch (cell.getRowMethod()) {
					case ROW_METHOD_FAMILY_DAYCARE_COMMUNE:
						value = getFamilyDaycarePlacementCount(areaId, COMMUNE);
						break;
					case ROW_METHOD_PROVIDER_COMMUNE:
						value = getProviderPlacementCount(schoolId);
						break;
					case ROW_METHOD_FAMILY_DAYCARE_PRIVATE:
						value = getFamilyDaycarePlacementCount(areaId, PRIVATE);
						break;
					case ROW_METHOD_PROVIDER_PRIVATE:
						value = getProviderPlacementCount(schoolId);
						break;
					case ROW_METHOD_SUM:
						int i = row - 1;
						while (i >= 0 && getCell(i, 0).getRowMethod() != ROW_METHOD_SUM) {
							value += getCell(i, 0).getFloatValue();
							i--;
						}
						break;
				}
				break;
			case COLUMN_METHOD_MEAN_HOURS:
			switch (cell.getRowMethod()) {
				case ROW_METHOD_FAMILY_DAYCARE_COMMUNE:
					value = getFamilyDaycareMeanHours(areaId, COMMUNE);
					break;
				case ROW_METHOD_PROVIDER_COMMUNE:
					value = getProviderMeanHours(schoolId);
					break;
				case ROW_METHOD_FAMILY_DAYCARE_PRIVATE:
					value = getFamilyDaycareMeanHours(areaId, PRIVATE);
					break;
				case ROW_METHOD_PROVIDER_PRIVATE:
					value = getProviderMeanHours(schoolId);
					break;
				case ROW_METHOD_SUM:
					int i = row - 1;
					int rowCount = 0;
					while (i >= 0 && getCell(i, 1).getRowMethod() != ROW_METHOD_SUM) {
						float hours = getCell(i, 1).getFloatValue(); 
						value += hours;
						if (hours > 0) {
							rowCount++;
						}
						i--;
					}
					if (rowCount > 0) {
						value /= rowCount;
					}
					break;
			}
			break;
		}
		
		return value;
	}

	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#getReportTitleLocalizationKey()
	 */
	public String getReportTitleLocalizationKey() {
		return KEY_REPORT_TITLE;
	}
	
	/**
	 * Returns the number of child placements in family daycare for the specified management type.
	 */
	protected int getFamilyDaycarePlacementCount(int areaId, int managementType) throws RemoteException {
		ReportBusiness rb = getReportBusiness();
		
		int schoolType1 = rb.getFamilyDayCareSchoolTypeId();
		int schoolType2 = rb.getGeneralFamilyDaycareSchoolTypeId();
		int schoolType3 = schoolType2;
		int schoolType4 = schoolType2;
				
		String managementType1 = null;
		String managementType2 = null;
		String managementType3 = null;
		String managementType4 = null;
		
		switch (managementType) {
			case COMMUNE:
				managementType1 = "COMMUNE";
				managementType2 = managementType1;
				managementType3 = managementType1;
				managementType4 = managementType1;
				break;
			case PRIVATE:
				managementType1 = "COMPANY";
				managementType2 = "FOUNDATION";
				managementType3 = "OTHER";
				managementType4 = "COOPERATIVE_COMMUNE_LIABILITY";
				break;
		}
		
		PreparedQuery query = null;
		query = getQuery(QUERY_FAMILY_DAYCARE_PLACEMENTS);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCount();
			query.setChildCarePlacements();
			query.setFourSchoolTypesForProviders(); // parameter 1-4
			query.setFourManagementTypes(); // parameter 5-8
			query.setSchoolArea(); // parameter 9
			query.prepare();
			setQuery(QUERY_FAMILY_DAYCARE_PLACEMENTS, query);
		}
		query.setInt(1, schoolType1);
		query.setInt(2, schoolType2);
		query.setInt(3, schoolType3);
		query.setInt(4, schoolType4);
		
		query.setString(5, managementType1);
		query.setString(6, managementType2);
		query.setString(7, managementType3);
		query.setString(8, managementType4);
		
		query.setInt(9, areaId);
		
		return query.execute();
	}
	
	/**
	 * Returns the number of child placements for the specified school.
	 */
	protected int getProviderPlacementCount(int schoolId) throws RemoteException {
		ReportBusiness rb = getReportBusiness();
		int schoolType1 = rb.getPreSchoolTypeId();
		int schoolType2 = rb.getGeneralPreSchoolTypeId();
		int schoolType3 = schoolType2;
		int schoolType4 = schoolType2;

		PreparedQuery query = null;
		query = getQuery(QUERY_PROVIDER_PLACEMENTS);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCount();
			query.setChildCarePlacements();
			query.setSchool(); // parameter 1
			query.setFourSchoolTypesForProviders(); // parameter 2-5
			query.prepare();
			setQuery(QUERY_PROVIDER_PLACEMENTS, query);
		}
		query.setInt(1, schoolId);
		query.setInt(2, schoolType1);
		query.setInt(3, schoolType2);
		query.setInt(4, schoolType3);
		query.setInt(5, schoolType4);
		
		return query.execute();
	}
	
	/**
	 * Returns the mean week hours in family daycare for the specified management type.
	 */
	protected float getFamilyDaycareMeanHours(int areaId, int managementType) throws RemoteException {
		ReportBusiness rb = getReportBusiness();
		
		int schoolType1 = rb.getFamilyDayCareSchoolTypeId();
		int schoolType2 = rb.getGeneralFamilyDaycareSchoolTypeId();
		int schoolType3 = schoolType2;
		int schoolType4 = schoolType2;
				
		String managementType1 = null;
		String managementType2 = null;
		String managementType3 = null;
		String managementType4 = null;
		
		switch (managementType) {
			case COMMUNE:
				managementType1 = "COMMUNE";
				managementType2 = managementType1;
				managementType3 = managementType1;
				managementType4 = managementType1;
				break;
			case PRIVATE:
				managementType1 = "COMPANY";
				managementType2 = "FOUNDATION";
				managementType3 = "OTHER";
				managementType4 = "COOPERATIVE_COMMUNE_LIABILITY";
				break;
		}
		
		PreparedQuery query = null;
		PreparedQuery query2 = null;
		query = getQuery(QUERY_FAMILY_DAYCARE_MEAN_HOURS);
		query2 = getQuery(QUERY_FAMILY_DAYCARE_MEAN_HOURS2);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectMeanChildCareWeekHoursCareTime();
			query.setChildCarePlacementsCareTime();
			query.setFourSchoolTypesForProviders(); // parameter 1-4
			query.setFourManagementTypes(); // parameter 5-8
			query.setSchoolArea(); // parameter 9
			query.prepare();
			setQuery(QUERY_FAMILY_DAYCARE_MEAN_HOURS, query);
			
			query2 = new PreparedQuery(getConnection());
			query2.setSelectMeanChildCareWeekHoursCareTimeString();
			query2.setChildCarePlacementsCareTimeString();
			query2.setFourSchoolTypesForProviders(); // parameter 1-4
			query2.setFourManagementTypes(); // parameter 5-8
			query2.setSchoolArea(); // parameter 9
			query2.prepare();
			setQuery(QUERY_FAMILY_DAYCARE_MEAN_HOURS2, query2);
		}
		
		query.setInt(1, schoolType1);
		query.setInt(2, schoolType2);
		query.setInt(3, schoolType3);
		query.setInt(4, schoolType4);
		query.setString(5, managementType1);
		query.setString(6, managementType2);
		query.setString(7, managementType3);
		query.setString(8, managementType4);		
		query.setInt(9, areaId);

		query2.setInt(1, schoolType1);
		query2.setInt(2, schoolType2);
		query2.setInt(3, schoolType3);
		query2.setInt(4, schoolType4);
		query2.setString(5, managementType1);
		query2.setString(6, managementType2);
		query2.setString(7, managementType3);
		query2.setString(8, managementType4);		
		query2.setInt(9, areaId);

		return query.executeFloat();
	}
	
	/**
	 * Returns the number of child placement mean hours for the specified school.
	 */
	protected float getProviderMeanHours(int schoolId) throws RemoteException {
		ReportBusiness rb = getReportBusiness();
		int schoolType1 = rb.getPreSchoolTypeId();
		int schoolType2 = rb.getGeneralPreSchoolTypeId();
		int schoolType3 = schoolType2;
		int schoolType4 = schoolType2;

		PreparedQuery query = null;
		PreparedQuery query2 = null;
		query = getQuery(QUERY_PROVIDER_MEAN_HOURS);
		query2 = getQuery(QUERY_PROVIDER_MEAN_HOURS2);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectMeanChildCareWeekHoursCareTime();
			query.setChildCarePlacementsCareTime();
			query.setSchool(); // parameter 1
			query.setFourSchoolTypesForProviders(); // parameter 2-5
			query.prepare();
			setQuery(QUERY_PROVIDER_MEAN_HOURS, query);
			
			query2 = new PreparedQuery(getConnection());
			query2.setSelectMeanChildCareWeekHoursCareTimeString();
			query2.setChildCarePlacementsCareTimeString();
			query2.setSchool(); // parameter 1
			query2.setFourSchoolTypesForProviders(); // parameter 2-5
			query2.prepare();
			setQuery(QUERY_PROVIDER_MEAN_HOURS2, query2);
		}
		
		query.setInt(1, schoolId);
		query.setInt(2, schoolType1);
		query.setInt(3, schoolType2);
		query.setInt(4, schoolType3);
		query.setInt(5, schoolType4);

		query2.setInt(1, schoolId);
		query2.setInt(2, schoolType1);
		query2.setInt(3, schoolType2);
		query2.setInt(4, schoolType3);
		query2.setInt(5, schoolType4);

		return (query.executeFloat() + query2.executeFloat()) / 2;
	}	
} public class NackaCommuneHighSchoolPlacementReportModel extends ReportModel {

	private final static int COLUMN_SIZE = 18;
	
	private final static int ROW_METHOD_STUDY_PATH = 1;
	private final static int ROW_METHOD_TOTAL = 2;

	private final static int COLUMN_METHOD_SCHOOL_1 = 101;
	private final static int COLUMN_METHOD_SCHOOL_2 = 102;
	private final static int COLUMN_METHOD_SCHOOL_3 = 103;
	private final static int COLUMN_METHOD_TOTAL = 104;
	private final static int COLUMN_METHOD_OTHER_COMMUNE_CITIZENS = 105;
	private final static int COLUMN_METHOD_NACKA_CITIZENS = 106;

	private final static String QUERY_ALL = "all";
	private final static String QUERY_NACKA_GYMNASIUM = "nacka_gymnasium";
	private final static String QUERY_OTHER_COMMUNES = "other_communes";
	private final static String QUERY_NACKA_COMMUNE = "nacka_commune";
	private final static String QUERY_STUDY_PATH = "study_path";

	private final static String KEY_REPORT_TITLE = KP + "title_nacka_commune_high_school_placements";
	
	private Collection _studyPaths = null;
	private School[] _schools = null;
	private School[] _nackaGymnasium = null;

	/**
	 * Constructs this report model.
	 * @param reportBusiness the report business instance for calculating cell values
	 */
	public NackaCommuneHighSchoolPlacementReportModel(ReportBusiness reportBusiness) {
		super(reportBusiness);
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#initReportSize()
	 */
	protected void initReportSize() {
		try {
			Collection studyPaths = getStudyPaths();
			int rowSize = 0;
			rowSize += studyPaths.size() + 1; 
			setReportSize(rowSize, COLUMN_SIZE);
		} catch (RemoteException e) {
			log(e.getMessage());
		}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildRowHeaders()
	 */
	protected Header[] buildRowHeaders() {
		Header[] headers = null;
		
		try {
			Collection studyPaths = getStudyPaths();
			headers = new Header[studyPaths.size() + 1];
			Iterator iter = studyPaths.iterator();
			int headerIndex = 0;
			while (iter.hasNext()) {
				SchoolStudyPath studyPath = (SchoolStudyPath) iter.next();
				headers[headerIndex] = new Header(studyPath.getDescription(), Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER, 1);
				Header child = new Header(studyPath.getCode(), Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL);
				headers[headerIndex].setChild(0, child);
				headerIndex++;
			}
			
			Header header = new Header(KEY_TOTAL, Header.HEADERTYPE_ROW_TOTAL);
			headers[headerIndex] = header;
			headerIndex++;

		} catch (RemoteException e) {
			log(e.getMessage());
		}
		
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildColumnHeaders()
	 */
	protected Header[] buildColumnHeaders() {
		Header[] headers = new Header[6];
		int headerColumn = 0;
		try {
			ReportBusiness rb = getReportBusiness();
			Collection schools = rb.getNackaCommuneHighSchools();
			this._schools = new School[3];
			this._nackaGymnasium = new School[3];
			int schoolIndex = 0;
			int nackaGymnasiumIndex = 0;
			Iterator iter = schools.iterator();
			boolean nackaGymnasiumFound = false;
			while (iter.hasNext()) {
				School school = (School) iter.next();
				this._schools[schoolIndex] = school;
				String name = school.getName();
				if (name.length() > 15 && name.substring(0, 15).equals("Nacka Gymnasium")) {
					this._nackaGymnasium[nackaGymnasiumIndex++] = school;
					if (nackaGymnasiumFound) {
						continue;
					} else {
						name = "Nacka Gymnasium";
						nackaGymnasiumFound = true;
					}
				}
				schoolIndex++;
				Header h = new Header(name, Header.HEADERTYPE_COLUMN_NONLOCALIZED_HEADER, 4);
				Header child0 = new Header(KEY_SCHOOL_YEAR_1, Header.HEADERTYPE_COLUMN_NORMAL);
				Header child1 = new Header(KEY_SCHOOL_YEAR_2, Header.HEADERTYPE_COLUMN_NORMAL);
				Header child2 = new Header(KEY_SCHOOL_YEAR_3, Header.HEADERTYPE_COLUMN_NORMAL);
				Header child3 = new Header(KEY_SUM_1_3, Header.HEADERTYPE_COLUMN_NORMAL);
				h.setChild(0, child0);
				h.setChild(1, child1);
				h.setChild(2, child2);
				h.setChild(3, child3);
				headers[headerColumn++] = h;
			}
		} catch (RemoteException e) {
			log(e.getMessage());
		}
		
		Header h = new Header(KEY_TOTAL, Header.HEADERTYPE_COLUMN_HEADER, 4);
		Header child0 = new Header(KEY_SCHOOL_YEAR_1, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child1 = new Header(KEY_SCHOOL_YEAR_2, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child2 = new Header(KEY_SCHOOL_YEAR_3, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child3 = new Header(KEY_SUM_1_3, Header.HEADERTYPE_COLUMN_NORMAL);
		h.setChild(0, child0);
		h.setChild(1, child1);
		h.setChild(2, child2);
		h.setChild(3, child3);
		headers[headerColumn++] = h;
		
		h = new Header(KEY_OF_WHICH_FROM_OTHER_COMMUNES, Header.HEADERTYPE_COLUMN_HEADER);
		headers[headerColumn++] = h;
		
		h = new Header(KEY_NACKA_STUDENTS, Header.HEADERTYPE_COLUMN_HEADER);
		headers[headerColumn++] = h;
				
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildCells()
	 */
	protected void buildCells() {
		for (int column = 0; column < getColumnSize(); column++) {
			int row = 0;
			int columnMethod = 0;
			String columnParameter = null;
			int cellType = Cell.CELLTYPE_NORMAL;
			switch (column) {
				case 0:
					columnMethod = COLUMN_METHOD_SCHOOL_1;
					columnParameter = "G1";
					break;
				case 1:
					columnMethod = COLUMN_METHOD_SCHOOL_1;
					columnParameter = "G2";
					break;
				case 2:
					columnMethod = COLUMN_METHOD_SCHOOL_1;
					columnParameter = "G3";
					break;
				case 3:
					columnMethod = COLUMN_METHOD_SCHOOL_1;
					columnParameter = null;
					cellType = Cell.CELLTYPE_SUM;
					break;
				case 4:
					columnMethod = COLUMN_METHOD_SCHOOL_2;
					columnParameter = "G1";
					break;
				case 5:
					columnMethod = COLUMN_METHOD_SCHOOL_2;
					columnParameter = "G2";
					break;
				case 6:
					columnMethod = COLUMN_METHOD_SCHOOL_2;
					columnParameter = "G3";
					break;
				case 7:
					columnMethod = COLUMN_METHOD_SCHOOL_2;
					columnParameter = null;
					cellType = Cell.CELLTYPE_SUM;
					break;
				case 8:
					columnMethod = COLUMN_METHOD_SCHOOL_3;
					columnParameter = "G1";
					break;
				case 9:
					columnMethod = COLUMN_METHOD_SCHOOL_3;
					columnParameter = "G2";
					break;
				case 10:
					columnMethod = COLUMN_METHOD_SCHOOL_3;
					columnParameter = "G3";
					break;
				case 11:
					columnMethod = COLUMN_METHOD_SCHOOL_3;
					columnParameter = null;
					cellType = Cell.CELLTYPE_SUM;
					break;
				case 12:
					columnMethod = COLUMN_METHOD_TOTAL;
					columnParameter = "G1";
					break;
				case 13:
					columnMethod = COLUMN_METHOD_TOTAL;
					columnParameter = "G2";
					break;
				case 14:
					columnMethod = COLUMN_METHOD_TOTAL;
					columnParameter = "G3";
					break;
				case 15:
					columnMethod = COLUMN_METHOD_TOTAL;
					columnParameter = null;
					cellType = Cell.CELLTYPE_TOTAL;
					break;
				case 16:
					columnMethod = COLUMN_METHOD_OTHER_COMMUNE_CITIZENS;
					columnParameter = null;
					break;
				case 17:
					columnMethod = COLUMN_METHOD_NACKA_CITIZENS;
					columnParameter = null;
					break;
			}
			
			try {
				Collection studyPaths = getStudyPaths();
				Iterator iter = studyPaths.iterator();
				while (iter.hasNext()) {
					SchoolStudyPath studyPath = (SchoolStudyPath) iter.next();
					Object rowParameter = studyPath.getCode();
					Cell cell = new Cell(this, row, column, ROW_METHOD_STUDY_PATH,
							columnMethod, rowParameter, columnParameter, cellType);
					setCell(row, column, cell);
					row++;
				}
				Cell cell = new Cell(this, row, column, ROW_METHOD_TOTAL,
						columnMethod, null, columnParameter, Cell.CELLTYPE_TOTAL);
				setCell(row, column, cell);
				row++;
			} catch (RemoteException e) {
				log(e.getMessage());
			}
		}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#calculate()
	 */
	protected float calculate(Cell cell) throws RemoteException {
		float value = 0f;
		String studyPathPrefix = null;
		if (cell.getRowParameter() != null) {
			studyPathPrefix = (String) cell.getRowParameter();
		}
		String schoolYearName = (String) cell.getColumnParameter();
		int row = cell.getRow();
		int column = cell.getColumn();
		
		switch (cell.getRowMethod()) {
			case ROW_METHOD_STUDY_PATH:
				switch (cell.getColumnMethod()) {
					case COLUMN_METHOD_SCHOOL_1:
						if (schoolYearName == null) {
							value += getCell(row, 0).getFloatValue();
							value += getCell(row, 1).getFloatValue();
							value += getCell(row, 2).getFloatValue();
						} else {
							value = getHighSchoolNackaCommunePlacementCount(this._schools[0], schoolYearName, studyPathPrefix);
						}
						break;
					case COLUMN_METHOD_SCHOOL_2:
						if (schoolYearName == null) {
							value += getCell(row, 4).getFloatValue();
							value += getCell(row, 5).getFloatValue();
							value += getCell(row, 6).getFloatValue();
						} else {
							value = getNackaGymnasiumPlacementCount(schoolYearName, studyPathPrefix);
						}
						break;
					case COLUMN_METHOD_SCHOOL_3:
						if (schoolYearName == null) {
							value += getCell(row, 8).getFloatValue();
							value += getCell(row, 9).getFloatValue();
							value += getCell(row, 10).getFloatValue();
						} else {
							value = getHighSchoolNackaCommunePlacementCount(this._schools[2], schoolYearName, studyPathPrefix);
						}
						break;
					case COLUMN_METHOD_TOTAL:
						for (int i = column % 4; i < 12; i += 4) {
							value += getCell(row, i).getFloatValue();
						}
						break;
					case COLUMN_METHOD_OTHER_COMMUNE_CITIZENS:
						value = getHighSchoolOCCPlacementCount(studyPathPrefix);
						break;
					case COLUMN_METHOD_NACKA_CITIZENS:
						value = getHighSchoolNackaCitizenPlacementCount(studyPathPrefix);
						break;
				}
				break;
			case ROW_METHOD_TOTAL:
				for (int i = 0; i < row; i++) {
					Cell c = getCell(i, column);
					value += c.getFloatValue();
				}
				break;
		}
		
		return value;
	}

	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#getReportTitleLocalizationKey()
	 */
	public String getReportTitleLocalizationKey() {
		return KEY_REPORT_TITLE;
	}
	
	/*
	 * Returns the value from executing the specified study path query.
	 * Special case for study path IB handled.
	 */
	private int executeStudyPathQuery(int parameterIndex, String studyPathPrefix, PreparedQuery query) {
		query.setString(parameterIndex, studyPathPrefix + "%");
		int value = query.execute();
		if (studyPathPrefix.equals("IB")) {
			query.setString(parameterIndex, "PRE%");
			value += query.execute();
		}
		return value;		
	}
	
	/**
	 * Returns the number of student placements for high schools
	 * in Nacka commune for the specified school year.
	 */
	protected int getHighSchoolNackaCommunePlacementCount(School school, String schoolYearName, String studyPathPrefix) throws RemoteException {
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_ALL);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setSchoolTypeHighSchool();
			query.setSchool(); // parameter 1
			query.setSchoolYearName(); // parameter 2
			query.setStudyPathPrefix(); // parameter 3
			query.prepare();
			setQuery(QUERY_ALL, query);
		}
		query.setInt(1, ((Integer) school.getPrimaryKey()).intValue());
		query.setString(2, schoolYearName);
		return executeStudyPathQuery(3, studyPathPrefix, query);
	}
	
	/**
	 * Returns the number of student placements for Nacka Gymnasium
	 * in Nacka commune for the specified school year.
	 */
	protected int getNackaGymnasiumPlacementCount(String schoolYearName, String studyPathPrefix) throws RemoteException {
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_NACKA_GYMNASIUM);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setSchoolTypeHighSchool();
			query.setSchools(this._nackaGymnasium);
			query.setSchoolYearName(); // parameter 1
			query.setStudyPathPrefix(); // parameter 2
			query.prepare();
			setQuery(QUERY_NACKA_GYMNASIUM, query);
		}
		query.setString(1, schoolYearName);
		return executeStudyPathQuery(2, studyPathPrefix, query);
	}
	
	/**
	 * Returns the number of student placements for Nacka commune high schools
	 * for the specified study path prefix.
	 * Only citizens outside Nacka commune are counted. 
	 */
	protected int getHighSchoolOCCPlacementCount(String studyPathPrefix) throws RemoteException{
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_OTHER_COMMUNES);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setNotNackaCitizens();
			query.setSchoolTypeHighSchool();
			query.setSchools(rb.getNackaCommuneHighSchools());
			query.setStudyPathPrefix(); // parameter 1
			query.prepare();
			setQuery(QUERY_OTHER_COMMUNES, query);
		}
		return executeStudyPathQuery(1, studyPathPrefix, query);
	}	
	
	/**
	 * Returns the number of student placements for Nacka commune high schools
	 * in Nacka commune for the specified school year.
	 * Only citizens in Nacka commune are counted. 
	 */
	protected int getHighSchoolNackaCitizenPlacementCount(String studyPathPrefix) throws RemoteException{
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_NACKA_COMMUNE);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setOnlyNackaCitizens();
			query.setSchoolTypeHighSchool();
			query.setSchools(rb.getNackaCommuneHighSchools());
			query.setStudyPathPrefix(); // parameter 1
			query.prepare();
			setQuery(QUERY_NACKA_COMMUNE, query);
		}
		return executeStudyPathQuery(1, studyPathPrefix, query);
	}	
	
	/**
	 * Returns the number of student placements for the specified study path code.
	 */
	protected int getHighSchoolPlacementCount(String studyPathCode) throws RemoteException {
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		Collection schools = rb.getNackaCommuneHighSchools();
		query = getQuery(QUERY_STUDY_PATH);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setSchools(schools);
			query.setSchoolTypeHighSchool();
			query.setStudyPathPrefix(); // parameter 1
			query.prepare();
			setQuery(QUERY_STUDY_PATH, query);
		}
		return executeStudyPathQuery(1, studyPathCode, query);
	}
	
	/*
	 * Returns a filtered list with only Nacka study paths. 
	 */
	private Collection getStudyPaths() throws RemoteException {
		if (this._studyPaths == null) {
			this._studyPaths = new ArrayList();
			ReportBusiness rb = getReportBusiness();
			Collection c = rb.getAllStudyPaths();
			Iterator iter = c.iterator();
			while (iter.hasNext()) {
				SchoolStudyPath sp = (SchoolStudyPath) iter.next();
				String code = sp.getCode();
				int count = getHighSchoolPlacementCount(code);
				if (count > 0) {
					this._studyPaths.add(sp);
				}
			}			
		}
		return this._studyPaths;
	}
} public class NackaCommuneHighSchoolStudyPathReportModel extends ReportModel {

	private final static int COLUMN_SIZE = 18;
	
	private final static int ROW_METHOD_STUDY_PATH = 1;
	private final static int ROW_METHOD_TOTAL = 2;

	private final static int COLUMN_METHOD_SCHOOL_1 = 101;
	private final static int COLUMN_METHOD_SCHOOL_2 = 102;
	private final static int COLUMN_METHOD_SCHOOL_3 = 103;
	private final static int COLUMN_METHOD_TOTAL = 104;
	private final static int COLUMN_METHOD_OTHER_COMMUNE_CITIZENS = 105;
	private final static int COLUMN_METHOD_NACKA_CITIZENS = 106;

	private final static String QUERY_ALL = "all";
	private final static String QUERY_NACKA_GYMNASIUM = "nacka_gymnasium";
	private final static String QUERY_OTHER_COMMUNES = "other_communes";
	private final static String QUERY_NACKA_COMMUNE = "nacka_commune";
	private final static String QUERY_STUDY_PATH = "study_path";
	private final static String QUERY_STUDY_PATH_AMOUNT = "study_path_amount";

	private final static String KEY_REPORT_TITLE = KP + "title_nacka_commune_high_school_all_study_paths";
	
	private Collection _studyPaths = null;
	private School[] _schools = null;
	private School[] _nackaGymnasium = null;
	private int[] _subtractRow = null;

	/**
	 * Constructs this report model.
	 * @param reportBusiness the report business instance for calculating cell values
	 */
	public NackaCommuneHighSchoolStudyPathReportModel(ReportBusiness reportBusiness) {
		super(reportBusiness);
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#initReportSize()
	 */
	protected void initReportSize() {
		try {
			Collection studyPaths = getStudyPaths();
			int rowSize = 0;
			rowSize += studyPaths.size() + 1; 
			setReportSize(rowSize, COLUMN_SIZE);
		} catch (RemoteException e) {
			log(e.getMessage());
		}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildRowHeaders()
	 */
	protected Header[] buildRowHeaders() {
		Header[] headers = null;
		
		try {
			Collection studyPaths = getStudyPaths();
			headers = new Header[studyPaths.size() + 1];
			Iterator iter = studyPaths.iterator();
			int headerIndex = 0;
			while (iter.hasNext()) {
				SchoolStudyPath studyPath = (SchoolStudyPath) iter.next();
				headers[headerIndex] = new Header(studyPath.getDescription(), Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER, 1);
				Header child = new Header(studyPath.getCode(), Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL);
				headers[headerIndex].setChild(0, child);
				headerIndex++;
			}
			
			Header header = new Header(KEY_TOTAL, Header.HEADERTYPE_ROW_TOTAL);
			headers[headerIndex] = header;
			headerIndex++;

		} catch (RemoteException e) {
			log(e.getMessage());
		}
		
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildColumnHeaders()
	 */
	protected Header[] buildColumnHeaders() {
		Header[] headers = new Header[6];
		int headerColumn = 0;
		try {
			ReportBusiness rb = getReportBusiness();
			Collection schools = rb.getNackaCommuneHighSchools();
			this._schools = new School[3];
			this._nackaGymnasium = new School[3];
			int schoolIndex = 0;
			int nackaGymnasiumIndex = 0;
			Iterator iter = schools.iterator();
			boolean nackaGymnasiumFound = false;
			while (iter.hasNext()) {
				School school = (School) iter.next();
				this._schools[schoolIndex] = school;
				String name = school.getName();
				if (name.length() > 15 && name.substring(0, 15).equals("Nacka Gymnasium")) {
					this._nackaGymnasium[nackaGymnasiumIndex++] = school;
					if (nackaGymnasiumFound) {
						continue;
					} else {
						name = "Nacka Gymnasium";
						nackaGymnasiumFound = true;
					}
				}
				schoolIndex++;
				Header h = new Header(name, Header.HEADERTYPE_COLUMN_NONLOCALIZED_HEADER, 4);
				Header child0 = new Header(KEY_SCHOOL_YEAR_1, Header.HEADERTYPE_COLUMN_NORMAL);
				Header child1 = new Header(KEY_SCHOOL_YEAR_2, Header.HEADERTYPE_COLUMN_NORMAL);
				Header child2 = new Header(KEY_SCHOOL_YEAR_3, Header.HEADERTYPE_COLUMN_NORMAL);
				Header child3 = new Header(KEY_SUM_1_3, Header.HEADERTYPE_COLUMN_NORMAL);
				h.setChild(0, child0);
				h.setChild(1, child1);
				h.setChild(2, child2);
				h.setChild(3, child3);
				headers[headerColumn++] = h;
			}
		} catch (RemoteException e) {
			log(e.getMessage());
		}
		
		Header h = new Header(KEY_TOTAL, Header.HEADERTYPE_COLUMN_HEADER, 4);
		Header child0 = new Header(KEY_SCHOOL_YEAR_1, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child1 = new Header(KEY_SCHOOL_YEAR_2, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child2 = new Header(KEY_SCHOOL_YEAR_3, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child3 = new Header(KEY_SUM_1_3, Header.HEADERTYPE_COLUMN_NORMAL);
		h.setChild(0, child0);
		h.setChild(1, child1);
		h.setChild(2, child2);
		h.setChild(3, child3);
		headers[headerColumn++] = h;
		
		h = new Header(KEY_OF_WHICH_FROM_OTHER_COMMUNES, Header.HEADERTYPE_COLUMN_HEADER);
		headers[headerColumn++] = h;
		
		h = new Header(KEY_NACKA_STUDENTS, Header.HEADERTYPE_COLUMN_HEADER);
		headers[headerColumn++] = h;
				
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildCells()
	 */
	protected void buildCells() {
		for (int column = 0; column < getColumnSize(); column++) {
			int row = 0;
			int columnMethod = 0;
			String columnParameter = null;
			int cellType = Cell.CELLTYPE_NORMAL;
			switch (column) {
				case 0:
					columnMethod = COLUMN_METHOD_SCHOOL_1;
					columnParameter = "G1";
					break;
				case 1:
					columnMethod = COLUMN_METHOD_SCHOOL_1;
					columnParameter = "G2";
					break;
				case 2:
					columnMethod = COLUMN_METHOD_SCHOOL_1;
					columnParameter = "G3";
					break;
				case 3:
					columnMethod = COLUMN_METHOD_SCHOOL_1;
					columnParameter = null;
					cellType = Cell.CELLTYPE_SUM;
					break;
				case 4:
					columnMethod = COLUMN_METHOD_SCHOOL_2;
					columnParameter = "G1";
					break;
				case 5:
					columnMethod = COLUMN_METHOD_SCHOOL_2;
					columnParameter = "G2";
					break;
				case 6:
					columnMethod = COLUMN_METHOD_SCHOOL_2;
					columnParameter = "G3";
					break;
				case 7:
					columnMethod = COLUMN_METHOD_SCHOOL_2;
					columnParameter = null;
					cellType = Cell.CELLTYPE_SUM;
					break;
				case 8:
					columnMethod = COLUMN_METHOD_SCHOOL_3;
					columnParameter = "G1";
					break;
				case 9:
					columnMethod = COLUMN_METHOD_SCHOOL_3;
					columnParameter = "G2";
					break;
				case 10:
					columnMethod = COLUMN_METHOD_SCHOOL_3;
					columnParameter = "G3";
					break;
				case 11:
					columnMethod = COLUMN_METHOD_SCHOOL_3;
					columnParameter = null;
					cellType = Cell.CELLTYPE_SUM;
					break;
				case 12:
					columnMethod = COLUMN_METHOD_TOTAL;
					columnParameter = "G1";
					break;
				case 13:
					columnMethod = COLUMN_METHOD_TOTAL;
					columnParameter = "G2";
					break;
				case 14:
					columnMethod = COLUMN_METHOD_TOTAL;
					columnParameter = "G3";
					break;
				case 15:
					columnMethod = COLUMN_METHOD_TOTAL;
					columnParameter = null;
					cellType = Cell.CELLTYPE_TOTAL;
					break;
				case 16:
					columnMethod = COLUMN_METHOD_OTHER_COMMUNE_CITIZENS;
					columnParameter = null;
					break;
				case 17:
					columnMethod = COLUMN_METHOD_NACKA_CITIZENS;
					columnParameter = null;
					break;
			}
			
			try {
				Collection studyPaths = getStudyPaths();
				Iterator iter = studyPaths.iterator();
				while (iter.hasNext()) {
					SchoolStudyPath studyPath = (SchoolStudyPath) iter.next();
					Object rowParameter = studyPath.getCode();
					Cell cell = new Cell(this, row, column, ROW_METHOD_STUDY_PATH,
							columnMethod, rowParameter, columnParameter, cellType);
					setCell(row, column, cell);
					row++;
				}
				Cell cell = new Cell(this, row, column, ROW_METHOD_TOTAL,
						columnMethod, null, columnParameter, Cell.CELLTYPE_TOTAL);
				setCell(row, column, cell);
				row++;
			} catch (RemoteException e) {
				log(e.getMessage());
			}
		}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#calculate()
	 */
	protected float calculate(Cell cell) throws RemoteException {
		float value = 0f;
		String studyPathPrefix = null;
		if (cell.getRowParameter() != null) {
			studyPathPrefix = (String) cell.getRowParameter();
		}
		String schoolYearName = (String) cell.getColumnParameter();
		int row = cell.getRow();
		int column = cell.getColumn();
		
		switch (cell.getRowMethod()) {
			case ROW_METHOD_STUDY_PATH:
				switch (cell.getColumnMethod()) {
					case COLUMN_METHOD_SCHOOL_1:
						if (schoolYearName == null) {
							value += getCell(row, 0).getFloatValue();
							value += getCell(row, 1).getFloatValue();
							value += getCell(row, 2).getFloatValue();
						} else {
							value = getHighSchoolNackaCommunePlacementCount(this._schools[0], schoolYearName, studyPathPrefix);
							value -= subtractRows(row, column);
						}
						break;
					case COLUMN_METHOD_SCHOOL_2:
						if (schoolYearName == null) {
							value += getCell(row, 4).getFloatValue();
							value += getCell(row, 5).getFloatValue();
							value += getCell(row, 6).getFloatValue();
						} else {
							value = getNackaGymnasiumPlacementCount(schoolYearName, studyPathPrefix);
							value -= subtractRows(row, column);
						}
						break;
					case COLUMN_METHOD_SCHOOL_3:
						if (schoolYearName == null) {
							value += getCell(row, 8).getFloatValue();
							value += getCell(row, 9).getFloatValue();
							value += getCell(row, 10).getFloatValue();
						} else {
							value = getHighSchoolNackaCommunePlacementCount(this._schools[2], schoolYearName, studyPathPrefix);
							value -= subtractRows(row, column);
						}
						break;
					case COLUMN_METHOD_TOTAL:
						for (int i = column % 4; i < 12; i += 4) {
							value += getCell(row, i).getFloatValue();
						}
						break;
					case COLUMN_METHOD_OTHER_COMMUNE_CITIZENS:
						value = getHighSchoolOCCPlacementCount(studyPathPrefix);
						value -= subtractRows(row, column);
						break;
					case COLUMN_METHOD_NACKA_CITIZENS:
						value = getHighSchoolNackaCitizenPlacementCount(studyPathPrefix);
						value -= subtractRows(row, column);
						break;
				}
				break;
			case ROW_METHOD_TOTAL:
				for (int i = 0; i < row; i++) {
					Cell c = getCell(i, column);
					value += c.getFloatValue();
				}
				break;
		}
		
		return value;
	}

	/*
	 * Subtract sub study path rows. 
	 */
	private int subtractRows(int row, int column) {
		int subtract = 0;
		if (this._subtractRow[row] != -1) {
			return 0;
		}
		for (int i = 0; i < this._subtractRow.length; i++) {
			int subtractRow = this._subtractRow[i];
			if (row == subtractRow) {
				Cell cell = getCell(i, column);
				subtract += cell.getValue();
			}
			
		}
		return subtract;
	}

	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#getReportTitleLocalizationKey()
	 */
	public String getReportTitleLocalizationKey() {
		return KEY_REPORT_TITLE;
	}
	
	/*
	 * Returns the value from executing the specified study path query.
	 */
	private int executeStudyPathQuery(int parameterIndex, String studyPathPrefix, PreparedQuery query) {
		if (studyPathPrefix.length() == 2) {
			studyPathPrefix += "%";
		}
		query.setString(parameterIndex, studyPathPrefix);
		return query.execute();
	}
	
	/**
	 * Returns the number of student placements for high schools
	 * in Nacka commune for the specified school year.
	 */
	protected int getHighSchoolNackaCommunePlacementCount(School school, String schoolYearName, String studyPathPrefix) throws RemoteException {
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_ALL);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setSchoolTypeHighSchool();
			query.setSchool(); // parameter 1
			query.setSchoolYearName(); // parameter 2
			query.setStudyPathPrefix(); // parameter 3
			query.prepare();
			setQuery(QUERY_ALL, query);
		}
		query.setInt(1, ((Integer) school.getPrimaryKey()).intValue());
		query.setString(2, schoolYearName);
		return executeStudyPathQuery(3, studyPathPrefix, query);
	}
	
	/**
	 * Returns the number of student placements for Nacka Gymnasium
	 * in Nacka commune for the specified school year.
	 */
	protected int getNackaGymnasiumPlacementCount(String schoolYearName, String studyPathPrefix) throws RemoteException {
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_NACKA_GYMNASIUM);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setSchoolTypeHighSchool();
			query.setSchools(this._nackaGymnasium);
			query.setSchoolYearName(); // parameter 1
			query.setStudyPathPrefix(); // parameter 2
			query.prepare();
			setQuery(QUERY_NACKA_GYMNASIUM, query);
		}
		query.setString(1, schoolYearName);
		return executeStudyPathQuery(2, studyPathPrefix, query);
	}
	
	/**
	 * Returns the number of student placements for Nacka commune high schools
	 * for the specified study path prefix.
	 * Only citizens outside Nacka commune are counted. 
	 */
	protected int getHighSchoolOCCPlacementCount(String studyPathPrefix) throws RemoteException{
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_OTHER_COMMUNES);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setNotNackaCitizens();
			query.setSchoolTypeHighSchool();
			query.setSchools(rb.getNackaCommuneHighSchools());
			query.setStudyPathPrefix(); // parameter 1
			query.setNotSchoolYearName("G4");
			query.prepare();
			setQuery(QUERY_OTHER_COMMUNES, query);
		}
		return executeStudyPathQuery(1, studyPathPrefix, query);
	}	
	
	/**
	 * Returns the number of student placements for Nacka commune high schools
	 * in Nacka commune for the specified school year.
	 * Only citizens in Nacka commune are counted. 
	 */
	protected int getHighSchoolNackaCitizenPlacementCount(String studyPathPrefix) throws RemoteException{
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_NACKA_COMMUNE);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setOnlyNackaCitizens();
			query.setSchoolTypeHighSchool();
			query.setSchools(rb.getNackaCommuneHighSchools());
			query.setStudyPathPrefix(); // parameter 1
			query.setNotSchoolYearName("G4");
			query.prepare();
			setQuery(QUERY_NACKA_COMMUNE, query);
		}
		return executeStudyPathQuery(1, studyPathPrefix, query);
	}	
	
	/**
	 * Returns the number of student placements for the specified study path code.
	 */
	protected int getHighSchoolPlacementCount(String studyPathCode) throws RemoteException {
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		Collection schools = rb.getNackaCommuneHighSchools();
		query = getQuery(QUERY_STUDY_PATH);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setSchools(schools);
			query.setSchoolTypeHighSchool();
			query.setStudyPathPrefix(); // parameter 1
			query.setNotSchoolYearName("G4");
			query.prepare();
			setQuery(QUERY_STUDY_PATH, query);
		}
		return executeStudyPathQuery(1, studyPathCode, query);
	}
	
	/*
	 * Returns a filtered list with only Nacka study paths. 
	 */
	private Collection getStudyPaths() throws RemoteException {
		if (this._studyPaths == null) {
			this._studyPaths = new ArrayList();
			ReportBusiness rb = getReportBusiness();
			Collection c = rb.getAllStudyPathsIncludingDirections();
			TreeMap map = new TreeMap();
			this._subtractRow = new int[c.size()];
			for (int i = 0; i < this._subtractRow.length; i++) {
				this._subtractRow[i] = -1;
			}
			Iterator iter = c.iterator();
			while (iter.hasNext()) {
				SchoolStudyPath sp = (SchoolStudyPath) iter.next();
				String code = sp.getCode();
				if (!code.equals("HV") && !code.equals("SM") && !code.equals("TE")) {
					map.put(sp.getCode(), sp);					
				}
			}
			iter = map.values().iterator();
			int studyPathAmount = 0;
			int row = 0;
			int studyPathRow = -1;
			String studyPathCode = "";
			while (iter.hasNext()) {
				SchoolStudyPath sp = (SchoolStudyPath) iter.next();
				String code = sp.getCode();
				int studyPathId = ((Integer) sp.getPrimaryKey()).intValue();
				int count = getHighSchoolPlacementCount(code);
				if (count > 0) {
					if (code.length() == 2) {
						studyPathAmount = getStudyPathAmount(studyPathId);
						this._studyPaths.add(sp);
						studyPathRow = row;
						studyPathCode = code;
						row++;
					} else {
						int subStudyPathAmount = getStudyPathAmount(studyPathId);
						String description = sp.getDescription();
						String subCode = code.substring(0, 2);
						if (!subCode.equals(studyPathCode) ||
								(((studyPathAmount != subStudyPathAmount) && (subStudyPathAmount != -1)) 
								|| description.indexOf("lokal inriktning") != -1)) {
							this._studyPaths.add(sp);
							if (subCode.equals(studyPathCode)) {
								this._subtractRow[row] = studyPathRow;
							} else {
								studyPathRow = -1;
								studyPathCode = "";
							}
							row++;
						}
					}
				}
			}			
		}
		return this._studyPaths;
	}
	
	/**
	 * Returns the amount for the specified study path code.
	 */
	protected int getStudyPathAmount(int studyPathId) {
		PreparedQuery query = null;
		query = getQuery(QUERY_STUDY_PATH_AMOUNT);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectMaxStudyPathAmount();
			query.setStudyPathAmount(); // parameter 1
			query.prepare();
			setQuery(QUERY_STUDY_PATH_AMOUNT, query);
		}
		query.setInt(1, studyPathId);
		return query.execute();
	}
} public class NackaElementarySchoolPlacementReportModel extends ReportModel {

	private final static int COLUMN_SIZE = 16;
	
	private final static int ROW_METHOD_SCHOOL = 1;
	private final static int ROW_METHOD_SUM = 2;
	private final static int ROW_METHOD_TOTAL = 3;

	private final static int COLUMN_METHOD_SCHOOL_YEAR = 101;
	private final static int COLUMN_METHOD_SUM_1_3 = 102;
	private final static int COLUMN_METHOD_SUM_4_6 = 103;
	private final static int COLUMN_METHOD_SUM_7_9 = 104;
	private final static int COLUMN_METHOD_TOTAL_1_9 = 105;
	private final static int COLUMN_METHOD_TOTAL_F_9 = 106;

	private final static String QUERY_ELEMENTARY = "elementary";
	private final static String QUERY_ELEMENTARY_6_YEAR_STUDENTS = "elementary_6";	
	private final static String QUERY_COUNT = "count";
	
	private final static String KEY_REPORT_TITLE = KP + "title_nacka_elementary_school_placements";

	private Map _schools = null;
	
	/**
	 * Constructs this report model.
	 * @param reportBusiness the report business instance for calculating cell values
	 */
	public NackaElementarySchoolPlacementReportModel(ReportBusiness reportBusiness) {
		super(reportBusiness);
		this._schools = new HashMap();
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#initReportSize()
	 */
	protected void initReportSize() {
		try {
			Collection areas = getReportBusiness().getElementarySchoolAreas();
			int rowSize = 0;
			Iterator iter = areas.iterator();
			while (iter.hasNext()) {
				SchoolArea area = (SchoolArea) iter.next();
				Collection schools = getReportBusiness().getElementarySchools(area);
				schools = removeEmptySchools(schools, area);
				rowSize += schools.size() + 1; // Sum rows
			}
			rowSize += 1; // Total row
			setReportSize(rowSize, COLUMN_SIZE);
		} catch (RemoteException e) {
			log(e.getMessage());
		}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildRowHeaders()
	 */
	protected Header[] buildRowHeaders() {
		Header[] headers = null;
		
		try {
			ReportBusiness rb = getReportBusiness();
			Collection areas = rb.getElementarySchoolAreas();
			headers = new Header[areas.size() + 1];
			Iterator areaIter = areas.iterator();
			int headerIndex = 0;
			while (areaIter.hasNext()) {
				SchoolArea area = (SchoolArea) areaIter.next();
				Collection schools = getReportBusiness().getElementarySchools(area);
				schools = removeEmptySchools(schools, area);
				headers[headerIndex] = new Header(area.getName(), Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER, schools.size() + 1);
				Iterator schoolIter = schools.iterator();
				int childIndex = 0;
				while (schoolIter.hasNext()) {
					School school = (School) schoolIter.next();
					Header child = new Header(school.getName(), Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL);
					headers[headerIndex].setChild(childIndex, child);
					childIndex++;
				}
				Header header = new Header(KEY_SUM, Header.HEADERTYPE_ROW_SUM);
				headers[headerIndex].setChild(childIndex, header);
				headerIndex++;
			}
			Header header = new Header(KEY_TOTAL, Header.HEADERTYPE_ROW_TOTAL);
			headers[headerIndex] = header;
		} catch (RemoteException e) {
			log(e.getMessage());
		}
		
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildColumnHeaders()
	 */
	protected Header[] buildColumnHeaders() {
		Header[] headers = new Header[10];
		
		Header h = new Header(KEY_SCHOOL_YEAR_F, Header.HEADERTYPE_COLUMN_NORMAL);
		headers[0] = h;
		
		h = new Header(KEY_SCHOOL_YEAR, Header.HEADERTYPE_COLUMN_NORMAL, 3);
		Header child0 = new Header(KEY_SCHOOL_YEAR_1, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child1 = new Header(KEY_SCHOOL_YEAR_2, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child2 = new Header(KEY_SCHOOL_YEAR_3, Header.HEADERTYPE_COLUMN_NORMAL);
		h.setChild(0, child0);
		h.setChild(1, child1);
		h.setChild(2, child2);
		headers[1] = h;
		
		h = new Header(KEY_SUM, Header.HEADERTYPE_COLUMN_HEADER, 1);
		child0 = new Header(KEY_SUM_1_3, Header.HEADERTYPE_COLUMN_NORMAL);
		h.setChild(0, child0);
		headers[2] = h;
		
		h = new Header(KEY_SCHOOL_YEAR, Header.HEADERTYPE_COLUMN_HEADER, 3);
		child0 = new Header(KEY_SCHOOL_YEAR_4, Header.HEADERTYPE_COLUMN_NORMAL);
		child1 = new Header(KEY_SCHOOL_YEAR_5, Header.HEADERTYPE_COLUMN_NORMAL);
		child2 = new Header(KEY_SCHOOL_YEAR_6, Header.HEADERTYPE_COLUMN_NORMAL);
		h.setChild(0, child0);
		h.setChild(1, child1);
		h.setChild(2, child2);
		headers[3] = h;
		
		h = new Header(KEY_SUM, Header.HEADERTYPE_COLUMN_HEADER, 1);
		child0 = new Header(KEY_SUM_4_6, Header.HEADERTYPE_COLUMN_NORMAL);
		h.setChild(0, child0);
		headers[4] = h;

		h = new Header(KEY_SCHOOL_YEAR, Header.HEADERTYPE_COLUMN_HEADER, 3);
		child0 = new Header(KEY_SCHOOL_YEAR_7, Header.HEADERTYPE_COLUMN_NORMAL);
		child1 = new Header(KEY_SCHOOL_YEAR_8, Header.HEADERTYPE_COLUMN_NORMAL);
		child2 = new Header(KEY_SCHOOL_YEAR_9, Header.HEADERTYPE_COLUMN_NORMAL);
		h.setChild(0, child0);
		h.setChild(1, child1);
		h.setChild(2, child2);
		headers[5] = h;

		h = new Header(KEY_SUM, Header.HEADERTYPE_COLUMN_HEADER, 1);
		child0 = new Header(KEY_SUM_7_9, Header.HEADERTYPE_COLUMN_NORMAL);
		h.setChild(0, child0);
		headers[6] = h;
		
		h = new Header(KEY_TOTAL, Header.HEADERTYPE_COLUMN_HEADER, 1);
		child0 = new Header(KEY_TOTAL_1_9, Header.HEADERTYPE_COLUMN_NORMAL);
		h.setChild(0, child0);
		headers[7] = h;
		
		h = new Header(KEY_TOTAL, Header.HEADERTYPE_COLUMN_HEADER, 1);
		child0 = new Header(KEY_TOTAL_F_9, Header.HEADERTYPE_COLUMN_NORMAL);
		h.setChild(0, child0);
		headers[8] = h;

		h = new Header(KEY_SIX_YEARS_STUDENTS, Header.HEADERTYPE_COLUMN_NORMAL);
		headers[9] = h;
				
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildCells()
	 */
	protected void buildCells() {
		for (int column = 0; column < getColumnSize(); column++) {
			int row = 0;
			int columnMethod = 0;
			Object columnParameter = null;
			switch (column) {
				case 0:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "F";
					break;
				case 1:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "1";
					break;
				case 2:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "2";
					break;
				case 3:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "3";
					break;
				case 4:
					columnMethod = COLUMN_METHOD_SUM_1_3;
					columnParameter = null;
					break;
				case 5:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "4";
					break;
				case 6:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "5";
					break;
				case 7:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "6";
					break;
				case 8:
					columnMethod = COLUMN_METHOD_SUM_4_6;
					columnParameter = null;
					break;
				case 9:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "7";
					break;
				case 10:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "8";
					break;
				case 11:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "9";
					break;
				case 12:
					columnMethod = COLUMN_METHOD_SUM_7_9;
					columnParameter = null;
					break;
				case 13:
					columnMethod = COLUMN_METHOD_TOTAL_1_9;
					columnParameter = null;
					break;
				case 14:
					columnMethod = COLUMN_METHOD_TOTAL_F_9;
					columnParameter = null;
					break;
				case 15:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "0";
					break;
			}

			try {
				ReportBusiness rb = getReportBusiness();
				Collection areas = rb.getElementarySchoolAreas();
				Iterator areaIter = areas.iterator();
				while (areaIter.hasNext()) {
					SchoolArea area = (SchoolArea) areaIter.next();
					Collection schools = getReportBusiness().getElementarySchools(area);
					schools = removeEmptySchools(schools, area);
					Iterator schoolIter = schools.iterator();
					while (schoolIter.hasNext()) {
						School school = (School) schoolIter.next();
						Object rowParameter = school.getPrimaryKey();
						Cell cell = new Cell(this, row, column, ROW_METHOD_SCHOOL,
								columnMethod, rowParameter, columnParameter, Cell.CELLTYPE_NORMAL);
						setCell(row, column, cell);
						row++;
					}
					Cell cell = new Cell(this, row, column, ROW_METHOD_SUM,
							columnMethod, null, columnParameter, Cell.CELLTYPE_SUM);
					setCell(row, column, cell);
					row++;
				}
				Cell cell = new Cell(this, row, column, ROW_METHOD_TOTAL,
						columnMethod, null, columnParameter, Cell.CELLTYPE_TOTAL);
				setCell(row, column, cell);
			} catch (RemoteException e) {
				log(e.getMessage());
			}
		}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#calculate()
	 */
	protected float calculate(Cell cell) throws RemoteException {
		float value = 0f;
		int schoolId = -1;
		if (cell.getRowParameter() != null) {
			schoolId = ((Integer) cell.getRowParameter()).intValue();
		}
		String schoolYearName = (String) cell.getColumnParameter();
		
		if (cell.getColumnMethod() == COLUMN_METHOD_SCHOOL_YEAR) {
			switch (cell.getRowMethod()) {
				case ROW_METHOD_SCHOOL:
					value = getElementarySchoolPlacementCount(schoolId, schoolYearName);
					break;
				case ROW_METHOD_SUM:
					int rowIndex = cell.getRow() - 1;
					if (rowIndex < 0) {
						break;
					}
					Cell c = getCell(rowIndex, cell.getColumn()); 
					while (rowIndex >= 0 && c.getCellType() == Cell.CELLTYPE_NORMAL) {						
						value += c.getFloatValue();
						rowIndex--;
						if (rowIndex >= 0) {
							c = getCell(rowIndex, cell.getColumn());
						}
					}
					break;
				case ROW_METHOD_TOTAL:
					rowIndex = cell.getRow() - 1;
					while (rowIndex >= 0) {
						c = getCell(rowIndex, cell.getColumn());
						if (c.getCellType() == Cell.CELLTYPE_NORMAL) {
							value += c.getFloatValue();
						}
						rowIndex--;
					}
					break;
			}
		} else {
			switch (cell.getColumnMethod()) {
				case COLUMN_METHOD_SUM_1_3:
					for (int i = 1; i < 4; i++) {
						value += getCell(cell.getRow(), i).getFloatValue();
					}
					break;
				case COLUMN_METHOD_SUM_4_6:
					for (int i = 5; i < 8; i++) {
						value += getCell(cell.getRow(), i).getFloatValue();
					}
					break;
				case COLUMN_METHOD_SUM_7_9:
					for (int i = 9; i < 12; i++) {
						value += getCell(cell.getRow(), i).getFloatValue();
					}
					break;
				case COLUMN_METHOD_TOTAL_1_9:
					value = getCell(cell.getRow(), 4).getFloatValue() +
							getCell(cell.getRow(), 8).getFloatValue() +
							getCell(cell.getRow(), 12).getFloatValue();
					break;
				case COLUMN_METHOD_TOTAL_F_9:
					value = getCell(cell.getRow(), 13).getFloatValue() +
							getCell(cell.getRow(), 0).getFloatValue();
					break;
			}
		}
		
		return value;
	}

	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#getReportTitleLocalizationKey()
	 */
	public String getReportTitleLocalizationKey() {
		return KEY_REPORT_TITLE;
	}
	
	/**
	 * Returns the number of student placements for the specified school and school year.
	 */
	protected int getElementarySchoolPlacementCount(int schoolId, String schoolYearName) throws RemoteException {
		PreparedQuery query = null;
		if (!schoolYearName.equals("0")) {
			ReportBusiness rb = getReportBusiness();
			query = getQuery(QUERY_ELEMENTARY);
			if (query == null) {
				query = new PreparedQuery(getConnection());
				query.setSelectCountDistinctUsers();
				query.setPlacements(rb.getSchoolSeasonId());
				query.setSchoolType(); // parameter 1
				query.setSchoolYearName(); // parameter 2
				query.setSchool(); // parameter 3
				query.prepare();
				setQuery(QUERY_ELEMENTARY, query);
			}
			if (schoolYearName.equals("F")) {
				query.setInt(1, rb.getPreSchoolClassTypeId());
			} else {
				query.setInt(1, rb.getElementarySchoolTypeId());
			}
			query.setString(2, schoolYearName);
			query.setInt(3, schoolId);
		} else { // 6 years old students
			query = getQuery(QUERY_ELEMENTARY_6_YEAR_STUDENTS);
			if (query == null) {
				query = new PreparedQuery(getConnection());
				query.setSelectCountDistinctUsers();
				query.setPlacements(getReportBusiness().getSchoolSeasonId());
				query.setOnlyStudentsBorn(getReportBusiness().getSchoolSeasonStartYear() - 6);
				query.setSchoolYearName("1");
				query.setSchoolTypeElementarySchool();
				query.setSchool(); // parameter 1
				query.prepare();
				setQuery(QUERY_ELEMENTARY_6_YEAR_STUDENTS, query);
			}
			query.setInt(1, schoolId);
		}
		return query.execute();
	}
	
	/**
	 * Returns the number of student placements for the specified school.
	 */
	protected int getCount(int schoolId) throws RemoteException {
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_COUNT);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setFourSchoolTypes(); // parameter 1-4
			query.setSchool(); // parameter 5
			query.prepare();
			setQuery(QUERY_COUNT, query);
		}

		int schoolTypeId = rb.getPreSchoolClassTypeId(); 
		query.setInt(1, schoolTypeId);
		query.setInt(2, rb.getElementarySchoolTypeId());
		query.setInt(3, schoolTypeId);
		query.setInt(4, schoolTypeId);

		query.setInt(5, schoolId);

		return query.execute();
	}
	
	/*
	 * Remove schools with no placements.
	 */
	Collection removeEmptySchools(Collection schools, SchoolArea area) throws RemoteException {
		Collection c = (Collection) this._schools.get(area);
		if (c == null) {
			c = new ArrayList();
			Iterator iter = schools.iterator();
			while (iter.hasNext()) {
				School school = (School) iter.next();
				int id = ((Integer) school.getPrimaryKey()).intValue();
				int count = getCount(id);
				if (count > 0) {
					c.add(school);
				}
			}
			this._schools.put(area, c);
		}
		return c;
	}
} public class NackaHighSchoolStudyPathPlacementReportModel extends ReportModel {

	private final static int COLUMN_SIZE = 6;
	
	private final static int ROW_METHOD_STUDY_PATH = 1;
	private final static int ROW_METHOD_TOTAL = 2;

	private final static int COLUMN_METHOD_STUDY_PATH_CODE = 101;
	private final static int COLUMN_METHOD_SCHOOL_YEAR = 102;
	private final static int COLUMN_METHOD_COMPULSORY_SCHOOL_YEAR = 103;
	private final static int COLUMN_METHOD_SUM_1_4 = 104;

	private final static String QUERY_STUDY_PATH = "study_path";
	private final static String QUERY_STUDY_PATH_YEAR = "study_path_year";
	
	private final static String KEY_REPORT_TITLE = KP + "title_nacka_high_school_study_path_placements";
	
	private Collection _studyPaths = null;
	
	/**
	 * Constructs this report model.
	 * @param reportBusiness the report business instance for calculating cell values
	 */
	public NackaHighSchoolStudyPathPlacementReportModel(ReportBusiness reportBusiness) {
		super(reportBusiness);
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#initReportSize()
	 */
	protected void initReportSize() {
		try {
			Collection studyPaths = getStudyPaths();
			int rowSize = 0;
			rowSize += studyPaths.size() + 1; 
			setReportSize(rowSize, COLUMN_SIZE);
		} catch (RemoteException e) {
			log(e.getMessage());
		}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildRowHeaders()
	 */
	protected Header[] buildRowHeaders() {
		Header[] headers = null;
		
		try {
			Collection studyPaths = getStudyPaths();
			headers = new Header[studyPaths.size() + 1];
			Iterator iter = studyPaths.iterator();
			int headerIndex = 0;
			while (iter.hasNext()) {
				SchoolStudyPath studyPath = (SchoolStudyPath) iter.next();
				String label = studyPath.getDescription();
				headers[headerIndex] = new Header(label, Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER);
				headerIndex++;
			}
			
			Header header = new Header(KEY_TOTAL, Header.HEADERTYPE_ROW_TOTAL);
			headers[headerIndex] = header;
			headerIndex++;

		} catch (RemoteException e) {
			log(e.getMessage());
		}
		
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildColumnHeaders()
	 */
	protected Header[] buildColumnHeaders() {
		Header[] headers = new Header[2];
		
		Header h = new Header(KEY_STUDY_PATH_CODE, Header.HEADERTYPE_COLUMN_HEADER);
		headers[0] = h;
		
		h = new Header(KEY_SCHOOL_YEAR, Header.HEADERTYPE_COLUMN_HEADER, 5);
		Header child0 = new Header(KEY_SCHOOL_YEAR_1, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child1 = new Header(KEY_SCHOOL_YEAR_2, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child2 = new Header(KEY_SCHOOL_YEAR_3, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child3 = new Header(KEY_SCHOOL_YEAR_4, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child4 = new Header(KEY_SUM_1_4, Header.HEADERTYPE_COLUMN_NORMAL);
		h.setChild(0, child0);
		h.setChild(1, child1);
		h.setChild(2, child2);
		h.setChild(3, child3);
		h.setChild(4, child4);
		headers[1] = h;
				
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildCells()
	 */
	protected void buildCells() {
		for (int column = 0; column < getColumnSize(); column++) {
			int row = 0;
			int columnMethod = 0;
			String columnParameter = null;
			switch (column) {
				case 0:
					columnMethod = COLUMN_METHOD_STUDY_PATH_CODE;
					break;
				case 1:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "1";
					break;
				case 2:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "2";
					break;
				case 3:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "3";
					break;
				case 4:
					columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					columnParameter = "4";
					break;
				case 5:
					columnMethod = COLUMN_METHOD_SUM_1_4;
					break;
			}
			
			try {
				Collection studyPaths = getStudyPaths();
				Iterator iter = studyPaths.iterator();
				while (iter.hasNext()) {
					SchoolStudyPath studyPath = (SchoolStudyPath) iter.next();
					String studyPathCode = studyPath.getCode();
					Object rowParameter = studyPathCode;
					String schoolYear = columnParameter;
					if (columnMethod == COLUMN_METHOD_COMPULSORY_SCHOOL_YEAR) {
						columnMethod = COLUMN_METHOD_SCHOOL_YEAR;
					} else if (columnMethod == COLUMN_METHOD_SCHOOL_YEAR) {
						if (studyPathCode.length() > 3 && studyPathCode.substring(0, 3).equals("GYS")) {
							columnMethod = COLUMN_METHOD_COMPULSORY_SCHOOL_YEAR;
							schoolYear = "GS" + columnParameter; 
						} else {
							schoolYear = "G" + columnParameter;
						}
					}
					int cellType = Cell.CELLTYPE_NORMAL;
					if (columnMethod == COLUMN_METHOD_STUDY_PATH_CODE) {
						cellType = Cell.CELLTYPE_ROW_HEADER;
					}
					Cell cell = new Cell(this, row, column, ROW_METHOD_STUDY_PATH,
							columnMethod, rowParameter, schoolYear, cellType);
					setCell(row, column, cell);
					row++;
				}

				int cellType = Cell.CELLTYPE_TOTAL;
				if (columnMethod == COLUMN_METHOD_STUDY_PATH_CODE) {
					cellType = Cell.CELLTYPE_ROW_HEADER;
				}
				Cell cell = new Cell(this, row, column, ROW_METHOD_TOTAL,
						columnMethod, "", columnParameter, cellType);
				setCell(row, column, cell);
				row++;
				
			} catch (RemoteException e) {
				log(e.getMessage());
			}
		}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#calculate()
	 */
	protected float calculate(Cell cell) throws RemoteException {
		float value = 0f;
		String studyPathCode = null;
		if (cell.getRowParameter() != null) {
			studyPathCode = (String) cell.getRowParameter();
		}
		int row = cell.getRow();
		int column = cell.getColumn();
		
		String schoolYearName = (String) cell.getColumnParameter();
		
		switch (cell.getRowMethod()) {
			case ROW_METHOD_STUDY_PATH:
				switch (cell.getColumnMethod()) {
					case COLUMN_METHOD_SCHOOL_YEAR:
						value = getHighSchoolPlacementCount(studyPathCode, schoolYearName, false);
						break;
					case COLUMN_METHOD_COMPULSORY_SCHOOL_YEAR:
						value = getHighSchoolPlacementCount(studyPathCode, schoolYearName, true);
						break;
					case COLUMN_METHOD_SUM_1_4:
						value = getCell(row, 1).getFloatValue() +
								getCell(row, 2).getFloatValue() +
								getCell(row, 3).getFloatValue() +
								getCell(row, 4).getFloatValue();
						break;
				}
				break;
			case ROW_METHOD_TOTAL:
				for (int i = 0; i < row; i++) {
					Cell c = getCell(i, column);
					value += c.getFloatValue();
				}
				break;
		}
		
		return value;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#getReportTitleLocalizationKey()
	 */
	public String getReportTitleLocalizationKey() {
		return KEY_REPORT_TITLE;
	}
	
	/**
	 * Returns the number of student placements for the specified study path code and school year.
	 */
	protected int getHighSchoolPlacementCount(String studyPathCode, String schoolYearName, boolean isCompulsory) 
			throws RemoteException {
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_STUDY_PATH_YEAR);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setOnlyNackaCitizens();
			query.setStudyPathPrefix(); // parameter 1
			query.setSchoolYearName(); // parameter 2
			query.setSchoolType(); // parameter 3
			query.prepare();
			setQuery(QUERY_STUDY_PATH_YEAR, query);
		}
		query.setString(1, studyPathCode);
		query.setString(2, schoolYearName);
		if (isCompulsory) {
			query.setInt(3, rb.getCompulsoryHighSchoolTypeId());
		} else {
			query.setInt(3, rb.getHighSchoolTypeId());
		}
		return query.execute();
	}
	
	/**
	 * Returns the number of student placements for the specified study path code.
	 */
	protected int getHighSchoolPlacementCount(String studyPathCode) throws RemoteException {
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_STUDY_PATH);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setOnlyNackaCitizens();
			query.setStudyPathPrefix(); // parameter 1
			query.prepare();
			setQuery(QUERY_STUDY_PATH, query);
		}
		query.setString(1, studyPathCode);
		return query.execute();
	}
	
	/*
	 * Returns a filtered list with only Nacka study paths. 
	 */
	private Collection getStudyPaths() throws RemoteException {
		if (this._studyPaths == null) {
			this._studyPaths = new ArrayList();
			ReportBusiness rb = getReportBusiness();
			Collection c = rb.getAllStudyPathsIncludingDirections();
			Iterator iter = c.iterator();
			while (iter.hasNext()) {
				SchoolStudyPath sp = (SchoolStudyPath) iter.next();
				String code = sp.getCode();
				int count = getHighSchoolPlacementCount(code);
				if (count > 0) {
					this._studyPaths.add(sp);
				}
			}			
		}
		return this._studyPaths;
	}
} public class NackaPrivateHighSchoolPlacementReportModel extends ReportModel {

	private final static int COLUMN_SIZE = 18;
	
	private final static int ROW_METHOD_STUDY_PATH = 1;
	private final static int ROW_METHOD_TOTAL = 2;

	private final static int COLUMN_METHOD_SCHOOL_1 = 101;
	private final static int COLUMN_METHOD_SCHOOL_2 = 102;
	private final static int COLUMN_METHOD_SCHOOL_3 = 103;
	private final static int COLUMN_METHOD_TOTAL = 104;
	private final static int COLUMN_METHOD_OTHER_COMMUNE_CITIZENS = 105;
	private final static int COLUMN_METHOD_NACKA_CITIZENS = 106;

	private final static String QUERY_ALL = "all";
	private final static String QUERY_OTHER_COMMUNES = "other_communes";
	private final static String QUERY_NACKA_COMMUNE = "nacka_commune";
	private final static String QUERY_COUNT = "count";

	private final static String KEY_REPORT_TITLE = KP + "title_nacka_private_high_school_placements";
	
	private School[] _schools = null;
	private Collection _studyPaths = null;

	/**
	 * Constructs this report model.
	 * @param reportBusiness the report business instance for calculating cell values
	 */
	public NackaPrivateHighSchoolPlacementReportModel(ReportBusiness reportBusiness) {
		super(reportBusiness);
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#initReportSize()
	 */
	protected void initReportSize() {
		Collection studyPaths = getStudyPaths();
		int rowSize = 0;
		rowSize += studyPaths.size() + 1; 
		setReportSize(rowSize, COLUMN_SIZE);
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildRowHeaders()
	 */
	protected Header[] buildRowHeaders() {
		Header[] headers = null;
		
		Collection studyPaths = getStudyPaths();
		headers = new Header[studyPaths.size() + 1];
		Iterator iter = studyPaths.iterator();
		int headerIndex = 0;
		while (iter.hasNext()) {
			SchoolStudyPath studyPath = (SchoolStudyPath) iter.next();
			headers[headerIndex] = new Header(studyPath.getDescription(), Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER, 1);
			Header child = new Header(studyPath.getCode(), Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL);
			headers[headerIndex].setChild(0, child);
			headerIndex++;
		}
		
		Header header = new Header(KEY_TOTAL, Header.HEADERTYPE_ROW_TOTAL);
		headers[headerIndex] = header;
		headerIndex++;
		
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildColumnHeaders()
	 */
	protected Header[] buildColumnHeaders() {
		Header[] headers = new Header[6];
		int headerColumn = 0;
		try {
			ReportBusiness rb = getReportBusiness();
			Collection schools = rb.getPrivateHighSchools();
			this._schools = new School[schools.size()];
			int schoolIndex = 0;
			Iterator iter = schools.iterator();
			while (iter.hasNext()) {
				School school = (School) iter.next();
				this._schools[schoolIndex++] = school;
				Header h = new Header(school.getName(), Header.HEADERTYPE_COLUMN_NONLOCALIZED_HEADER, 4);
				Header child0 = new Header(KEY_SCHOOL_YEAR_1, Header.HEADERTYPE_COLUMN_NORMAL);
				Header child1 = new Header(KEY_SCHOOL_YEAR_2, Header.HEADERTYPE_COLUMN_NORMAL);
				Header child2 = new Header(KEY_SCHOOL_YEAR_3, Header.HEADERTYPE_COLUMN_NORMAL);
				Header child3 = new Header(KEY_SUM_1_3, Header.HEADERTYPE_COLUMN_NORMAL);
				h.setChild(0, child0);
				h.setChild(1, child1);
				h.setChild(2, child2);
				h.setChild(3, child3);
				headers[headerColumn++] = h;
			}
		} catch (RemoteException e) {
			log(e.getMessage());
		}
		
		Header h = new Header(KEY_TOTAL, Header.HEADERTYPE_COLUMN_HEADER, 4);
		Header child0 = new Header(KEY_SCHOOL_YEAR_1, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child1 = new Header(KEY_SCHOOL_YEAR_2, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child2 = new Header(KEY_SCHOOL_YEAR_3, Header.HEADERTYPE_COLUMN_NORMAL);
		Header child3 = new Header(KEY_SUM_1_3, Header.HEADERTYPE_COLUMN_NORMAL);
		h.setChild(0, child0);
		h.setChild(1, child1);
		h.setChild(2, child2);
		h.setChild(3, child3);
		headers[headerColumn++] = h;
		
		h = new Header(KEY_OF_WHICH_FROM_OTHER_COMMUNES, Header.HEADERTYPE_COLUMN_HEADER);
		headers[headerColumn++] = h;
		
		h = new Header(KEY_NACKA_STUDENTS, Header.HEADERTYPE_COLUMN_HEADER);
		headers[headerColumn++] = h;
				
		return headers;
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#buildCells()
	 */
	protected void buildCells() {
		for (int column = 0; column < getColumnSize(); column++) {
			int row = 0;
			int columnMethod = 0;
			String columnParameter = null;
			int cellType = Cell.CELLTYPE_NORMAL;
			switch (column) {
				case 0:
					columnMethod = COLUMN_METHOD_SCHOOL_1;
					columnParameter = "G1";
					break;
				case 1:
					columnMethod = COLUMN_METHOD_SCHOOL_1;
					columnParameter = "G2";
					break;
				case 2:
					columnMethod = COLUMN_METHOD_SCHOOL_1;
					columnParameter = "G3";
					break;
				case 3:
					columnMethod = COLUMN_METHOD_SCHOOL_1;
					columnParameter = null;
					cellType = Cell.CELLTYPE_SUM;
					break;
				case 4:
					columnMethod = COLUMN_METHOD_SCHOOL_2;
					columnParameter = "G1";
					break;
				case 5:
					columnMethod = COLUMN_METHOD_SCHOOL_2;
					columnParameter = "G2";
					break;
				case 6:
					columnMethod = COLUMN_METHOD_SCHOOL_2;
					columnParameter = "G3";
					break;
				case 7:
					columnMethod = COLUMN_METHOD_SCHOOL_2;
					columnParameter = null;
					cellType = Cell.CELLTYPE_SUM;
					break;
				case 8:
					columnMethod = COLUMN_METHOD_SCHOOL_3;
					columnParameter = "G1";
					break;
				case 9:
					columnMethod = COLUMN_METHOD_SCHOOL_3;
					columnParameter = "G2";
					break;
				case 10:
					columnMethod = COLUMN_METHOD_SCHOOL_3;
					columnParameter = "G3";
					break;
				case 11:
					columnMethod = COLUMN_METHOD_SCHOOL_3;
					columnParameter = null;
					cellType = Cell.CELLTYPE_SUM;
					break;
				case 12:
					columnMethod = COLUMN_METHOD_TOTAL;
					columnParameter = "G1";
					break;
				case 13:
					columnMethod = COLUMN_METHOD_TOTAL;
					columnParameter = "G2";
					break;
				case 14:
					columnMethod = COLUMN_METHOD_TOTAL;
					columnParameter = "G3";
					break;
				case 15:
					columnMethod = COLUMN_METHOD_TOTAL;
					columnParameter = null;
					cellType = Cell.CELLTYPE_TOTAL;
					break;
				case 16:
					columnMethod = COLUMN_METHOD_OTHER_COMMUNE_CITIZENS;
					columnParameter = null;
					break;
				case 17:
					columnMethod = COLUMN_METHOD_NACKA_CITIZENS;
					columnParameter = null;
					break;
			}
			
			Collection studyPaths = getStudyPaths();
			Iterator iter = studyPaths.iterator();
			while (iter.hasNext()) {
				SchoolStudyPath studyPath = (SchoolStudyPath) iter.next();
				Object rowParameter = studyPath.getCode();
				Cell cell = new Cell(this, row, column, ROW_METHOD_STUDY_PATH,
						columnMethod, rowParameter, columnParameter, cellType);
				setCell(row, column, cell);
				row++;
			}
			
			Cell cell = new Cell(this, row, column, ROW_METHOD_TOTAL,
					columnMethod, null, columnParameter, Cell.CELLTYPE_TOTAL);
			setCell(row, column, cell);
			row++;
		}
	}
	
	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#calculate()
	 */
	protected float calculate(Cell cell) throws RemoteException {
		float value = 0f;
		String studyPathPrefix = null;
		if (cell.getRowParameter() != null) {
			studyPathPrefix = (String) cell.getRowParameter();
		}
		String schoolYearName = (String) cell.getColumnParameter();
		int row = cell.getRow();
		int column = cell.getColumn();
		
		switch (cell.getRowMethod()) {
			case ROW_METHOD_STUDY_PATH:
				switch (cell.getColumnMethod()) {
					case COLUMN_METHOD_SCHOOL_1:
						if (schoolYearName == null) {
							value += getCell(row, 0).getFloatValue();
							value += getCell(row, 1).getFloatValue();
							value += getCell(row, 2).getFloatValue();
						} else {
							value = getHighSchoolNackaCommunePlacementCount(this._schools[0], schoolYearName, studyPathPrefix);
						}
						break;
					case COLUMN_METHOD_SCHOOL_2:
						if (schoolYearName == null) {
							value += getCell(row, 4).getFloatValue();
							value += getCell(row, 5).getFloatValue();
							value += getCell(row, 6).getFloatValue();
						} else {
							value = getHighSchoolNackaCommunePlacementCount(this._schools[1], schoolYearName, studyPathPrefix);
						}
						break;
					case COLUMN_METHOD_SCHOOL_3:
						if (schoolYearName == null) {
							value += getCell(row, 8).getFloatValue();
							value += getCell(row, 9).getFloatValue();
							value += getCell(row, 10).getFloatValue();
						} else {
							value = getHighSchoolNackaCommunePlacementCount(this._schools[2], schoolYearName, studyPathPrefix);
						}
						break;
					case COLUMN_METHOD_TOTAL:
						for (int i = column % 4; i < 12; i += 4) {
							value += getCell(row, i).getFloatValue();
						}
						break;
					case COLUMN_METHOD_OTHER_COMMUNE_CITIZENS:
						value = getHighSchoolOCCPlacementCount(studyPathPrefix);
						break;
					case COLUMN_METHOD_NACKA_CITIZENS:
						value = getHighSchoolNackaCitizenPlacementCount(studyPathPrefix);
						break;
				}
				break;
			case ROW_METHOD_TOTAL:
				for (int i = 0; i < row; i++) {
					Cell c = getCell(i, column);
					value += c.getFloatValue();
				}
				break;
		}
		
		return value;
	}

	/**
	 * @see se.idega.idegaweb.commune.school.report.business.ReportModel#getReportTitleLocalizationKey()
	 */
	public String getReportTitleLocalizationKey() {
		return KEY_REPORT_TITLE;
	}
	
	/*
	 * Returns the value from executing the specified study path query.
	 * Special case for study path IB handled.
	 */
	private int executeStudyPathQuery(int parameterIndex, String studyPathPrefix, PreparedQuery query) {
		query.setString(parameterIndex, studyPathPrefix + "%");
		int value = query.execute();
		if (studyPathPrefix.equals("IB")) {
			query.setString(parameterIndex, "PRE%");
			value += query.execute();
		}
		return value;		
	}
	
	/**
	 * Returns the number of student placements for high schools
	 * in Nacka commune for the specified school year.
	 */
	protected int getHighSchoolNackaCommunePlacementCount(School school, String schoolYearName, String studyPathPrefix) throws RemoteException {
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_ALL);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setSchoolTypeHighSchool();
			query.setSchool(); // parameter 1
			query.setSchoolYearName(); // parameter 2
			query.setStudyPathPrefix(); // parameter 3
			query.prepare();
			setQuery(QUERY_ALL, query);
		}
		query.setInt(1, ((Integer) school.getPrimaryKey()).intValue());
		query.setString(2, schoolYearName);
		return executeStudyPathQuery(3, studyPathPrefix, query);
	}
	
	/**
	 * Returns the number of student placements for private high schools
	 * for the specified study path prefix.
	 */
	protected int getHighSchoolOCCPlacementCount(String studyPathPrefix) throws RemoteException{
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_OTHER_COMMUNES);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setNotNackaCitizens();
			query.setSchoolTypeHighSchool();
			query.setSchools(rb.getPrivateHighSchools());
			query.setStudyPathPrefix(); // parameter 1
			query.prepare();
			setQuery(QUERY_OTHER_COMMUNES, query);
		}
		return executeStudyPathQuery(1, studyPathPrefix, query);
	}	
	
	/**
	 * Returns the number of student placements for private high schools
	 * in Nacka commune for the specified school year.
	 * Only citizens in Nacka commune are counted. 
	 */
	protected int getHighSchoolNackaCitizenPlacementCount(String studyPathPrefix) throws RemoteException{
		PreparedQuery query = null;
		ReportBusiness rb = getReportBusiness();
		query = getQuery(QUERY_NACKA_COMMUNE);
		if (query == null) {
			query = new PreparedQuery(getConnection());
			query.setSelectCountDistinctUsers();
			query.setPlacements(rb.getSchoolSeasonId());
			query.setOnlyNackaCitizens();
			query.setSchoolTypeHighSchool();
			query.setSchools(rb.getPrivateHighSchools());
			query.setStudyPathPrefix(); // parameter 1
			query.prepare();
			setQuery(QUERY_NACKA_COMMUNE, query);
		}
		return executeStudyPathQuery(1, studyPathPrefix, query);
	}
	
	/**
	 * Returns the number of placements for private high schools for the specified study path prefix.
	 */
	protected int getPlacementCount(String studyPathPrefix) {
		int count = -1;
		try {
			PreparedQuery query = null;
			ReportBusiness rb = getReportBusiness();
			query = getQuery(QUERY_COUNT);
			if (query == null) {
				query = new PreparedQuery(getConnection());
				query.setSelectCountDistinctUsers();
				query.setPlacements(rb.getSchoolSeasonId());
				query.setSchoolTypeHighSchool();
				query.setSchools(rb.getPrivateHighSchools());
				query.setStudyPathPrefix(); // parameter 1
				query.prepare();
				setQuery(QUERY_COUNT, query);
			}
			count = executeStudyPathQuery(1, studyPathPrefix, query);
		} catch (RemoteException e) {}
		
		return count;
	}
	
	/*
	 * Returns all study paths with non-zero placements.
	 */
	private Collection getStudyPaths() {
		if (this._studyPaths == null) {
			this._studyPaths = new ArrayList();
			try {
				Collection c = getReportBusiness().getAllStudyPaths();
				Iterator iter = c.iterator();
				while (iter.hasNext()) {
					SchoolStudyPath sp = (SchoolStudyPath) iter.next();
					int count = getPlacementCount(sp.getCode());
					if (count > 0) {
						this._studyPaths.add(sp);
					}
				}
			} catch (RemoteException e) {}
			
		}
		return this._studyPaths;
	}
} public interface ReportBusiness extends com.idega.business.IBOService
{
 public se.idega.idegaweb.commune.school.report.business.ReportModel createReportModel(java.lang.Class p0) throws java.rmi.RemoteException;
 public Collection getAfterSchool6Areas() throws java.rmi.RemoteException;
 public int getAfterSchool6TypeId() throws java.rmi.RemoteException;
 public Collection getAfterSchool7_9Areas() throws java.rmi.RemoteException;
 public int getAfterSchool7_9TypeId() throws java.rmi.RemoteException;
 public Collection getAllStudyPaths() throws java.rmi.RemoteException;
 public Collection getAllStudyPathsIncludingDirections() throws java.rmi.RemoteException;
 public Collection getChildCareProviders() throws java.rmi.RemoteException;
 public Collection getCommuneSchools(int p0,Collection p1,Collection p2) throws java.rmi.RemoteException;
 public int getCompulsoryHighSchoolTypeId() throws java.rmi.RemoteException;
 public Collection getCompulsoryHighSchools() throws java.rmi.RemoteException;
 public Collection getCompulsorySchoolAreas() throws java.rmi.RemoteException;
 public int getCompulsorySchoolTypeId() throws java.rmi.RemoteException;
 public Collection getCompulsorySchools(com.idega.block.school.data.SchoolArea p0) throws java.rmi.RemoteException;
 public com.idega.block.school.data.SchoolSeason getCurrentSchoolSeason() throws java.rmi.RemoteException;
 public Collection<SchoolArea> getElementarySchoolAreas() throws java.rmi.RemoteException;
 public int getElementarySchoolTypeId() throws java.rmi.RemoteException;
 public Collection getElementarySchools(com.idega.block.school.data.SchoolArea p0) throws java.rmi.RemoteException;
 public int getFamilyAfterSchool6TypeId() throws java.rmi.RemoteException;
 public int getFamilyAfterSchool7_9TypeId() throws java.rmi.RemoteException;
 public int getFamilyDayCareSchoolTypeId() throws java.rmi.RemoteException;
 public int getGeneralFamilyDaycareSchoolTypeId() throws java.rmi.RemoteException;
 public int getGeneralPreSchoolTypeId() throws java.rmi.RemoteException;
 public int getHighSchoolStudentAgeFrom(int p0) throws java.rmi.RemoteException;
 public int getHighSchoolStudentAgeTo(int p0) throws java.rmi.RemoteException;
 public int getHighSchoolTypeId() throws java.rmi.RemoteException;
 public Collection getNackaCommuneHighSchools() throws java.rmi.RemoteException;
 public int getPreSchoolClassTypeId() throws java.rmi.RemoteException;
 public Collection getPreSchoolOperationAreas() throws java.rmi.RemoteException;
 public int getPreSchoolTypeId() throws java.rmi.RemoteException;
 public Collection getPrivateHighSchools() throws java.rmi.RemoteException;
 public Collection getPrivateSchoolAreas() throws java.rmi.RemoteException;
 public Collection getPrivateSchools(com.idega.block.school.data.SchoolArea p0) throws java.rmi.RemoteException;
 public int getSchoolSeasonId() throws java.rmi.RemoteException;
 public int getSchoolSeasonStartYear() throws java.rmi.RemoteException;
 public void log(java.lang.String p0) throws java.rmi.RemoteException;
} public abstract class ReportModel {

	private int _rowSize = 0;
	private int _columnSize = 0;
	
	private ReportBusiness _reportBusiness = null;
	
	private Cell[][] _cells = null;
	private Header[] _rowHeaders = null;
	private Header[] _columnHeaders = null;
	
	private Map _queryCache = null;
	private Connection _connection = null;

	protected final static String KP = "report."; // Localization key prefix
	
	protected final static String KEY_SCHOOL_YEAR_F = KP + "school_year_f";
	protected final static String KEY_SCHOOL_YEAR_1 = KP + "school_year_1";
	protected final static String KEY_SCHOOL_YEAR_2 = KP + "school_year_2";
	protected final static String KEY_SCHOOL_YEAR_3 = KP + "school_year_3";
	protected final static String KEY_SCHOOL_YEAR_4 = KP + "school_year_4";
	protected final static String KEY_SCHOOL_YEAR_5 = KP + "school_year_5";
	protected final static String KEY_SCHOOL_YEAR_6 = KP + "school_year_6";
	protected final static String KEY_SCHOOL_YEAR_7 = KP + "school_year_7";
	protected final static String KEY_SCHOOL_YEAR_8 = KP + "school_year_8";
	protected final static String KEY_SCHOOL_YEAR_9 = KP + "school_year_9";
	protected final static String KEY_SCHOOL_YEAR_10 = KP + "school_year_10";
	protected final static String KEY_SCHOOL_YEAR = KP + "school_year";
	protected final static String KEY_SUM_1_3 = KP + "sum_1_3";
	protected final static String KEY_SUM_4_6 = KP + "sum_4_6";
	protected final static String KEY_SUM_7_10 = KP + "sum_7_10";
	protected final static String KEY_TOTAL_1_10 = KP + "total_1_10";
	protected final static String KEY_TOTAL_F_10 = KP + "total_f_10";
	protected final static String KEY_SUM_7_9 = KP + "sum_7_9";
	protected final static String KEY_TOTAL_1_9 = KP + "total_1_9";
	protected final static String KEY_TOTAL_F_9 = KP + "total_f_9";
	protected final static String KEY_SUM = KP + "sum";
	protected final static String KEY_TOTAL = KP + "total";
	protected final static String KEY_SHARE = KP + "share";
	protected final static String KEY_ELEMENTARY_SCHOOL = KP + "elementary_school";
	protected final static String KEY_NACKA_COMMUNE = KP + "nacka_commune";
	protected final static String KEY_OTHER_COMMUNES = KP + "other_communes";
	protected final static String KEY_PRIVATE_SCHOOLS = KP + "private_schools";
	protected final static String KEY_FOREIGN_SCHOOLS = KP + "foreign_schools";
	protected final static String KEY_COMPULSORY_SCHOOLS = KP + "compulsory_schools";
	protected final static String KEY_SIX_YEARS_STUDENTS = KP + "six_years_students";
	protected final static String KEY_COUNTY_COUNCIL = KP + "county_council";
	protected final static String KEY_FREE_STANDING = KP + "free_standing";
	protected final static String KEY_COMPULSORY_HIGH_SCHOOLS = KP + "compulsory_high_schools";
	protected final static String KEY_STUDY_PATH_CODE_COMPULSORY_HIGH_SCHOOL = KP + "study_path_code_compulsory_high_school";
	protected final static String KEY_STUDENT_AGE_16 = KP + "student_age_16";
	protected final static String KEY_STUDENT_AGE_17 = KP + "student_age_17";
	protected final static String KEY_STUDENT_AGE_18 = KP + "student_age_18";
	protected final static String KEY_STUDENT_AGE_19 = KP + "student_age_19";
	protected final static String KEY_OTHER_COMMUNE_CITIZENS = KP + "other_commune_citizens";
	protected final static String KEY_TOTAL_1_4 = KP + "total_1_4";
	protected final static String KEY_NACKA_STUDENTS = KP + "nacka_students";
	protected final static String KEY_PROVISIONS_PROGRAM = KP + "provisions_program";
	protected final static String KEY_NUMBER_OF_STUDENTS = KP + "number_of_students";
	protected final static String KEY_STUDY_PATH_CODE = KP + "study_path_code";
	protected final static String KEY_SUM_1_4 = KP + "sum_1_4";

	protected final static String KEY_PRE_SCHOOL_OPERATION = KP + "pre_school_operation";
	protected final static String KEY_PRE_SCHOOL = KP + "pre_school";
	protected final static String KEY_OF_WHICH_COMMUNE_MANAGEMENT = KP + "of_which_commune_management";
	protected final static String KEY_OF_WHICH_PRIVATE_MANAGEMENT = KP + "of_which_private_management";
	protected final static String KEY_FAMILY_DAYCARE = KP + "family_day_daycare";
	protected final static String KEY_COOPERATIVE = KP + "cooperative";
	protected final static String KEY_SCHOOL_CHILDREN_CARE_6_YEAR = KP + "school_children_care_6_year";
	protected final static String KEY_AFTER_SCHOOL_CENTRE = KP + "after_school_centre";
	protected final static String KEY_SCHOOL_CHILDREN_CARE_7_9_YEAR = KP + "school_children_care_7_9_year";
	protected final static String KEY_FAMILY_AFTER_SCHOOL_CENTRE = KP + "family_after_school_centre";
	protected final static String KEY_SUM_CHILDREN = KP + "sum_children";
	protected final static String KEY_COMMUNE_PRE_SCHOOL_OPERATION = KP + "commune_pre_school_operation";
	protected final static String KEY_PRIVATE_COOPERATIVE_PRE_SCHOOL_OPERATION = KP + "private_cooperative_pre_school_operation";
	protected final static String KEY_COMMUNE_SCHOOL_CHILDREN_CARE_6 = KP + "commun_school_children_care_6";
	protected final static String KEY_PRIVATE_COOPERATIVE_SCHOOL_CHILDREN_CARE_6 = KP + "private_cooperative_school_children_care_6";
	protected final static String KEY_COMMUNE_SCHOOL_CHILDREN_CARE_7_9 = KP + "commune_school_children_care_7_9";
	protected final static String KEY_PRIVATE_SCHOOL_CHILDREN_CARE_7_9 = KP + "private_school_children_care_7_9";
	protected final static String KEY_COMMUNE_SUM = KP + "commune_sum";
	protected final static String KEY_PRIVATE_SUM = KP + "private_sum";
	protected final static String KEY_NUMBER_OF_CHILDREN = KP + "number_of_children";
	protected final static String KEY_SHARE_IN_PERCENT = KP + "share_in_percent";
	protected final static String KEY_CHILDREN_TOTAL = KP + "children_total";
	protected final static String KEY_COMMUNE_PRE_SCHOOL_PROVIDERS = KP + "commune_pre_school_providers";
	protected final static String KEY_COMMUNE_AFTER_SCHOOL_PROVIDERS = KP + "commune_after_school_providers";
	protected final static String KEY_COMMUNE_FAMILY_DAYCARE_PROVIDERS = KP + "commune_family_daycare_providers";
	protected final static String KEY_PRIVATE_PRE_SCHOOL_PROVIDERS = KP + "private_pre_school_providers";
	protected final static String KEY_PRIVATE_AFTER_SCHOOL_PROVIDERS = KP + "private_after_school_providers";
	protected final static String KEY_PRIVATE_FAMILY_DAYCARE_PROVIDERS = KP + "private_family_daycare_providers";
	protected final static String KEY_PROVIDER_TOTAL = KP + "provider_total";
	protected final static String KEY_NUMBER_OF_PROVIDERS = KP + "number_of_providers";
	protected final static String KEY_COMMUNE_UNITS = KP + "commune_units";
	protected final static String KEY_PRIVATE_UNITS = KP + "private_units";
	protected final static String KEY_CHILDREN_IN_FAMILY_DAYCARE = KP + "children_in_family_daycare";
	protected final static String KEY_MEAN_WEEK_HOURS = KP + "mean_week_hours";
	protected final static String KEY_PARENTAL_LEAVE = KP + "parental_leave";
	protected final static String KEY_JOB_CANDIDATE = KP + "job_candidate";
	protected final static String KEY_GENERAL_PRE_SCHOOL = KP + "general_pre_school";
	protected final static String KEY_SUM_CHILD_CARE_HOURS = KP + "sum_child_care_hours";
	protected final static String KEY_CHILD_CARE_HOURS = KP + "child_care_hours";
	protected final static String KEY_SCHOOL_CHILDREN_CARE = KP + "school_children_care";
	protected final static String KEY_TOTAL_PRE_SCHOOL_OPERATION = KP + "total_pre_school_operation";
	protected final static String KEY_AFTER_SCHOOL = KP + "after_school";
	protected final static String KEY_FAMILY_AFTER_SCHOOL = KP + "family_after_school";
	protected final static String KEY_TOTAL_AFTER_SCHOOL_OPERATION = KP + "total_after_school_operation";
	protected final static String KEY_SCHOOL_CHILDREN_CARE_INCLUDING_FAMILY_AFTER_SCHOOL = KP + "school_children_care_including";	
	//protected final static String KEY_GTEQ_36 = KP + "gteq_36";
	
	protected final static String KEY_GTEQ_40 = KP + "gteq_40";

	protected final static String KEY_COMMUNE_PROVIDERS = KP + "commune_providers";
	protected final static String KEY_PRE_SCHOOLS = KP + "pre_schools";
	protected final static String KEY_FAMILY_DAYCARE_CENTERS = KP + "key_family_daycare_centers";
	protected final static String KEY_WITHIN_PRE_SCHOOL_OPERATION = KP + "within_pre_school_operation";
	protected final static String KEY_WITHIN_AFTER_SCHOOL_OPERATION = KP + "within_after_school_operation";
	protected final static String KEY_AFTER_SCHOOL_CENTERS_6_9 = KP + "after_school_centers_6_9";
	protected final static String KEY_ELEMENTARY_SCHOOLS = KP + "elementary_schools";
	protected final static String KEY_WITHIN_ELEMENTARY_SCHOOL = KP + "within_elementary_school";
	protected final static String KEY_WITHIN_PRE_SCHOOL_CLASS = KP + "within_pre_school_class";
	protected final static String KEY_HIGH_SCHOOLS = KP + "high_schools";
	protected final static String KEY_PRIVATE_FREESTANDING_PROVIDERS = KP + "private_freestanding_providers";
	protected final static String KEY_CHILDREN_STUDENTS = KP + "children_students";
	protected final static String KEY_OF_WHICH_FROM_OTHER_COMMUNES = KP + "of_which_from_other_communes";
	protected final static String KEY_NUMBER_OF_PROVIDERS_CHILDCARE = KP + "number_of_providers_childcare";
	
	/**
	 * Constructs a report model with the specified report business logic. 
	 */	
	public ReportModel(ReportBusiness reportBusiness) {
		this._reportBusiness = reportBusiness;
		this._queryCache = new HashMap();
	}

	/**
	 * Constructs a report model with the specified size and report business logic. 
	 */	
	public ReportModel(int rowSize, int columnSize, ReportBusiness reportBusiness) {
		this(reportBusiness);
		setReportSize(rowSize, columnSize);
	}
	
	/**
	 * Sets the size of this report. 
	 */
	protected void setReportSize(int rowSize, int columnSize) {
		this._rowSize = rowSize;
		this._columnSize = columnSize;
	}

	/*
	 * Initializes the model information (headers and cells).
	 */
	private void init() {
		if (this._cells == null) {
			initReportSize();
			this._cells = new Cell[this._rowSize][this._columnSize];
			this._rowHeaders = buildRowHeaders();
			this._columnHeaders = buildColumnHeaders();
			buildCells();							
		}
	}
	
	/**
	 * Returns the number of rows in this report model. 
	 */
	public int getRowSize() {
		return this._rowSize;
	}
	
	/**
	 * Returns the number of columns in this report model. 
	 */
	public int getColumnSize() {
		return this._columnSize;
	}
	
	/**
	 * Returns the report business for this report model.
	 */
	ReportBusiness getReportBusiness() {
		return this._reportBusiness;
	}
	
	/**
	 * Returns the row headers for this report model. 
	 */
	public Header[] getRowHeaders() {
		init();
		return this._rowHeaders;
	}
	
	/**
	 * Returns the column headers for this report model. 
	 */
	public Header[] getColumnHeaders() {
		init();
		return this._columnHeaders;
	}
	
	/**
	 * Returns the cell for the specified position. 
	 */
	public Cell getCell(int row, int column) {
		init();
		return this._cells[row][column];
	}

	/**
	 * Logs the specified message on the default system log. 
	 */
	public void log(String msg) {
		try {
			this._reportBusiness.log(msg);
		} catch (RemoteException e) {
			// Failed to access the system log, using System.err to log message
			System.err.println(msg);
		}
	}
	
	/**
	 * Returns a database connection. 
	 */
	protected Connection getConnection() {
		if (this._connection == null) {
			this._connection = ConnectionBroker.getConnection();
		}
		return this._connection;
	}
	
	/**
	 * Returns the prepared query for the specified key. 
	 */
	protected PreparedQuery getQuery(String key) {
		return (PreparedQuery) this._queryCache.get(key);
	}
	
	/**
	 * Sets the prepared query with the specified key. 
	 */
	protected void setQuery(String key, PreparedQuery query) {
		this._queryCache.put(key, query);
	}
	
	/**
	 * Sets the cell for the specified position. 
	 */
	protected void setCell(int row, int column, Cell cell) {
		init();
		this._cells[row][column] = cell;
	}

	/**
	 * Closes used resources for this report model.
	 */
	public void close() {
		Iterator iter = this._queryCache.values().iterator();
		while (iter.hasNext()) {
			PreparedQuery query = (PreparedQuery) iter.next();
			query.close();
		}
		if (this._connection != null) {
			ConnectionBroker.freeConnection(this._connection);
		}
		this._queryCache = new HashMap();
		this._connection = null;
	}
	
	/**
	 * Initializes the report size (rows, columns). 
	 */
	abstract protected void initReportSize();
	
	/**
	 * Builds the report model row headers. 
	 */
	abstract protected Header[] buildRowHeaders();
	
	/**
	 * Builds the report model column headers. 
	 */
	abstract protected Header[] buildColumnHeaders();
	
	/**
	 * Builds the report model cells. 
	 */
	abstract protected void buildCells();
	
	/**
	 * Returns the title for this report in the form of a localization key. 
	 */
	abstract public String getReportTitleLocalizationKey();
	
	/**
	 * Returns the calculated value for the specified cell.
	 * @throws RemoteException if error occurred during calculation
	 */
	abstract protected float calculate(Cell cell) throws RemoteException;
} public class ReportPDFWriter {

	private final static String REPORT_FOLDER_NAME = "School Report Files";

	private ReportModel _reportModel = null;
	private IWResourceBundle _iwrb = null;
	private Font _normalFont = null;
	private Font _boldFont = null;
	int _widths[] = null;
	
	/**
	 * Constructs a report PDF writer object.
	 * @param reportModel the report model to write as a PDF file
	 * @param iwrb the resource bundle to use for translating text labels
	 */	
	public ReportPDFWriter(ReportModel reportModel, IWResourceBundle iwrb) {
		this._reportModel = reportModel;
		this._iwrb = iwrb;
	}	
	
	/**
	 * Creates the PDF report file.
	 */
	public ICFile createFile() {
		ICFile reportFolder = null;
		ICFileHome fileHome = null;

		try {
			fileHome = (ICFileHome) com.idega.data.IDOLookup.getHome(ICFile.class);
			reportFolder = fileHome.findByFileName(REPORT_FOLDER_NAME);
		} catch (FinderException e) {
			try {
				ICFile root = fileHome.findByFileName(ICFileBMPBean.IC_ROOT_FOLDER_NAME);
				reportFolder = fileHome.create();
				reportFolder.setName(REPORT_FOLDER_NAME);
				reportFolder.setMimeType("application/vnd.iw-folder");
				reportFolder.store();
				root.addChild(reportFolder);
			} catch (Exception e2) {
				System.out.println(e2);
				return null;
			}
		} catch (IDOLookupException e) {
			System.out.println(e);
			return null;
		}

		ICFile exportFile = null;
		String filename = this._reportModel.getReportTitleLocalizationKey() + ".pdf";
		
		try {
			MemoryFileBuffer buffer = getPDFBuffer();
			MemoryInputStream mis = new MemoryInputStream(buffer);

			try {
				exportFile = fileHome.findByFileName(filename);
				if (exportFile != null) {
					exportFile.remove();
				}
			} catch (FinderException e) {}

			exportFile = fileHome.create();
			exportFile.setFileValue(mis);
			exportFile.setMimeType("application/pdf");
			exportFile.setName(filename);
			exportFile.setFileSize(buffer.length());
			exportFile.store();
			
			reportFolder.addChild(exportFile);
		} catch (Exception e) {
			System.out.println(e);
		}
		return exportFile;
	}
	
	/*
	 * Returns the memory buffer for the PDF file. 
	 */
	private MemoryFileBuffer getPDFBuffer() throws DocumentException {
		MemoryFileBuffer buffer = new MemoryFileBuffer();
		MemoryOutputStream mos = new MemoryOutputStream(buffer);
		
		Document document = new Document(PageSize.A4, 50, 50, 50, 50);
		PdfWriter writer = PdfWriter.getInstance(document, mos);
		
		String titleKey = this._reportModel.getReportTitleLocalizationKey();
		String title = localize(titleKey, titleKey);
		this._normalFont = new Font(Font.HELVETICA, 7, Font.NORMAL);
		this._boldFont = new Font(Font.HELVETICA, 7, Font.BOLD);
		
		document.addTitle(title);
		document.addAuthor("Agura IT Reports");
		document.addSubject(title);
		document.open();
		
		String dateString = new Date(System.currentTimeMillis()).toString();
		
		document.add(new Phrase(title + " " + dateString + "\n\n", this._boldFont));
		document.add(new Phrase("\n", this._boldFont));

		int cols = this._reportModel.getColumnSize() + 1;
		Table table = new Table(cols);
		this._widths = new int[cols];
		for (int i = 0; i < cols; i++) {
			this._widths[i] = 1;
		}

		table.setSpacing(1.5f);
		
		buildColumnHeaders(table);
		buildRowHeaders(table);		
		buildReportCells(table);		

		int totalWidth = 0;
		for (int i = 0; i < cols; i++) {
			this._widths[i] += 1;
			totalWidth += this._widths[i];
		}
		int width = (100 * totalWidth) / 95;
		if (width > 100) {
			width = 100;
		}
		table.setWidth(width);
		table.setWidths(this._widths);
		document.add(table);
		document.close();
		writer.setPdfVersion(PdfWriter.VERSION_1_2);

		return buffer;
	}
	
	/**
	 * Builds the report column headers.
	 */
	protected void buildColumnHeaders(Table table) throws BadElementException {
		Header[] headers = this._reportModel.getColumnHeaders();
		com.lowagie.text.Cell cell = new com.lowagie.text.Cell();
		cell.setRowspan(2);
		table.addCell(cell, new Point(0, 0));
		int column = 1;
		for (int i = 0; i < headers.length; i++) {
			Header header = headers[i];
			Header[] children = header.getChildren();
			if (children == null) {
				String s = null;
				if (header.getHeaderType() == Header.HEADERTYPE_COLUMN_NONLOCALIZED_HEADER) {
					s = header.getLocalizationKey();
				} else {
					s = localize(header.getLocalizationKey(), header.getLocalizationKey());
				}
				cell = new com.lowagie.text.Cell(new Phrase(s, this._normalFont));
				cell.setRowspan(2);
				cell.setHorizontalAlignment(Element.ALIGN_CENTER); 
				cell.setVerticalAlignment(Element.ALIGN_BOTTOM); 
				table.addCell(cell, new Point(0, column));				
				setColSize(s, column, true);
				column++;
			} else {
				String s = null;
				if (header.getHeaderType() == Header.HEADERTYPE_COLUMN_NONLOCALIZED_HEADER) {
					s = header.getLocalizationKey();
				} else {
					s = localize(header.getLocalizationKey(), header.getLocalizationKey());
				}
				cell = new com.lowagie.text.Cell(new Phrase(s, this._normalFont));
				cell.setColspan(children.length);
				cell.setHorizontalAlignment(Element.ALIGN_CENTER); 
				table.addCell(cell, new Point(0, column));
				if (children.length == 1) {
					setColSize(s, column, false);
				}
				for (int j = 0; j < children.length; j++) {
					Header child = children[j];
					s = null;
					if (child.getHeaderType() == Header.HEADERTYPE_COLUMN_NONLOCALIZED_HEADER) {
						s = child.getLocalizationKey();
					} else {
						s = localize(child.getLocalizationKey(), child.getLocalizationKey());
					}
					cell = new com.lowagie.text.Cell(new Phrase(s, this._normalFont));
					cell.setHorizontalAlignment(Element.ALIGN_CENTER); 
					cell.setVerticalAlignment(Element.ALIGN_BOTTOM); 
					cell.setNoWrap(true);
					table.addCell(cell, new Point(1, column + j));
					setColSize(s, column + j, false);
				}
				column += children.length;
			}
		}
	}

	/**
	 * Builds the report row headers.
	 */
	protected void buildRowHeaders(Table table) throws BadElementException {
		Header[] headers = this._reportModel.getRowHeaders();
		int row = 2;
		String s = null;
		com.lowagie.text.Cell cell = null;
		for (int i = 0; i < headers.length; i++) {
			Header header = headers[i];
			Header[] children = header.getChildren();
			if (children == null) {
				int headerType = header.getHeaderType();
				if (headerType == Header.HEADERTYPE_ROW_SPACER) {
					s = " ";
				} else if (headerType == Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER
						|| header.getHeaderType() == Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL) {
					s = header.getLocalizationKey();
				} else {
					s = localize(header.getLocalizationKey(), header.getLocalizationKey());					
				}
				cell = new com.lowagie.text.Cell(new Phrase(s, this._boldFont));
				if (headerType == Header.HEADERTYPE_ROW_LABEL || headerType == Header.HEADERTYPE_ROW_SPACER) {
					cell.setColspan(this._reportModel.getColumnSize() + 1);
				}
				cell.setNoWrap(true);
				cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
				if (headerType == Header.HEADERTYPE_ROW_LABEL) {
					cell.setBackgroundColor(new java.awt.Color(0xe0, 0xe0, 0xe0));
				}
				table.addCell(cell, new Point(row, 0));
				setColSize(s, 0, false);
				row++;
			} else {
				if (header.getHeaderType() == Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER
						|| header.getHeaderType() == Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL) {
					s = header.getLocalizationKey();
				} else {
					s = localize(header.getLocalizationKey(), header.getLocalizationKey());					
				}
				cell = new com.lowagie.text.Cell(new Phrase(s, this._normalFont));
				cell.setColspan(this._reportModel.getColumnSize() + 1);
				cell.setLeading(16);
				table.addCell(cell, new Point(row, 0));
				row++;
				for (int j = 0; j < children.length; j++) {
					Header child = children[j];
					int headerType = child.getHeaderType();
					if (headerType == Header.HEADERTYPE_ROW_SPACER) {
						s = " ";
					} else if (headerType == Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER ||
							headerType == Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL) {
						s = child.getLocalizationKey();
					} else {
						s = localize(child.getLocalizationKey(), child.getLocalizationKey());					
					}
					cell = new com.lowagie.text.Cell(new Phrase(s, this._boldFont));
					if (headerType == Header.HEADERTYPE_ROW_LABEL || headerType == Header.HEADERTYPE_ROW_SPACER) {
						cell.setColspan(this._reportModel.getColumnSize() + 1);
					}
					cell.setNoWrap(true);
					cell.setVerticalAlignment(Element.ALIGN_MIDDLE); 
					if (headerType == Header.HEADERTYPE_ROW_LABEL) {
						cell.setBackgroundColor(new java.awt.Color(0xe0, 0xe0, 0xe0));
					}
					table.addCell(cell, row, 0);
					setColSize(s, 0, false);
					row++;
				}
			}
		}
	}

	/**
	 * Builds the report cells.
	 */
	protected void buildReportCells(Table table) throws BadElementException {
		int cellRow = 0;
		int tableRow = 2;
		Header[] rowHeaders = this._reportModel.getRowHeaders();
		NumberFormat formatter = NumberFormat.getNumberInstance();
		formatter.setMaximumFractionDigits(1);
		for (int i = 0; i < rowHeaders.length; i++) {
			int rowCount = 0;
			Header header = rowHeaders[i];
			Header[] children = header.getChildren();
			boolean hasChildren = false;
			if (children != null) {
				hasChildren = true;
				tableRow++;
				rowCount = children.length;
			} else {
				int headerType = header.getHeaderType();
				if (headerType == Header.HEADERTYPE_ROW_LABEL || 
						headerType == Header.HEADERTYPE_ROW_SPACER) {
					rowCount = 0;
					tableRow++;
				} else {
					rowCount = 1;
				}
			}
			for (int j = 0; j < rowCount; j++) {
				if (hasChildren) {
					Header child = children[j];
					int headerType = child.getHeaderType();
					if (headerType == Header.HEADERTYPE_ROW_LABEL || 
							headerType == Header.HEADERTYPE_ROW_SPACER) {
						tableRow++;
						continue;
					}
				}
				for (int cellColumn = 0; cellColumn < this._reportModel.getColumnSize(); cellColumn++) {
					Cell cell = this._reportModel.getCell(cellRow, cellColumn);
					int align = Element.ALIGN_RIGHT;
					Font font = this._normalFont;
					String s = null;
					
					switch (cell.getCellType()) {
						case Cell.CELLTYPE_PERCENT:
							s = formatter.format(cell.getFloatValue());
							break;
						case Cell.CELLTYPE_ROW_HEADER:
							s = cell.getStringValue();
							if (s.equals("&nbsp;")) {
								s = " ";
							}
							font = this._boldFont;
							align = Element.ALIGN_LEFT;
							break;
						case Cell.CELLTYPE_SUM:
							s = formatNumber(cell.getValue());
							font = this._boldFont;
							break;
						case Cell.CELLTYPE_TOTAL:
							s = formatNumber(cell.getValue());
							font = this._boldFont;
							break;
						default:
							s = formatNumber(cell.getValue());
							break;
					}
					int tableColumn = cellColumn + 1;
					com.lowagie.text.Cell pdfCell = new com.lowagie.text.Cell(new Phrase(s, font));
					pdfCell.setHorizontalAlignment(align);
					pdfCell.setNoWrap(true);
					pdfCell.setVerticalAlignment(Element.ALIGN_MIDDLE); 
					table.addCell(pdfCell, new Point(tableRow, tableColumn));
					setColSize(s, tableColumn, false);
				}
				cellRow++;
				tableRow++;
			}
		}
		this._reportModel.close();
	}

	/*
	 * Sets a column size.
	 */
	private void setColSize(String text, int column, boolean wrap) {
		String s = "";
		if (wrap) {
			StringTokenizer st = new StringTokenizer(text, " ");
			while (st.hasMoreTokens()) {
				String token = st.nextToken();
				int tlen = token.length();
				if (tlen > s.length()) {
					s = token;
				}
			}
		} else {
			s = text;
		}
		int len = s.length();
		if (this._widths[column] < len) {
			if (s.indexOf('m') != -1) {
				len++;
			}
			this._widths[column] = len;
		}
	}
	
	/*
	 * Returns a string with space for numbers larger than 999.
	 */
	String formatNumber(int n) {
		if (n == 0) {
			return " ";
		}
		String s = "" + n;
		int length = s.length();
		if (length > 3) {
			s = s.substring(0, (length - 3)) + " " + s.substring(length - 3);
		}
		return s;
	}
	
	/*
	 * Returns the localized text for the specified key.
	 */
	private String localize(String key, String defaultText) {
		return this._iwrb.getLocalizedString(key, defaultText);
	}
} public class ReportXLSWriter {

	private final static String REPORT_FOLDER_NAME = "School Report Files";

	Table _table = null;
	String _filename = null;
	String _reportTitle = null;
	
	/**
	 * Constructs a report XLS writer object.
	 * @param table the idegaWeb table containing the report
	 * @param reportTitle the title text for the report 
	 */	
	public ReportXLSWriter(Table table, String filename, String reportTitle) {
		this._table = table;
		this._filename = filename;
		this._reportTitle = reportTitle;
	}	
	
	/**
	 * Creates the PDF report file.
	 */
	public ICFile createFile() {
		ICFile reportFolder = null;
		ICFileHome fileHome = null;

		try {
			fileHome = (ICFileHome) com.idega.data.IDOLookup.getHome(ICFile.class);
			reportFolder = fileHome.findByFileName(REPORT_FOLDER_NAME);
		} catch (FinderException e) {
			try {
				ICFile root = fileHome.findByFileName(ICFileBMPBean.IC_ROOT_FOLDER_NAME);
				reportFolder = fileHome.create();
				reportFolder.setName(REPORT_FOLDER_NAME);
				reportFolder.setMimeType("application/vnd.iw-folder");
				reportFolder.store();
				root.addChild(reportFolder);
			} catch (Exception e2) {
				System.out.println(e2);
				return null;
			}
		} catch (IDOLookupException e) {
			System.out.println(e);
			return null;
		}

		ICFile exportFile = null;
				
		try {
			try {
				exportFile = fileHome.findByFileName(this._filename);
				if (exportFile != null) {
					exportFile.remove();
				}
			} catch (FinderException e) {}

			exportFile =  POIUtility.createICFileFromTable(this._table, this._filename, this._reportTitle);

			reportFolder.addChild(exportFile);
		} catch (Exception e) {
			System.out.println(e);
		}
		
		return exportFile;
	}
}
import java.rmi.RemoteException;
import se.idega.idegaweb.commune.presentation.CommuneBlock;
import se.idega.idegaweb.commune.school.report.business.NackaCC15HoursPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCC6YearPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCC7_9YearPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCCCommunePrivatePlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCCHourIntervalReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCCPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCCPreSchoolPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCCProviderReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCCTotalPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCitizenElementarySchoolPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCommuneHighSchoolPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCommuneHighSchoolStudyPathReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCompulsoryHighSchoolPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCompulsorySchoolOCCPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaCompulsorySchoolPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaElementarySchoolOCCPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaElementarySchoolPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaHighSchoolAgePlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaHighSchoolStudyPathPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaHighSchoolYearPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaPrivateHighSchoolPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaPrivateSchoolPlacementReportModel;
import se.idega.idegaweb.commune.school.report.business.NackaProviderSummaryReportModel;
import se.idega.idegaweb.commune.school.report.business.ReportBusiness;
import se.idega.idegaweb.commune.school.report.business.ReportModel;
import se.idega.idegaweb.commune.school.report.business.ReportPDFWriter;
import se.idega.idegaweb.commune.school.report.business.ReportXLSWriter;
import com.idega.core.file.data.ICFile;
import com.idega.presentation.ExceptionWrapper;
import com.idega.presentation.IWContext;
import com.idega.presentation.Table;
import com.idega.presentation.text.Break;
import com.idega.presentation.text.Link;
import com.idega.presentation.ui.DropdownMenu;
import com.idega.presentation.ui.Form;
import com.idega.presentation.ui.HiddenInput;
import com.idega.presentation.ui.SubmitButton;
import com.idega.repository.data.RefactorClassRegistry;
/*
 * $Id: SchoolReports.java,v 1.41 2006/05/08 13:53:38 laddi Exp $
 *
 * Copyright (C) 2003 Agura IT. All Rights Reserved.
 *
 * This software is the proprietary information of Agura IT AB.
 * Use is subject to license terms.
 *
 */
package se.idega.idegaweb.commune.school.report.presentation;




/**
 * This block handles selecting and presenting school reports.
 * <p>
 * Last modified: $Date: 2006/05/08 13:53:38 $ by $Author: laddi $
 *
 * @author Anders Lindman
 * @version $Revision: 1.41 $
 */
public class SchoolReports extends CommuneBlock {

	public final static String IW_REPORT_BUNDLE_IDENTIFIER = "se.idega.idegaweb.commune.school";

	private final static String PP = "school_report."; // Parameter prefix

	private final static String PARAMETER_REPORT_INDEX = PP + "report_index";
	private final static String PARAMETER_CREATE_REPORT = PP + "create_report";
	private final static String PARAMETER_CREATE_PDF = PP + "create_pdf";
	private final static String PARAMETER_CREATE_EXCEL = PP + "create_excel";
	private final static String PARAMETER_REPORT_CLASS_NAME = PP + "report_class_name";

	private final static String KP = "school_report."; // Localization key prefix

	private final static String KEY_REPORT_SELECTOR_TITLE = KP + "select_report";
	private final static String KEY_CREATE_REPORT = KP + "create_report";
	private final static String KEY_NO_REPORT_SELECTED = KP + "no_report_selected";
//	private final static String KEY_FOR_PRINTING = KP + "for_printing";
	private final static String KEY_PDF = KP + "pdf";
	private final static String KEY_EXCEL = KP + "excel";
	private final static String KEY_BACK = KP + "back";

	private final static int ACTION_DEFAULT = 1;
	private final static int ACTION_CREATE_REPORT = 2;
	private final static int ACTION_CREATE_PDF = 3;
	private final static int ACTION_CREATE_EXCEL = 4;

	private Class[] _reportModelClasses = {
				NackaCitizenElementarySchoolPlacementReportModel.class,
				NackaElementarySchoolPlacementReportModel.class,
				NackaElementarySchoolOCCPlacementReportModel.class,
				NackaCompulsorySchoolPlacementReportModel.class,
				NackaCompulsorySchoolOCCPlacementReportModel.class,
				NackaPrivateSchoolPlacementReportModel.class,
				NackaProviderSummaryReportModel.class
	};

	private Class[] _highSchoolReportModelClasses = {
				NackaHighSchoolYearPlacementReportModel.class,
				NackaHighSchoolAgePlacementReportModel.class,
				NackaCommuneHighSchoolPlacementReportModel.class,
				NackaCompulsoryHighSchoolPlacementReportModel.class,
				NackaPrivateHighSchoolPlacementReportModel.class,