fr.eoit.activity.fragment.manufacture.ProductionPlanFragment.java Source code

Java tutorial

Introduction

Here is the source code for fr.eoit.activity.fragment.manufacture.ProductionPlanFragment.java

Source

/*
 * 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;
        }
    }
}