/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 * 
 * Copyright 2004, 2010  Technical University Berlin, Germany, and others.
 * 
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Please visit http://www.eclipse.org/objectteams for updates and contact.
 * 
 * Contributors:
 * 	  Technical University Berlin - Initial API and implementation
 **********************************************************************/
package org.eclipse.objectteams.samples.ordersystem.order;

import java.util.LinkedList;
import java.util.Iterator;
import java.util.List;

/**
* This is a generic team definition of an order. An <code>Order</code> consists of a list of
* <code>Item</code>s, implemented as an abstract role, and several team features.
*/
public team class Order {

	/**
	 * The abstract role of an address. This address is used by Customer
	 */
	public abstract class Address {
		@SuppressWarnings("unused") private int id;
	}
		
	/**
	 * The abstract role of a customer.
	 */
	public abstract class Customer {
		
		@SuppressWarnings("unused") private int id;

		private boolean usePrivateAddress = true;
		private Address orderAddress;
		
		/**
		 * @return Returns the usePrivateAddress.
		 */
		public boolean isUsePrivateAddress() {
			return usePrivateAddress;
		}
		
		/**
		 * @param usePrivateAddress The usePrivateAddress to set.
		 */
		public void setUsePrivateAddress(boolean usePrivateAddress) {
			this.usePrivateAddress = usePrivateAddress;
//			this.orderAddress = null;
		}
		
		/**
		 * @return Returns the orderAddress.
		 */
		public Address getOrderAddress() {
			return orderAddress;
		}
		
		/**
		 * @param orderAddress The orderAddress to set.
		 */
		public void setOrderAddress(Address orderAddress) {
			this.orderAddress = orderAddress;
			this.usePrivateAddress = false;
		}
		
		abstract public String getRepres();
		
	}
	
	/**
	 * The abstract role of an order entry. An <code>Item</code> is a part of an order list.
	 */
    protected abstract class Item {
		
		/**
		 * Returns the number of available items. This abstract method is implemented in a sub-role. 
		 */
		abstract int getStockCount();
		
		/**
		 * Returns the current price of a single piece. This abstract method is implemented in a sub-role.
		 */
		abstract int getSinglePrice ();
		
		/**
		 * Returns the description of the item. This abstract method is implemented in a sub-role. 
		 */
		abstract String getDescription();

		@SuppressWarnings("unused") private int id;

		/**
		 * Number of ordered pieces.
		 */
		private int count = 0;
		
		/**
		 * Number of missing pieces.
		 */
		private int numMissing = 0;
		
		/**
		 * Discounting rate for the current item.
		 */
		private double discount = 0.0;

		/**
		 * Returns the number of ordered pieces.
		 */
		protected int  getCount() {
			return count ;  	    }

		/**
		 * Sets the number of ordered pieces.
		 * @param count
		 */
		protected void setCount(int count) {
			this.count = count;	}

		/**
		 * Returns the number of missing pieces.
		 */
		protected int  getMissing  () {
			return numMissing;    }

		/**
		 * Sets the number of missing pieces. 
		 * @param count number of missing pieces
		 */
		protected void setMissing  (int count) {
			numMissing = count;  }

		/**
		 * Sets the discounting rate for the item.
		 * @param discount Discounting rate to be set
		 */
		protected void setDiscount (double discount) {
			this.discount = discount; }

		/**
		 * Returns the total price of the item considering the discounting rate.
		 */
		protected int getTotalPrice() {
			return (int) ((getSinglePrice() * getCount()) * (1.0 - discount));
		}

		/**
		 * Reserves the missing pices again and returns the number of actually reserved pieces.
		 * Checks whether the complete order list can be delivered, if all missing pieces have been reserved.
		 */
		void check () {
			int stockCount = getStockCount();
			if ((numMissing > 0) && (stockCount > 0)) {
				int reserved = doReserve(numMissing);
				numMissing -= reserved;
				if (numMissing == 0)
					Order.this.check(); // delegate up to the enclosing team instance
			}
		}

		/**
		 * Give the alarm, if the reservation became invalid.
		 * Completely replaces the original behavior, thus the warning about
		 * a missing base call.
		 */
		@SuppressWarnings("basecall")
		callin void alarm () {
			System.err.println("\nOrder of "+Order.this.customer.getRepres()+":");
			System.err.println("ATTENTION, Reservation became invalid!");
			System.err.println("Order item: "+getDescription());
			// TODO: [begin] set missing pieces to zero, try to newly reserve items 
			setMissing(getCount());
			check();
		    // TODO: [end]
		}

		/**
		 * Returns a report about the ordered item.
		 */
		public String toString() {
			String comment = "";
			if (numMissing > 0)
				comment = "\n !! "+numMissing+" pieces not on stock!!";
			return getDescription()+": \t"
				+ getCount()+"*\t= "+getEuroString(getTotalPrice())
				+ comment;
		}

		/**
		 * Reserves the missing items. Returns the number of actually reserved pieces.
		 * @param numMissing Number of missing pieces
		 * @return Number of actually reserved pieces
		 */
		abstract public int doReserve(int numMissing);
		
		/**
		 * Deliver the given number of pieces.
		 * @param count
		 */
		abstract public void doDeliver(int count);

	}

	@SuppressWarnings("unused") private int id;

	/**
	 * An Order is always associated with a customer.
	 */
	Customer customer;
	
	/**
	 * List of ordered items.
	 */
	List<Item> itemList;
	
	/**
	 * This <code>Order</code>'s status.
	 */
	int status;
	
	/**
	 * Status value of the order list. All ordered items are available and can be delivered.
	 */
	public static final int NORMAL = 0;
	
	/**
	 * Status value of the order list. There is at least one of the ordered items which is 
	 * not available so that the complete order list cannot be delivered and has to wait for stock.
	 */
	public static final int WAIT   = 1;
	
	/**
	 * Status value of the order list. All ordered items have been delivered.
	 */
	public static final int DELIVERED = 2;
	
	/**
	 * Status values of the order list.
	 */
	public static final String[] STATES = {
		"in progress",
		"wait for stock",
		"delivered"
	};
	
	/**
	 * Creates a new team instance.
	 */
	public Order (Customer customer) {
		this.customer = customer;
		itemList = new LinkedList<Item>();
		status = NORMAL;
		activate(ALL_THREADS);
	}

	/**
	 * Creates a new team instance with a different order address.
	 */
	public Order (Customer customer, Address orderAddress) {
		// this(customer);
		this.customer = customer;
		this.customer.setOrderAddress(orderAddress);
		itemList = new LinkedList<Item>();
		status = NORMAL;
		activate(ALL_THREADS);
	}

    /**
     * Creates a new team instance with a different order address.
     */
    public Order (Customer customer, Address orderAddress, boolean isUsingPrivateAddress) {
        // this(customer);
        this.customer = customer;
        this.customer.setOrderAddress(orderAddress);
        this.customer.setUsePrivateAddress(true);
        itemList = new LinkedList<Item>();
        status = NORMAL;
        activate(ALL_THREADS);
    }

	Order() { }

	/**
	 * Checks the order list and notes the missing items which cannot be delevered.  The state of 
	 * the missing items is set on <code>WAIT</code>. If all items in the order list are available, 
	 * they will be delivered. 
	 */
	void check () {
		status = NORMAL;
		Iterator<Item> it = itemList.iterator();
		while (it.hasNext()) {
			Item p = it.next();
			if (p.getMissing() > 0) {
				status = WAIT;
				return;
			}
		}
		System.out.println("Now deliverable!");
		print();
		deliver();
		print();
	}

	/**
	 * Orders a given number (count) of pieces. The local variable <code>reserved</code> holds the 
	 * number of actually reserved pieces. 
	 */
	public void order (Item item, int count) {
		int reserved = item.doReserve(count);
		item.setCount(count);
		if (reserved < count) {
			item.setMissing(count - reserved);
			status = WAIT;
		}
		itemList.add(item);
	}

	/**
	 * Checks the order status and returns true, if the order can be delivered.
	 */
	public boolean isDeliverable () {
		return status == NORMAL;
	}

	/**
	 * Delivers all items in the order list. After delivering the team instance should be deaktivated.
	 */
	public void deliver () {
		Iterator<Item> it = itemList.iterator();
		while (it.hasNext()) {
			Item p = it.next();
			p.doDeliver(p.getCount());
		}
		status = DELIVERED;
		deactivate();
	}

	/**
	 * Sets the discounting rate for the given item.
	 * @param item item which should be discounted
	 * @param discount discounting rate
	 */
	public void setDiscount (Item item, double discount) {
		item.setDiscount(discount);
	}

	/**
	 * This team method prints a string representation of this order.
	 */
	public void print() {
        System.out.println("----------------------------------------");
		System.out.println(toString());
        System.out.println("----------------------------------------");
	}

    /**
     * 
     */
    public String toString() {
        String tempString = "";
        tempString += "Order for "+customer.getRepres()+"\n";
        if (customer.getOrderAddress() != null) {
            tempString += "order address  : " + customer.getOrderAddress() + "\n";
            tempString += "-> using " + 
                          ((customer.isUsePrivateAddress()) ? "private address" : "order address") 
                          + "\n";
        }
        tempString += "("+STATES[status]+")\n";
        tempString += "========================================\n";
		Iterator<Item> it = itemList.iterator();
		int i = 1;
		int total = 0;
		while (it.hasNext()) {
			Item p = it.next();
            tempString += ((i++)+".\t"+p) + "\n";
			total += p.getTotalPrice();
		}
        tempString += "Total: "+getEuroString(total) +"\n";
        return tempString;
    }

	/**
	 * Returns an euro string for the given price. 
	 * @param price
	 * @return euro string 
	 */
	public String getEuroString(int price) {
		int euro = price / 100;
		int cent = price % 100;
		return euro + "," + cent + " Euro";
	}

}
