fr.eoit.parameter.Mining.java Source code

Java tutorial

Introduction

Here is the source code for fr.eoit.parameter.Mining.java

Source

/*
 * Copyright (C) 2013 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.parameter;

import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.util.Log;
import android.util.SparseArray;
import fr.eoit.EOITConst;
import fr.eoit.bean.AsteroidItemBean;
import fr.eoit.bean.ItemBean;
import fr.eoit.bean.ItemBeanWithMaterials;
import fr.eoit.db.bean.Groups;
import fr.eoit.db.bean.Item;
import fr.eoit.db.bean.ItemMaterials;
import fr.eoit.formula.FormulaCalculator;
import fr.eoit.util.SparseItemBeanArray;
import fr.piconsoft.db.util.DbUtil;
import fr.piconsoft.db.util.InClauseQueryBuilder;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

/**
 * @author picon.software
 *
 */
public final class Mining implements LoaderCallbacks<Cursor> {

    private final static int LOADER_ID = EOITConst.getNextLoaderIdSequence();
    private final static String LOG_TAG = Mining.class.getSimpleName();

    public static final int FULL_LOADING = 0;
    public static final int ONLY_BASIC_ASTEROIDS = 1;

    private static int currentMode = -1;
    private static Context context;
    private static SparseArray<TreeSet<ItemBeanWithMaterials>> asteroidMap;
    private static SparseItemBeanArray asteroids = new SparseItemBeanArray();

    private Mining() {
    }

    public static void loadMiningData(FragmentActivity pActivity, int mode) {
        if (asteroidMap == null || currentMode != mode) {
            context = pActivity.getApplicationContext();
            currentMode = mode;
            pActivity.getSupportLoaderManager().initLoader(LOADER_ID, null, new Mining());
        }
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        if (id == LOADER_ID) {
            Log.d(LOG_TAG, "Starting cursorloader...");

            String whereClause = "";

            if (currentMode == FULL_LOADING) {
                whereClause = "g." + Groups.COLUMN_NAME_CATEGORIE_ID + " = "
                        + EOITConst.Categories.ASTEROID_CATEGORIE_ID;
            } else if (currentMode == ONLY_BASIC_ASTEROIDS) {
                whereClause = InClauseQueryBuilder.buildInClause("i." + Item._ID, EOITConst.Items.ARKONOR,
                        EOITConst.Items.BISTOT, EOITConst.Items.CROKITE, EOITConst.Items.DARK_OCHRE,
                        EOITConst.Items.GNEISS, EOITConst.Items.HEDBERGITE, EOITConst.Items.HEMORPHITE,
                        EOITConst.Items.JASPET, EOITConst.Items.KERNITE, EOITConst.Items.MERCOXIT,
                        EOITConst.Items.OMBER, EOITConst.Items.PLAGIOCLASE, EOITConst.Items.PYROXERES,
                        EOITConst.Items.SCORDITE, EOITConst.Items.SPODUMAIN, EOITConst.Items.VELDSPAR);
            }

            return new CursorLoader(context, ItemMaterials.CONTENT_URI_REFINE,
                    new String[] { Item._ID, ItemMaterials.COLUMN_NAME_MATERIAL_ITEM_ID,
                            ItemMaterials.COLUMN_NAME_QUANTITY, Item.COLUMN_NAME_NAME, Item.COLUMN_NAME_VOLUME,
                            Item.COLUMN_NAME_PORTION_SIZE, Item.COLUMN_NAME_GROUP_ID },
                    whereClause, null, null);
        }
        return null;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        if (DbUtil.hasAtLeastOneRow(cursor) && loader.getId() == LOADER_ID) {

            Log.d(LOG_TAG, "Reading cursor...");

            while (!cursor.isAfterLast()) {
                AsteroidItemBean item = getItem(cursor);
                ItemBeanWithMaterials mineral = new ItemBeanWithMaterials();
                mineral.id = cursor
                        .getInt(cursor.getColumnIndexOrThrow(ItemMaterials.COLUMN_NAME_MATERIAL_ITEM_ID));
                mineral.quantity = cursor.getInt(cursor.getColumnIndexOrThrow(ItemMaterials.COLUMN_NAME_QUANTITY));

                if (asteroids.containsKey(item.id)) {
                    ((AsteroidItemBean) asteroids.get(item.id)).addMineral(mineral);
                } else {
                    asteroids.append(item);
                    item.addMineral(mineral);
                }

                cursor.moveToNext();
            }

            asteroidMap = new SparseArray<TreeSet<ItemBeanWithMaterials>>();
            asteroidMap.append(EOITConst.Items.TRITANIUM,
                    new TreeSet<ItemBeanWithMaterials>(new AsteroidMineralComparator(EOITConst.Items.TRITANIUM)));
            asteroidMap.append(EOITConst.Items.PYERITE,
                    new TreeSet<ItemBeanWithMaterials>(new AsteroidMineralComparator(EOITConst.Items.PYERITE)));
            asteroidMap.append(EOITConst.Items.MEXALLON,
                    new TreeSet<ItemBeanWithMaterials>(new AsteroidMineralComparator(EOITConst.Items.MEXALLON)));
            asteroidMap.append(EOITConst.Items.ISOGEN,
                    new TreeSet<ItemBeanWithMaterials>(new AsteroidMineralComparator(EOITConst.Items.ISOGEN)));
            asteroidMap.append(EOITConst.Items.NOCXIUM,
                    new TreeSet<ItemBeanWithMaterials>(new AsteroidMineralComparator(EOITConst.Items.NOCXIUM)));
            asteroidMap.append(EOITConst.Items.ZYDRINE,
                    new TreeSet<ItemBeanWithMaterials>(new AsteroidMineralComparator(EOITConst.Items.ZYDRINE)));
            asteroidMap.append(EOITConst.Items.MEGACYTE,
                    new TreeSet<ItemBeanWithMaterials>(new AsteroidMineralComparator(EOITConst.Items.MEGACYTE)));
            asteroidMap.append(EOITConst.Items.MORPHITE,
                    new TreeSet<ItemBeanWithMaterials>(new AsteroidMineralComparator(EOITConst.Items.MORPHITE)));

            asteroids.populateSet(asteroidMap.get(EOITConst.Items.TRITANIUM));
            asteroids.populateSet(asteroidMap.get(EOITConst.Items.PYERITE));
            asteroids.populateSet(asteroidMap.get(EOITConst.Items.MEXALLON));
            asteroids.populateSet(asteroidMap.get(EOITConst.Items.ISOGEN));
            asteroids.populateSet(asteroidMap.get(EOITConst.Items.NOCXIUM));
            asteroids.populateSet(asteroidMap.get(EOITConst.Items.ZYDRINE));
            asteroids.populateSet(asteroidMap.get(EOITConst.Items.MEGACYTE));
            asteroids.populateSet(asteroidMap.get(EOITConst.Items.MORPHITE));

            Log.d(LOG_TAG, "Finish reading cursor...");
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
    }

    private static AsteroidItemBean getItem(Cursor cursor) {
        AsteroidItemBean item = new AsteroidItemBean();

        item.id = cursor.getInt(cursor.getColumnIndexOrThrow(ItemMaterials._ID));
        item.name = cursor.getString(cursor.getColumnIndexOrThrow(Item.COLUMN_NAME_NAME));
        item.batchSize = cursor.getInt(cursor.getColumnIndexOrThrow(Item.COLUMN_NAME_PORTION_SIZE));
        item.volume = cursor.getDouble(cursor.getColumnIndexOrThrow(Item.COLUMN_NAME_VOLUME));
        item.groupId = cursor.getInt(cursor.getColumnIndexOrThrow(Item.COLUMN_NAME_GROUP_ID));

        return item;
    }

    public static AsteroidItemBean getMatchingAsteroid(ItemBean requiredMineral) {
        SparseItemBeanArray asteroidsForRequiredMineral = new SparseItemBeanArray(
                asteroidMap.get(requiredMineral.id));
        SparseItemBeanArray restrictedAsteroidsForRequiredMineral = new SparseItemBeanArray();

        List<Integer> asteroidIdList = new ArrayList<Integer>();
        for (int id : getAsteroidIds()) {
            asteroidIdList.add(id);
        }

        for (ItemBeanWithMaterials asteroid : asteroidsForRequiredMineral.values()) {
            if (asteroidIdList.contains(asteroid.id)) {
                restrictedAsteroidsForRequiredMineral.append(asteroid);
            }
        }

        if (restrictedAsteroidsForRequiredMineral.isEmpty()) {
            return null;
        }
        AsteroidItemBean asteroidItemBean = (AsteroidItemBean) restrictedAsteroidsForRequiredMineral.valueAt(0)
                .clone();

        if (!asteroidItemBean.containsMineral(requiredMineral.id)
                && restrictedAsteroidsForRequiredMineral.size() > 1) {
            asteroidItemBean = (AsteroidItemBean) restrictedAsteroidsForRequiredMineral.valueAt(1).clone();
        } else if (!asteroidItemBean.containsMineral(requiredMineral.id)) {
            return null;
        }

        long refinedMineralQuantity = asteroidItemBean.getMineral(requiredMineral.id).quantity;

        long effectiveRefinedMineralQuantity = refinedMineralQuantity
                - FormulaCalculator.calculateRefiningWaste(refinedMineralQuantity, asteroidItemBean.groupId)
                - FormulaCalculator.calculateReprocessStationTake(refinedMineralQuantity);

        asteroidItemBean.quantity = (long) ((Math.floor(requiredMineral.quantity / effectiveRefinedMineralQuantity)
                + 1) * asteroidItemBean.batchSize);

        return asteroidItemBean;
    }

    public static SparseItemBeanArray reprocess(SparseItemBeanArray asteroidsToReprocess) {

        SparseItemBeanArray minerals = new SparseItemBeanArray();

        for (ItemBeanWithMaterials asteroidToReprocess : asteroidsToReprocess.values()) {
            AsteroidItemBean asteroid = (AsteroidItemBean) asteroids.get(asteroidToReprocess.id);

            // in the case of asteroid that can't be reprocessed.
            if (asteroid == null) {
                return minerals;
            }

            int numberOfPossibleReprocessBatch = (int) Math
                    .floor(asteroidToReprocess.quantity / asteroid.batchSize);

            for (ItemBeanWithMaterials mineral : asteroid.materials.values()) {
                long refinedMineralQuantity = mineral.quantity;

                long effectiveRefinedMineralQuantity = refinedMineralQuantity
                        - FormulaCalculator.calculateRefiningWaste(refinedMineralQuantity, asteroid.groupId)
                        - FormulaCalculator.calculateReprocessStationTake(refinedMineralQuantity);

                ItemBeanWithMaterials refinedMineral = mineral.clone();
                refinedMineral.quantity = effectiveRefinedMineralQuantity * numberOfPossibleReprocessBatch;

                minerals.include(refinedMineral);
            }
        }

        return minerals;
    }

    private static int[] getAsteroidIds() {
        int securityStatusIndex = (int) (Parameters.securityStatus * 10);

        switch (Parameters.territory) {
        case EOITConst.Territories.AMARR_SPACE:
            return EOITConst.Asteroid.DISTRIBUTION_IN_AMARR_SPACE[securityStatusIndex];

        case EOITConst.Territories.CALDARI_SPACE:
            return EOITConst.Asteroid.DISTRIBUTION_IN_CALDARI_SPACE[securityStatusIndex];

        case EOITConst.Territories.GALLENTE_SPACE:
            return EOITConst.Asteroid.DISTRIBUTION_IN_GALLENTE_SPACE[securityStatusIndex];

        case EOITConst.Territories.MINMATAR_SPACE:
            return EOITConst.Asteroid.DISTRIBUTION_IN_MINMATAR_SPACE[securityStatusIndex];

        default:
            return null;
        }
    }

    private class AsteroidMineralComparator implements Comparator<ItemBeanWithMaterials> {

        private int mineralId;

        public AsteroidMineralComparator(int mineralId) {
            this.mineralId = mineralId;
        }

        @Override
        public int compare(ItemBeanWithMaterials lhs, ItemBeanWithMaterials rhs) {

            double lhsQuantity, rhsQuantity;

            if (lhs.materials.containsKey(mineralId)) {
                lhsQuantity = lhs.materials.get(mineralId).quantity / lhs.volume;
            } else {
                lhsQuantity = -1;
            }
            if (rhs.materials.containsKey(mineralId)) {
                rhsQuantity = rhs.materials.get(mineralId).quantity / rhs.volume;
            } else {
                rhsQuantity = -1;
            }

            return lhsQuantity > rhsQuantity ? -1 : (lhsQuantity == rhsQuantity ? 0 : 1);
        }
    }
}