import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Date;
import java.util.Calendar;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.ArrayList;
import java.text.SimpleDateFormat;

public class Converter
{
	public static void main(String[] args) throws FileNotFoundException
	{
		Converter c = new Converter("ConversionData.txt");
	}

	static SimpleDateFormat sdf = new SimpleDateFormat("d MMM yyyy");
	private String file;

	public Converter(String file) throws FileNotFoundException
	{
		this.file = file;
		begin();
	}

	public void begin() throws FileNotFoundException
	{
		parseCusts(new Scanner(new FileReader(file)));
		parseTitles(new Scanner(new FileReader(file)));
	}

	public void parseCusts(Scanner s) //throws FileNotFoundException
	{
		String nextLine = "";
		String account = "";
		ArrayList<String> last = new ArrayList<String>();
		ArrayList<String> firstName = new ArrayList<String>();
		String address;
		String email;
		String rating;
		while(s.hasNextLine())
		{
			nextLine = s.nextLine();
			if(nextLine.startsWith("CUST"))
			{
				account = nextLine.substring(5, nextLine.length());
				nextLine = s.nextLine();
				while(nextLine.startsWith("LNAM"))
				{
					last.add(nextLine.substring(5, nextLine.length()));
					nextLine = s.nextLine();
				}
				while(nextLine.startsWith("FNAM"))
				{
					firstName.add(nextLine.substring(5, nextLine.length()));
					nextLine = s.nextLine();
				}
				address = nextLine.substring(5, nextLine.length());
				nextLine = s.nextLine();
				email = nextLine.substring(5, nextLine.length());
				nextLine = s.nextLine();
				rating = nextLine.substring(5, nextLine.length());
				nextLine = s.nextLine();
				addCustToDB(account, last, firstName, address, email, rating);
				last = new ArrayList<String>();
				firstName = new ArrayList<String>();
			}
		}
	}

	// For testing, this only prints out the information.
	void addCustToDB(String account, ArrayList<String> lastNames, ArrayList<String> firstNames,
					 String address, String email, String rating)
	{
		System.out.print(account + " {");
		for (String s : firstNames)
			System.out.print(s + " ");
		System.out.print("} [");
		for (String s : lastNames)
			System.out.print(s + " ");
		System.out.println("] " + address + " " + email + " " + rating);
		System.out.flush();
	}

	public void parseTitles(Scanner s) //throws FileNotFoundException
	{
		String nextLine = "";
		String dataLine = "";
		String title = "";
		ArrayList<String> role = new ArrayList<String>();
		String genre;
		String rating;
		String format;
		String pricingCode;
		String itemID;
		long itemIDint = 0;
		String store = "";
		ArrayList<CustomerDetail> history = new ArrayList<CustomerDetail>();

		while (s.hasNextLine())
		{
			nextLine = s.nextLine();
			if (nextLine.startsWith("TITL"))
			{
				title = nextLine.substring(5, nextLine.length());
				nextLine = s.nextLine();
				nextLine = s.nextLine();	// skip YEAR
				while (nextLine.startsWith("ROLE"))
				{
					role.add(nextLine.substring(5, nextLine.length()));
					nextLine = s.nextLine();
				}
				// A bug: this only handles one GENR line; many movies have >1
				genre = nextLine.substring(5, nextLine.length());
				nextLine = s.nextLine();
				rating = nextLine.substring(5, nextLine.length());
				nextLine = s.nextLine();
				format = nextLine.substring(5, nextLine.length());
				nextLine = s.nextLine();
				pricingCode = nextLine.substring(5, nextLine.length());
				nextLine = s.nextLine();
				while (nextLine.startsWith("ITEM"))
				{
					itemID = nextLine.substring(5, nextLine.length());
					itemIDint = Long.parseLong(itemID.trim());
					nextLine = s.nextLine();
					store = nextLine.substring(5, nextLine.length());
					nextLine = s.nextLine();
					while (nextLine.startsWith("HIST"))
					{
						dataLine = nextLine.substring(5, nextLine.length());
						String custID = dataLine.substring(0, 6);
						String startDate = dataLine.substring(8, 18);
						int sMonth = Integer.parseInt(startDate.substring(0,2));
						int sDay = Integer.parseInt(startDate.substring(3,5));
						int sYear = Integer.parseInt(startDate.substring(6,10));
						Calendar start = Calendar.getInstance();
						start.set(sYear, sMonth-1, sDay);
						Calendar end = null;
						double cost = 0;
						if (dataLine.length() > 20)
						{
							String endDate = dataLine.substring(20, 30);
							int eMonth = Integer.parseInt(endDate.substring(0,2));
							int eDay = Integer.parseInt(endDate.substring(3,5));
							int eYear = Integer.parseInt(endDate.substring(6,10));

							end = Calendar.getInstance();
							end.set(eYear, eMonth-1, eDay);

							cost = Double.parseDouble(dataLine.substring(32, dataLine.length()));
						}
						history.add(new CustomerDetail(custID, itemID, start, end, cost));
						if (s.hasNextLine())
							nextLine = s.nextLine();
						else
							break;
					}
					role = new ArrayList<String>();
				}
				addTitleToDB(title, role, genre, rating, format, pricingCode, itemIDint,
				             store, history);
				history = new ArrayList<CustomerDetail>();
			}
		}
	}

	// For testing, this only prints out the information.
	void addTitleToDB(String title, ArrayList<String> role, String genre,
					  String rating, String format, String pricingCode, long itemIDint,
				      String store, ArrayList<CustomerDetail> history)
	{
		System.out.println(title + " (" + genre + " " + rating + " " + format +
		                   " " + pricingCode + " " + itemIDint + " " + store + ")");
		for (int i=0; i<history.size(); i++)
		{
			if (i == 0)
				System.out.print("Hist:\t");
			else
				System.out.print("\t");
			System.out.println(history.get(i));
		}
		System.out.flush();
	}


	// inner class
	// one object of this class per transaction
	class CustomerDetail
	{
		String customerID;
		String itemID;
		Calendar   rentalStart;
		Calendar   rentalEnd;		// null if rental item is still out
		double cost;

		CustomerDetail(String cID, String iID, Calendar rS, Calendar rE, double c)
		{
			customerID = cID;
			itemID = iID;
			rentalStart = rS;
			rentalEnd = rE;
			cost = c;
		}

		// override Object.toString
		public String toString()
		{
			return customerID + ": " + itemID + " " + sdf.format(rentalStart.getTime()) + " - " +
			(rentalEnd == null ? "<out>" : (sdf.format(rentalEnd.getTime()) + " $" + cost));
		}
	}


}
