/***
 * 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.dom.payment;

import org.nakedobjects.applib.AbstractDomainObject;
import org.nakedobjects.applib.annotation.Disabled;
import org.nakedobjects.applib.annotation.Hidden;
import org.nakedobjects.applib.annotation.MemberOrder;
import org.nakedobjects.applib.annotation.When;
import org.nakedobjects.applib.util.TitleBuffer;

public abstract class PaymentMethod extends AbstractDomainObject {

	// {{ Identification
	public String title() {
		TitleBuffer buf = new TitleBuffer();
		buf.append(getOwner() != null? getOwner().title(): "");
		buf.append(getName());
		return buf.toString();
	}
	// }}

	
	// {{ Type
	private PaymentMethodType type;

	@Disabled
	@MemberOrder(sequence = "1")
	public PaymentMethodType getType() {
		return type;
	}

	public void setType(final PaymentMethodType type) {
		this.type = type;
	}
	// }}


	// {{ Owner
	private PaymentMethodOwner owner;

	@Disabled
	@MemberOrder(sequence = "2")
	public PaymentMethodOwner getOwner() {
		return owner;
	}

	public void setOwner(final PaymentMethodOwner owner) {
		this.owner = owner;
	}

	public void modifyOwner(
			final PaymentMethodOwner owner) {
		PaymentMethodOwner currentOwner = getOwner();
		// check for no-op
		if (owner == null
				|| owner.equals(currentOwner)) {
			return;
		}
		// delegate to parent to associate
		owner.addToPaymentMethods(this);
		// additional business logic
		onModifyOwner(currentOwner, owner);
	}

	public void clearOwner() {
		PaymentMethodOwner currentOwner = getOwner();
		// check for no-op
		if (currentOwner == null) {
			return;
		}
		// delegate to parent to dissociate
		currentOwner.removeFromPaymentMethods(this);
		// additional business logic
		onClearOwner(currentOwner);
	}
	
	protected void onModifyOwner(final PaymentMethodOwner oldOwner, final PaymentMethodOwner newOwner) {
	}

	protected void onClearOwner(final PaymentMethodOwner oldOwner) {
	}
	// }}

	
	// {{ Name
	private String name;

	@Disabled(When.ONCE_PERSISTED)
	@MemberOrder(sequence = "3")
	public String getName() {
		return name;
	}

	public void setName(final String name) {
		this.name = name;
	}
	// }}



	// {{ Current
	private Boolean current;
	@MemberOrder(sequence = "4")
	public Boolean getCurrent() {
		return current;
	}

	public void setCurrent(final Boolean current) {
		this.current = current;
	}
	// }}

	
	// {{ pay
	@Hidden
	public abstract void pay(Payable payable);
	public abstract String validatePay(Payable payable);
	// }}


	// {{ Lifecycle methods
	public void persisting() {
		getOwner().addToPaymentMethods(this);
	}
	// }}

}
