/***
 * 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.
***/

@Named("OK")
public Person ok() {
    Person person = customerRepository.newCustomer();
    person.getName().setFirstName(getFirstName());
    person.getName().setLastName(getLastName());
    person.getName().setTitle(getTitle());
    Customer customer = person.getRole(Customer.class);
    if (enteredAllOf(getVehicle1Model(), 
                     getVehicle1RegistrationNumber())) {
        Vehicle vehicle = customer.newVehicle(getVehicle1Model());
        vehicle.setRegistrationNumber(
                    getVehicle1RegistrationNumber());
        customer.addToVehicles(vehicle);
    }
    if (enteredAllOf(getVehicle2Model(), 
                     getVehicle2RegistrationNumber())) {
        Vehicle vehicle = customer.newVehicle(getVehicle2Model());
        vehicle.setRegistrationNumber(
                    getVehicle2RegistrationNumber());
        customer.addToVehicles(vehicle);
    }
    if (enteredAllOf(getCreditCardNumber(), 
                     getCreditCardExpiryDate())) {
        CreditCard creditCard = 
            (CreditCard) customer.newPaymentMethod(
                findPaymentMethodType(CreditCard.class));
        creditCard.setCardNumber(getCreditCardNumber());
        creditCard.setExpiryDate(getCreditCardExpiryDate());
        customer.addToPaymentMethods(creditCard);
    }
    if (enteredAllOf(getAccountLimit()) && 
        getAccountLimit() > 0) {
        Account account = 
            (Account) customer.newPaymentMethod(
                findPaymentMethodType(Account.class));
        account.setLimit(getAccountLimit());
        customer.addToPaymentMethods(account);
    }
    if (getSetupCash()) {
        Cash cash = (Cash) customer.newPaymentMethod(
                findPaymentMethodType(Cash.class));
        customer.addToPaymentMethods(cash);
    }
    persist(person);
    setTakenOn(true);
    return person;
}
public String disableOk() {
    String invalidReason = validate(this);
    if (invalidReason != null) {
        return invalidReason;
    }
    return getTakenOn()?"Already taken on":null;
}


private PaymentMethodType findPaymentMethodType(
        final Class<? extends PaymentMethod> paymentMethodClass) {
    return paymentMethodTypeRepository.findByClassName(
            paymentMethodClass.getName());
}

private static boolean enteredAllOf(final Object... objects) {
    for(Object o: objects) {
        if (o == null) return false;
    }
    return true;
}
