package model.gammeOperatoire;

import java.util.Arrays;
import java.util.Vector;

import controller.GestionCommande;

import model.article.Article;
import model.posteCharge.PosteCharge;


/**
 * Operation heritee Activite
 * @author Magic Penguins
 * @see Activite
 */
public class Operation extends Activite {

	private static final long serialVersionUID = 455426452332997783L;
	/**
	 * Article concerne par l'operation
	 */
	protected Article cible;
	/**
	 * True pour une operation d'assemblage, false pour une operation de fabrication
	 */
	protected boolean assemblage;
	/**
	 * Poste concerne par l'operation
	 */
	protected PosteCharge poste;
	/**
	 * Quantite d'article(s) produit(s) par operation
	 */
	protected int nbCible;
	protected static String[] strNom = {"Fabrication", "Assemblage"};
	static String[] str = {"Quantite", "Assemblage", "Produit", "Poste"}; 
	
	/**
	 * Constructeur d'une operation
	 * @param duree
	 * Duree de l'operation
	 * @param cible
	 * Article concerne par l'operation
	 * @param poste
	 * Poste concerne par l'operation
	 * @param nbCible
	 * Quantite d'article(s) produit(s) par operation
	 * @param assemblage
	 * True pour une operation d'assemblage, false pour une operation de fabrication
	 */
	public Operation(int duree, Article cible, PosteCharge poste, int nbCible, boolean assemblage) {
		super(duree, strNom[(assemblage? 1:0)]+" ("+cible.getDesignation()+")", new Vector<String>(Arrays.asList(str)));

		this.cible=cible;
		this.poste=poste;
		this.nbCible=nbCible;
		this.assemblage=assemblage;
	}

	public Article getCible() {
		return cible;
	}

	public boolean isAssemblage() {
		return assemblage;
	}

	public PosteCharge getPoste() {
		return poste;
	}

	public int getNbCible() {
		return nbCible;
	}
	
	@Override
	public void set(Vector<Object> source){
		this.nom= (String)source.get(param.indexOf(baseStr[0]));
		this.duree=Integer.parseInt((String)(source.get(param.indexOf(baseStr[1]))));
		this.nbCible=Integer.parseInt((String)(source.get(param.indexOf(str[0]))));
		this.assemblage=(Boolean)(source.get(param.indexOf(str[1])));
		this.cible=(Article)(source.get(param.indexOf(str[2])));
		this.poste=(PosteCharge)(source.get(param.indexOf(str[3])));
	}
	
	/**
	 * Getters des attributs
	 */
	@Override
	public Object get(int i){
		switch(i) {
		case 0 	: 	return nom;
		case 1 	:	return duree;
		case 2	: 	return nbCible;
		case 3	:	return assemblage;
		case 4	:	return cible;
		case 5	:	return poste;
		default	:	return null;
		}
	}
	
	/**
	 * Calcule la duree de l'operation de maniere deterministe
	 * Si le stock des composants de l'article cible est insuffisante, on calculera la duree de production de ces composants recursivement
	 * @return La duree deterministe de l'operation
	 */
	public int duree(){
		int tmpDuree = 0;
		for (int i=0;i<cible.getNomenclature().size();i++){
			if (cible.getNomenclature().get(i).getArticle().getStock()<cible.getNomenclature().get(i).getQuantite()){
				if (cible.getNomenclature().get(i).getArticle().getGamme()==null || !assemblage){
					tmpDuree += cible.getNomenclature().get(i).getQuantite()*cible.getNomenclature().get(i).getArticle().getDelai();
					GestionCommande.ajouterRupture(cible.getNomenclature().get(i).getArticle());
				}
				else{
					tmpDuree += cible.getNomenclature().get(i).getQuantite()*cible.getNomenclature().get(i).getArticle().getGamme().calculerDuree();
				}
			}
		}
		return tmpDuree;
	}
}
