/***
 * Excerpted from "Domain-Driven Design Using Naked Objects",
 * published by The Pragmatic Bookshelf.
 * Copyrights apply to this code. It may not be used to create training material, 
 * courses, books, articles, and the like. Contact us if you are in doubt.
 * We make no guarantees that this code is fit for any purpose. 
 * Visit http://www.pragmaticprogrammer.com/titles/dhnako for more book information.
***/
package com.pragprog.dhnako.carserv.fixture.employee;

import org.nakedobjects.applib.Filter;
import org.nakedobjects.applib.fixtures.AbstractFixture;

import com.pragprog.dhnako.carserv.dom.employee.Employee;
import com.pragprog.dhnako.carserv.dom.employee.EmployeeRepository;
import com.pragprog.dhnako.carserv.dom.person.Person;
import com.pragprog.dhnako.carserv.dom.person.Title;

public abstract class AbstractEmployeeFixture extends AbstractFixture {

    public abstract void install();
    
    protected Person createEmployee(
    		final String titleName, 
    		final String lastName, final String firstName,
    		final Integer hourlyChargeRate) {
    	
    	Person person = firstMatch(Person.class, new Filter<Person>() {
			public boolean accept(Person person) {
				return person.matches(firstName, lastName);
			}
    	});
    	
    	Employee employeeRole;
    	if (person != null) {
    		// add employee role to existing
    		employeeRole = newTransientInstance(Employee.class);
    		employeeRole.setPerson(person);
    	} else {
    		// new person & employee role
	    	person = employeeRepository.newEmployee();
	    	person.getName().setTitle(findTitle(titleName));
	    	person.getName().setLastName(lastName);
	    	person.getName().setFirstName(firstName);
	    	employeeRole = person.getRole(Employee.class);
    	}
        
        employeeRole.setHourlyChargeRate(hourlyChargeRate);

        // save new object(s) 
        if (isPersistent(person)) {
        	persist(employeeRole);
        } else {
        	persist(person);
        }
        return person;
    }

	protected Title findTitle(final String titleName) {
		return firstMatch(Title.class, new Filter<Title>() {
			public boolean accept(Title title) {
				return title.getName().equals(titleName);
			}
        });
	}
	


	// {{ injected: EmployeeRepository
	private EmployeeRepository employeeRepository;

	public void setEmployeeRepository(final EmployeeRepository employeeRepository) {
		this.employeeRepository = employeeRepository;
	}
	// }}


}
