/* Generated by Together */
package manufacturingplant.assemblylineplant;
import java.util.Vector;
import java.util.Map;
import manufacturingplant.Warehouse;
import manufacturingplant.ManufacturingPlant;
import manufacturingplant.Part;
import manufacturingplant.Product;
import java.util.HashMap;
public class AssemblyLinePlant extends ManufacturingPlant {
/**
* Maakt een nieuwe Assembly Line Plant.
* @require lines >= 1
* @ensure this.getLineCount() == lines
*/
public AssemblyLinePlant(int lines, int bins) {
super(bins);
this.assemblyLines = new AssemblyLine[lines];
for (int i = 0; i < this.assemblyLines.length; i++){
this.assemblyLines[i] = new AssemblyLine(this);
}
this.lineTargets = new HashMap();
}
/**
* Geeft het aantal assembly lines in deze plant.
* @ensure result >= 1
*/
public int getLineCount() {
return this.assemblyLines.length;
}
/**
* Geeft aan of de gegeven assembly-opdracht uitgevoerd kan worden.
* @require steps.length == sourceBinsPerStep.length == sourceCountPerStep
* @require voor alle step in sourceBinsPerStep,
* corresponderende cstep in sourceCountPerStep:
* step.length = cstep.length
* @require voor alle [step][bininstep] in sourceBinsPerStep: bininstep >= 1 && bininstep <= warehouse.getBinCount()
* @require voor alle [cstep][countinstep] in sourceBinsPerStep: countinstep >= 1
* @return true als de opdracht uitgevoerd kan worden, anders false
*/
public boolean canAssemble(int productCount, AssemblyLineStep[] steps, int[][] sourceBinsPerStep, int[][] sourceCountPerStep) {
// kan tot tegenspraak assemblen..
boolean canAssemble = true;
// is er een line vrij?
int freeLine = this.findFreeAssemblyLine();
if (freeLine != -1) { // vrije gevonden
if (this.obtainParts(false, productCount, sourceBinsPerStep, sourceCountPerStep) != null) {
// kan nog steeds maken
// FUTURE: meer voorwaarden hier invoegen
} else {
canAssemble = false;
}
} else {
canAssemble = false;
}
return canAssemble;
}
/**
* @return -1 indien geen beschikbaar, 0 <= i < this.assemblyLines.length is wel beschikbaar
*/
private int findFreeAssemblyLine() {
for (int i = 0; i < this.assemblyLines.length; i++) {
if (!this.assemblyLines[i].isBusy()) { // vrije gevonden
return i;
}
}
return -1;
}
/**
* Geeft aan of de producten opgehaald kunnen worden (!doGet) of haalt
* ze daadwerkelijk op (doGet).
* @return indien doGet: Part[productnr][stepnr][bin_i] als array van Parts
* @return indien !doGet: null indien niet gemaakt kan worden, != null indien wel gemaakt kan worden
*/
private Part[][][][] obtainParts(boolean doGet, int count, int[][] binsPerStep, int[][]countsPerStep) {
// onderdelen..
Vector usedBins = new Vector();
for (int iStep = 0; iStep < binsPerStep.length; iStep++) {
for (int j = 0; j < binsPerStep[iStep].length; j++) {
Integer binNum = new Integer(binsPerStep[iStep][j]);
if (!usedBins.contains(binNum)) {
usedBins.add(binNum);
}
}
}
// je hebt nu een lijst bins die je gebruikt..
int[] arrUsedBins = new int[usedBins.size()];
int[] arrBinUsage = new int[usedBins.size()];
for (int k = 0; k < usedBins.size(); k++) {
Object o = usedBins.get

;
if (o instanceof Integer) {
arrUsedBins[k] = (int)(Integer)o;
}
}
// vullen met counts..
for (int lStep = 0; lStep < countsPerStep.length; lStep++) {
for (int m = 0; m < countsPerStep[lStep].length; m++) {
Integer binNum = new Integer(binsPerStep[lStep][m]);
// nou, hier gebeurt het echte telwerk:
arrBinUsage[ usedBins.indexOf(binNum) ] += count * countsPerStep[lStep][m];
}
}
Warehouse w = this.getWarehouse();
if (!doGet) { // alleen kijken
// delegeren richting Warehouse
if (w.canGetFromBins(arrUsedBins, arrBinUsage)) {
// kan nog steeds maken
return new Part[1][][][]; // als het maar geen null is
} else {
return null;
}
} else {
// ophalen en verwerken
Part[][] parts = w.getFromBins(arrUsedBins, arrBinUsage);
// houdt bij welke onderdelen uit parts[][] opgebruikt zijn..
int[] usedParts = new int[parts.length];
for (int n = 0; n <usedParts.length; n++) {
usedParts[n] = 0;
}
// klaar! nu alleen nog even uitdelen..
Part[][][][] retParts;
retParts = new Part[count][][][];
for (int i = 0; i < count; i++) {
retParts[i] = new Part[binsPerStep.length][][]; // dat is dus het aantal stappen
for (int j = 0; j < binsPerStep.length; j++) {
retParts[i][j] = new Part[binsPerStep[j].length][]; // dat is het aantal bins per stap
for (int k = 0; k < binsPerStep[j].length; k++) {
retParts[i][j][k] = new Part[countsPerStep[j][k]]; // dat is het aantal onderdelen per bin per stap
// vullen maar!
for (int l = 0; l < countsPerStep[j][k]; l++){
Integer sourceBin = new Integer( binsPerStep[j][k] ); // stap j, binindex k
int sourceBinWhI = usedBins.indexOf(sourceBin);
retParts[i][j][k][l] = parts[ sourceBinWhI ][usedParts[sourceBinWhI]++];
}
}
}
}
return retParts;
}
}
/**
* Maakt een productCount aantal producten.
* @require canAssemble(productCount, steps, sourceBinsPerStep, sourceCountPerStep)
* @require 1 <= targetBin <= warehouse.getBinCount()
* @ensure er zijn productCount producten in targetBin gelegd
*/
public void doAssemble(String productName, int targetBin, int productCount, AssemblyLineStep[] steps, int[][] sourceBinsPerStep, int[][] sourceCountPerStep) {
Part[][][][] parts = obtainParts(true, productCount, sourceBinsPerStep, sourceCountPerStep);
int assemblyLineI = this.findFreeAssemblyLine();
// die is vrij, preconditie
AssemblyLine assemblyLine = this.assemblyLines[assemblyLineI];
this.lineTargets.put(assemblyLine, new Integer(targetBin)); // "terugvinden"
assemblyLine.doAssemble(productName, productCount, steps, parts);
}
/**
* Map die bijhoudt in welk bakje de resultaten van
* een bepaalde assembly line gegooid moeten worden
*/
private Map lineTargets;
/**
* Interne functie die kijkt in welke bin het resultaat van
* een assembly gedaan moet worden
*/
private int getResultBin(AssemblyLine line) {
Object o = this.lineTargets.get(line);
if (o instanceof Integer)
return (int)(Integer)o;
else
return -1;
}
/**
* Intern aan te roepen als er een product afgeleverd wordt.
*/
protected void deliverProduct(AssemblyLine source, Product p) {
// stop netjes in juiste warehouse
Warehouse w = this.getWarehouse();
int[] bins = new int[1];
Part[][] parts = new Part[1][];
parts[0] = new Part[1];
parts[0][0] = p;
bins[0] = this.getResultBin(source);
w.addToBins(bins, parts);
//System.err.println("DBG: deliver aan " + bins[0]);
}
/**
* Geeft het aantal bins van het warenhuis.
* @ensure result == this.getWarehouse().getBinCount()
* @ensure result >= 1
*/
public int getBinCount() {
return this.getWarehouse().getBinCount();
}
/**
* @li dsafds nk aggregation
*/
//private Warehouse lnkMagazijn; //wordt reeds ge-erfd?
/**
* @link aggregationByValue
* @label heeft
* @undirected
* @clientCardinality 1*/
private AssemblyLine[] assemblyLines;
}