/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ucp.model;

import java.util.ArrayList;
import ucp.plan.UcpAlgorithm;

/**
 * Class represents UML Package.
 * 
 * @author Trifolium Alpestre
 */
public class UcpPackage {

private ArrayList<UcpPackage> pList = new ArrayList<UcpPackage>();
private ArrayList<UcpUseCase> uList = new ArrayList<UcpUseCase>();
private ArrayList<UcpActor> aList = new ArrayList<UcpActor>();
private UcpMetrics metrics = new UcpMetrics();
private String name;
private String id;

/**
 * 
 * @return
 */
public String getName() {
        return name;
    }

    /**
     * 
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 
     * @return
     */
    public String getId() {
        return id;
    }

    /**
     * 
     * @param id
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * 
     * @param ucpPackage
     */
    public void addPackage(UcpPackage ucpPackage) {
        this.getPList().add(ucpPackage);
    }
    
    /**
     * 
     * @param ucpUseCase
     */
    public void addUseCase(UcpUseCase ucpUseCase) {
        this.getUList().add(ucpUseCase);
    }

    /**
     * 
     * @param ucpActor
     */
    public void addActor(UcpActor ucpActor) {
        this.getAList().add(ucpActor);
    }

    /**
     * 
     * @return
     */
    public ArrayList<UcpPackage> getPList() {
        return pList;
    }

    /**
     * 
     * @return
     */
    public ArrayList<UcpUseCase> getUList() {
        return uList;
    }

    /**
     * 
     * @return
     */
    public ArrayList<UcpActor> getAList() {
        return aList;
    }

    /**
     * 
     * @return
     */
    public UcpMetrics getMetrics() {
        return metrics;
    }

        
    
    /**
     * 
     * Method finds elements and sets coplexity.
     * 
     * @param idref
     * @param complexity
     */
    public void setComplexity(String idref, int complexity) {//prochazi model a hleda element s idref, kteremu nastavi complexity
        
        if (id.equals(idref)) //pokud ma balik stejne id (idref)
        {
            metrics.setComplexity(0); //nastavi se mu complexity
            //pro baliky se UCP nepocita, balik vlastni complexity nema
            //UCP se pocita jen pro sub elementy v baliku, proto complexity=0
        }
        
        else //jinak se hleda dal (hloubeji)
        
        {
        
        for (UcpPackage p:pList)
        {
            p.setComplexity(idref, complexity); //preda hodnoty dal (hloubeji)       
        }
        
        for (UcpUseCase u:uList)
        {
            u.setComplexity(idref, complexity); //preda hodnoty dal (hloubeji)
        }
        
        for (UcpActor a:aList)
        {
            a.setComplexity(idref, complexity); //preda hodnoty dal (hloubeji)        
        }
        
        }
    }
    
    
    
    /**
     * 
     * Method sets metrics.
     * 
     * @param ucpMetrics
     */
    public void setMetrics(UcpMetrics ucpMetrics) {//jednoduche nastaveni metrics - vsem elementum v baliku nastavi stejne metrics
        
        this.metrics.setT(ucpMetrics.getT()); //technical factors
        this.metrics.setE(ucpMetrics.getE()); //environmental factors
        this.metrics.setHoursPerUc(ucpMetrics.getHoursPerUc()); //normovany cas prace na jeden UC
        
        for (UcpPackage p:pList)
        {
            p.setMetrics(ucpMetrics); //preda hodnoty dal (hloubeji)        
        }
        
        for (UcpUseCase u:uList)
        {
            u.setMetrics(ucpMetrics); //preda hodnoty dal (hloubeji)        
        }
                
        for (UcpActor a:aList)
        {
            a.setMetrics(ucpMetrics); //preda hodnoty dal (hloubeji)        
        }
    }
    
    
    /**
     * Method counts UCP metrics according to defined level.
     * 
     * @param level
     */
    public void countUcp(int level) //vypocet ucp
    {
        UcpAlgorithm ucpAlgorithm = new UcpAlgorithm();
        int sumComplexity = 0;
        double sumHours = 0.0;
        double sumHoursSW = 0.0;
        
        for (UcpUseCase u:uList)
        {
            u.countUcp(level);//rekurzivni vypocet metrik u sub elementu
            
            //vyscitani zakladni metrics ze sub elementu do metrics vlastniho elementu
            if (u.getMetrics().getHours() > 0)//pokud ma subelement spocitane nenulove hodiny
            {//pak ma spocitane i cele metrics, takze se vyscitaji jen hodiny
                sumHours = sumHours + u.getMetrics().getHours();
                sumHoursSW = sumHoursSW + u.getMetrics().getHoursSW();
            }
            else
            {//jinak se vyscitaji jen complexity
                sumComplexity = sumComplexity + u.getMetrics().getComplexity();
            }
            
            //vyscitaji se i sumarni sub metriky ze sub elementu
            sumComplexity = sumComplexity + u.getMetrics().getSubUUCP();
            sumHours = sumHours + u.getMetrics().getSubCasesHours();
            sumHoursSW = sumHoursSW + u.getMetrics().getSubCasesHoursSW();
        }
        
        for (UcpPackage p:pList)
        {
            p.countUcp(level);//rekurzivni vypocet metrik u sub elementu
            
            //vyscitani zakladni metrics ze sub elementu do metrics vlastniho elementu
            if (p.getMetrics().getHours() > 0)//pokud ma subelement spocitane nenulove hodiny
            {//pak ma spocitane i cele metrics, takze se vyscitaji jen hodiny
                sumHours = sumHours + p.getMetrics().getHours();
                sumHoursSW = sumHoursSW + p.getMetrics().getHoursSW();
            }
            else
            {//jinak se vyscitaji jen complexity
                sumComplexity = sumComplexity + p.getMetrics().getComplexity();
            }
            
            //vyscitaji se i sumarni sub metriky ze sub elementu
            sumComplexity = sumComplexity + p.getMetrics().getSubUUCP();
            sumHours = sumHours + p.getMetrics().getSubCasesHours();
            sumHoursSW = sumHoursSW + p.getMetrics().getSubCasesHoursSW();
        }
        
        for (UcpActor a:aList)
        {
            a.countUcp(level);//rekurzivni vypocet metrik u sub elementu
            
            //vyscitani zakladni metrics ze sub elementu do metrics vlastniho elementu
            if (a.getMetrics().getHours() > 0)//pokud ma subelement spocitane nenulove hodiny
            {//pak ma spocitane i cele metrics, takze se vyscitaji jen hodiny
                sumHours = sumHours + a.getMetrics().getHours();
                sumHoursSW = sumHoursSW + a.getMetrics().getHoursSW();
            }
            else
            {//jinak se vyscitaji jen complexity
                sumComplexity = sumComplexity + a.getMetrics().getComplexity();
            }
            
            //vyscitaji se i sumarni sub metriky ze sub elementu
            sumComplexity = sumComplexity + a.getMetrics().getSubUUCP();
            sumHours = sumHours + a.getMetrics().getSubCasesHours();
            sumHoursSW = sumHoursSW + a.getMetrics().getSubCasesHoursSW();
        }
        
        //po pruchodu sub elementu se z pomocnych promennych nastavi sumarni sub metriky vlastniho elementu
        this.metrics.setSubUUCP(sumComplexity);
        this.metrics.setSubCasesHours(sumHours);
        this.metrics.setSubCasesHoursSW(sumHoursSW);
        
        //level = 1 -> pocitaji se baliky
        if (level >= 1)
        {
            //vypocet metrics pro vlastni element
            ucpAlgorithm.apply(this.metrics);
        }
    }    
    
}
