Java tutorial
/* * Copyright (C) 2012 Picon software * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package fr.eoit.activity.fragment.manufacture; import android.database.Cursor; import android.database.MatrixCursor; import android.os.Bundle; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnKeyListener; import android.view.ViewGroup; import android.widget.EditText; import android.widget.TextView; import fr.eoit.EOITConst; import fr.eoit.R; import fr.eoit.activity.fragment.EnhancedMaterialListFragment; import fr.piconsoft.activity.fragment.LoaderFragment; import fr.eoit.activity.loader.BaseProductionNeedsLoader; import fr.eoit.activity.loader.BaseProductionNeedsLoader.OnLoadFinishedListener; import fr.eoit.activity.util.PricesUtils; import fr.eoit.bean.AsteroidItemBean; import fr.eoit.bean.ItemBeanWithMaterials; import fr.eoit.db.bean.Stock; import fr.eoit.formula.FormulaCalculator; import fr.eoit.parameter.Mining; import fr.eoit.parameter.Parameters; import fr.piconsoft.db.util.DbUtil; import fr.eoit.util.Formatter; import fr.eoit.util.SparseItemBeanArray; import fr.eoit.util.manufacture.ManufactureUtils; import fr.piconsoft.db.util.InClauseQueryBuilder; import java.util.*; /** * @author picon.software * */ public class ProductionPlanFragment extends LoaderFragment<Cursor> implements OnLoadFinishedListener { private final static int BASE_PRODUCTION_NEEDS_LOADER_ID = EOITConst.getNextLoaderIdSequence(); private TextView totalPriceTextView = null; private TextView totalTimeTextView = null; private double sellPrice; private double producePrice; private int baseProductionTime; private int unitPerBatch; private int itemId; private int currentNumberOfRuns = 1; private SparseItemBeanArray baseProductionNeedItemMap = null, productionNeeds, remainingProductionNeedsItems, stockItems = new SparseItemBeanArray(); private Set<Integer> ids = new TreeSet<Integer>(); private EnhancedMaterialListFragment[] stepsFragments = new EnhancedMaterialListFragment[6]; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View fragment = inflater.inflate(R.layout.manufacture_production_plan, container, false); Mining.loadMiningData(getActivity(), Mining.ONLY_BASIC_ASTEROIDS); Bundle args = getArguments(); itemId = args.getInt("itemId", 0); sellPrice = args.getDouble("sellPrice", 0); producePrice = args.getDouble("producePrice", 0); unitPerBatch = args.getInt("unitPerBatch", 0); baseProductionTime = args.getInt("productionTime", 0); int categorieId = args.getInt("categorieId"); TextView runsTextView = (TextView) fragment.findViewById(R.id.RUNS); runsTextView.setOnKeyListener(new RunsListener()); runsTextView.setText("1"); totalPriceTextView = (TextView) fragment.findViewById(R.id.TOTAL_PROFIT_VALUE); totalTimeTextView = (TextView) fragment.findViewById(R.id.TOTAL_TIME_VALUE); stepsFragments[0] = (EnhancedMaterialListFragment) getFragmentManager() .findFragmentById(R.id.PRODUCTION_STEP0); stepsFragments[1] = (EnhancedMaterialListFragment) getFragmentManager() .findFragmentById(R.id.PRODUCTION_STEP1); stepsFragments[2] = (EnhancedMaterialListFragment) getFragmentManager() .findFragmentById(R.id.PRODUCTION_STEP2); stepsFragments[3] = (EnhancedMaterialListFragment) getFragmentManager() .findFragmentById(R.id.PRODUCTION_STEP3); stepsFragments[4] = (EnhancedMaterialListFragment) getFragmentManager() .findFragmentById(R.id.PRODUCTION_STEP4); stepsFragments[5] = (EnhancedMaterialListFragment) getFragmentManager() .findFragmentById(R.id.PRODUCTION_STEP5); stepsFragments[0].getView().setVisibility(View.GONE); stepsFragments[1].getView().setVisibility(View.GONE); stepsFragments[2].getView().setVisibility(View.GONE); stepsFragments[3].getView().setVisibility(View.GONE); stepsFragments[4].getView().setVisibility(View.GONE); stepsFragments[5].getView().setVisibility(View.GONE); getLoaderManager().initLoader(BASE_PRODUCTION_NEEDS_LOADER_ID, null, new BaseProductionNeedsLoader.BaseProductionNeedsLoaderCallBacks(getActivity(), this, itemId, categorieId)); return fragment; } @Override public void onLoadFinishedBaseProductionNeeds(int itemId, SparseItemBeanArray data) { this.baseProductionNeedItemMap = data; if (baseProductionNeedItemMap != null) { ids.clear(); for (ItemBeanWithMaterials item : baseProductionNeedItemMap.values()) { ids.addAll(ManufactureUtils.getIds(item)); } } initOrRestart(); } @Override public Loader<Cursor> getCursorLoader(int id, Bundle args) { stockItems.clear(); return new CursorLoader(getActivity(), Stock.CONTENT_URI, new String[] { Stock._ID, Stock.COLUMN_NAME_ITEM_ID, Stock.COLUMN_NAME_QUANTITY }, InClauseQueryBuilder.buildInClause(Stock.COLUMN_NAME_ITEM_ID, ids), null, Stock.COLUMN_NAME_ITEM_ID + " ASC"); } @Override public void onLoadFinished(Cursor cursor) { if (DbUtil.hasAtLeastOneRow(cursor)) { while (!cursor.isAfterLast()) { int id = cursor.getInt(cursor.getColumnIndexOrThrow(Stock.COLUMN_NAME_ITEM_ID)); long quantity = cursor.getLong(cursor.getColumnIndexOrThrow(Stock.COLUMN_NAME_QUANTITY)); ItemBeanWithMaterials item = new ItemBeanWithMaterials(); item.id = id; item.quantity = quantity; stockItems.include(item); cursor.moveToNext(); } } productionNeeds = ManufactureUtils.getProductionNeeds(baseProductionNeedItemMap, stockItems, currentNumberOfRuns); remainingProductionNeedsItems = new SparseItemBeanArray(productionNeeds); List<ProductionStep> steps = new ArrayList<ProductionStep>(); ProductionStep miningSteps; if (Parameters.isMiningActive) { miningSteps = getMiningStep(); if (!miningSteps.isEmpty()) steps.add(miningSteps); } ProductionStep shoppingSteps = getShoppingStep(); if (!shoppingSteps.isEmpty()) steps.add(shoppingSteps); steps.addAll(findSteps()); int index = 0; for (EnhancedMaterialListFragment fragment : stepsFragments) { if (steps.size() > index) { fragment.initialize(steps.get(index)); } else { fragment.getView().setVisibility(View.GONE); } index++; } updateProductionInfos(currentNumberOfRuns); } @Override public void onLoaderReset(Loader<Cursor> loader) { } private List<ProductionStep> findSteps() { List<MatrixCursor> steps = new ArrayList<MatrixCursor>(); SparseItemBeanArray nextStepItems = new SparseItemBeanArray(); int unitPerBatch = getArguments().getInt("unitPerBatch", 0); steps.add(getCursor(itemId, getArguments().getString("itemName"), currentNumberOfRuns * unitPerBatch, getArguments().getDouble("volume"), sellPrice)); if (baseProductionNeedItemMap != null) { SparseItemBeanArray currentStepItems = new SparseItemBeanArray(); SparseItemBeanArray currentStepItemsToConvert = new SparseItemBeanArray(); nextStepItems.putAll(baseProductionNeedItemMap.multiply(currentNumberOfRuns)); do { MatrixCursor currentStep = EnhancedMaterialListFragment.getEmptyCursor(); currentStepItems.clear(); currentStepItemsToConvert.clear(); currentStepItems.putAll(nextStepItems); nextStepItems.clear(); for (ItemBeanWithMaterials item : currentStepItems.values()) { if (item.materials != null && !item.materials.isEmpty()) { currentStepItemsToConvert = currentStepItemsToConvert.union(item); nextStepItems.putAll(item.materials); } } currentStepItemsToConvert = currentStepItemsToConvert.exclude(stockItems); for (ItemBeanWithMaterials item : currentStepItemsToConvert.values()) { EnhancedMaterialListFragment.addRowToMatrixCursor(currentStep, item); } if (!currentStepItemsToConvert.isEmpty()) { steps.add(currentStep); } } while (!nextStepItems.isEmpty()); Collections.reverse(steps); } List<ProductionStep> prodSteps = new ArrayList<ProductionStep>(); int cpt = 1; for (MatrixCursor step : steps) { prodSteps.add(new ProductionStep("STEP " + cpt + " : PRODUCE", step)); cpt++; } return prodSteps; } private ProductionStep getMiningStep() { MatrixCursor miningStep = EnhancedMaterialListFragment.getEmptyCursor(); SparseItemBeanArray miningStepItemsToConvert = new SparseItemBeanArray(); SparseItemBeanArray requiredMinerals = new SparseItemBeanArray(); for (ItemBeanWithMaterials item : productionNeeds.values()) { if (item.isMineral()) { requiredMinerals.append(item); } } for (int i = EOITConst.Items.MINERAL_IDS.length - 1; i >= 0; i--) { ItemBeanWithMaterials requiredMineral = requiredMinerals.get(EOITConst.Items.MINERAL_IDS[i]); if (requiredMineral != null) { AsteroidItemBean requiredAsteroid = Mining.getMatchingAsteroid(requiredMineral); if (requiredAsteroid != null) { miningStepItemsToConvert.append(requiredAsteroid); SparseItemBeanArray itemToRemove = requiredAsteroid.materials .multiply(requiredAsteroid.quantity); requiredMinerals = requiredMinerals.exclude(itemToRemove); remainingProductionNeedsItems = remainingProductionNeedsItems.exclude(itemToRemove); } } } for (ItemBeanWithMaterials item : miningStepItemsToConvert.values()) { EnhancedMaterialListFragment.addRowToMatrixCursor(miningStep, item); } return new ProductionStep("MINE", miningStep); } private ProductionStep getShoppingStep() { MatrixCursor shoppingStep = EnhancedMaterialListFragment.getEmptyCursor(); for (ItemBeanWithMaterials item : remainingProductionNeedsItems.values()) { EnhancedMaterialListFragment.addRowToMatrixCursor(shoppingStep, item); } return new ProductionStep("SHOPPING", shoppingStep); } private static MatrixCursor getCursor(final int itemId, final String itemName, final long itemQuantity, final double volume, final double sellPrice) { MatrixCursor cursor = EnhancedMaterialListFragment.getEmptyCursor(); double itemSellPrice = sellPrice > 0 ? sellPrice : 0; DbUtil.addRowToMatrixCursor(cursor, itemId, itemName, itemQuantity, volume, EOITConst.SELL_PRICE_ID, itemSellPrice, itemSellPrice, itemSellPrice, itemSellPrice); return cursor; } private void updateProductionInfos(int numberOfRuns) { int pl = getArguments().getInt("pl", 0); int productivityModifier = getArguments().getInt("productivityModifier", 0); double productionTime = FormulaCalculator.calculateProductionTime(baseProductionTime, productivityModifier, pl); double sellpriceTotal = sellPrice * unitPerBatch * numberOfRuns; double productionPriceTotal = producePrice * unitPerBatch * numberOfRuns; double productionTimeTotal = productionTime * numberOfRuns; totalPriceTextView .setText(PricesUtils.formatPrice(sellpriceTotal - productionPriceTotal, getActivity(), true)); totalTimeTextView.setText(Formatter.formatTime(productionTimeTotal)); } public class RunsListener implements OnKeyListener { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if ((keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9 || keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DEL) && event.getAction() == KeyEvent.ACTION_UP) { String editTextStr = ((EditText) v).getText().toString(); if (editTextStr.length() != 0) { currentNumberOfRuns = Integer.parseInt(editTextStr); updateProductionInfos(currentNumberOfRuns); restartLoader(); } return false; } return false; } } public static class ProductionStep { private String stepTitle; private MatrixCursor stepElements; public ProductionStep(String stepTitle, MatrixCursor stepElements) { super(); this.stepTitle = stepTitle; this.stepElements = stepElements; } /** * @return the stepTitle */ public String getStepTitle() { return stepTitle; } /** * @return the stepElements */ public MatrixCursor getStepElements() { return stepElements; } public boolean isEmpty() { return stepElements.getCount() == 0; } } }