
import java.io.*;

public class ThesisIIV3
{
	// ************************************************************
  	// *														  *
	// *                       main Method      				  *
	// *														  *
	// ************************************************************
	public static void main(String[] args) throws Exception
	{
		String[] inputStrings;

		System.out.println("\n * * * Welcome to the UML Specification Analysis * * * \n");
/*CALL*/inputStrings=input();
/*CALL*/writeUMLFile("<Book>"+(char)10);
/*CALL*/readUMLFile(inputStrings);
/*CALL*/writeUMLFile("</Book>"+(char)10);
		System.out.println("\n * * * End of the Document Analysis * * * \n");
	}
  	// ************************************************************
  	// *														  *
	// *                    input Method  		            	  *
	// *														  *
	// ************************************************************
	public static String[] input() throws Exception
	{
		String[] inputStrings={"",""}; // Two dimensional string

		System.out.print(" Type the Name of the Input File, for example 'UML.xml', and then Press Enter:\t");
/*CALL*/inputStrings[0]=readString();
		System.out.print(" Type the Name of the Starting Chapter, for example '1 Scope', and then Press Enter:\t");
/*CALL*/inputStrings[1]=readString();
		return inputStrings;
	}
	// ************************************************************
  	// *														  *
	// *                    readString Method  		           	  *
	// *														  *
	// ************************************************************
	public static String readString() throws Exception
	{
		char tempCh;
		String tempSt="";

		tempCh = (char)System.in.read();
		while((int)tempCh != 13 ) // Enter = 13
		{
			  tempSt = tempSt + tempCh;
			  tempCh = (char)System.in.read();
		}
		tempCh = (char)System.in.read(); //Abort the ENTER key
		return tempSt;
	}
	// ************************************************************
	// *														  *
	// *                    readUMLFile Method     				  *
	// *														  *
    // ************************************************************
	public static void readUMLFile(String[] inputStrings)
	{
		// inputStrings[0] is the name of the input file, e.g.: UML.xml
		// inputStrings[1] is the first header where we like to start the processing, e.g.: 1 Scope
		boolean startAnalysis=false;
		int indexOfLinkTarget; // "LinkTarger" is a key word for processing
		int indexOfFirstHeader;
		int indexOfBeginingOfHeaders;
		int indexOfEndOfHeaders;
		int stackPointer=-1;
		int[] tempStack = new int[1000]; // [0] to [999]
		String lineSt="";
		String tempStHeaders="";
		String tempHeaderNumberFive="";
		String [] analyzedHeader={"","","",""};// Type,firstPart,secondPart,thirdPart

		try // Read the INPUT FILE
		{
			FileReader inputFileReader = new FileReader(inputStrings[0]); // inputReader is an object
			BufferedReader inputFileBuffer = new BufferedReader(inputFileReader);
			while(true) // Until the end of the input file
			{
				lineSt=inputFileBuffer.readLine(); // Read a line from the input file
//				System.out.println(lineSt);
/* END-1 */		if(lineSt==null) // End of the input file
				{
					break;
				}
				indexOfLinkTarget=lineSt.indexOf("LinkTarget");
				if(indexOfLinkTarget!=-1)
				// I found a line which has the "LinkTarget" string
				{
					if(startAnalysis!=true)
					// It will ignore all lines which have the "LinkTarget"
					// until it reaches a line which has both
					// "LinkTarget" and "First Header, e.g.: 1 Scope"
					// because we would like to jump from the:
					// "bookmark tree", "table of contents" and "many of the first chapters"
					{
						indexOfFirstHeader=lineSt.indexOf(inputStrings[1]);
						if(indexOfFirstHeader!=-1)
						// I found the first header, e.g.: "1 Scope"
						{
							startAnalysis=true;
//							System.out.println("\n\n"+lineSt);
							System.out.println("\n"+inputStrings[1]);
/*CALL*/					analyzedHeader=headersAnalysis(inputStrings[1]);
							stackPointer ++;
/*PUSH*/					tempStack[stackPointer]=Integer.parseInt(analyzedHeader[0]); // Convert analyzedHeader[0] from String into Integer
/*CALL*/					writeUMLFile("<Chapter Number="+(char)34+analyzedHeader[1]+(char)34+">"+
										(char)10+"<Name>"+analyzedHeader[2]+"</Name>"+(char)10);
						}
					}
					else
					// startAnalysis is TRUE: I already started the processing
					{
						indexOfLinkTarget=indexOfLinkTarget+10;// Because length of "LinkTarget" is 10
						indexOfBeginingOfHeaders=lineSt.indexOf(">",indexOfLinkTarget);
						indexOfEndOfHeaders=lineSt.indexOf("<",indexOfBeginingOfHeaders);
						indexOfBeginingOfHeaders ++;
						indexOfEndOfHeaders --;
						tempStHeaders=lineSt.substring(indexOfBeginingOfHeaders,indexOfEndOfHeaders);
/* END-2 */				if(tempStHeaders.compareTo("Index")==0) // End of the processing
						{
							break;
						}
//						System.out.println("\n"+lineSt);
						System.out.println("\n"+tempStHeaders);
/*CALL*/				analyzedHeader=headersAnalysis(tempStHeaders);
						while((Integer.parseInt(analyzedHeader[0])<=tempStack[stackPointer])||(Integer.parseInt(analyzedHeader[0])==6 && tempStack[stackPointer]==3))
						{
							if(tempStack[stackPointer]==1)
							{
/*CALL*/						writeUMLFile("</Part>"+(char)10);
							}
							else if(tempStack[stackPointer]==2)
							{
/*CALL*/						writeUMLFile("</Chapter>"+(char)10);
							}
							else if(tempStack[stackPointer]==3)
							{
/*CALL*/						writeUMLFile("</Section>"+(char)10);
							}
							else if(tempStack[stackPointer]==4)
							{
/*CALL*/						writeUMLFile("</Subsection>"+(char)10);
							}
							else if(tempStack[stackPointer]==5)
							{
								tempHeaderNumberFive=tempHeaderNumberFive.replace((char)32,(char)95); // Replace "Space" with "Underline"
//								System.out.println("--->"+tempHeaderNumberFive);
/*CALL*/						writeUMLFile("</"+tempHeaderNumberFive+">"+(char)10);
							}
							else if(tempStack[stackPointer]==6)
							{
/*CALL*/						writeUMLFile("</Annex>"+(char)10);
							}
/*POP*/						stackPointer --;
							if(stackPointer==-1) // Stack is empty
							{
								break;
							}
						}
						stackPointer ++;
/*PUSH*/				tempStack[stackPointer]=Integer.parseInt(analyzedHeader[0]);
						if(Integer.parseInt(analyzedHeader[0])==1)
						{
/*CALL*/					writeUMLFile("<Part Number="+(char)34+analyzedHeader[2]+(char)34+
										">"+(char)10+"<Name>"+analyzedHeader[3]+"</Name>"+(char)10);
						}
						else if(Integer.parseInt(analyzedHeader[0])==2)
						{
/*CALL*/					writeUMLFile("<Chapter Number="+(char)34+analyzedHeader[1]+(char)34+
										">"+(char)10+"<Name>"+analyzedHeader[2]+"</Name>"+(char)10);
						}
						else if(Integer.parseInt(analyzedHeader[0])==3)
						{
/*CALL*/					writeUMLFile("<Section Number="+(char)34+analyzedHeader[1]+(char)34+
										">"+(char)10+"<Name>"+analyzedHeader[2]+"</Name>"+(char)10);
						}
						else if(Integer.parseInt(analyzedHeader[0])==4)
						{
/*CALL*/					writeUMLFile("<Subsection Number="+(char)34+analyzedHeader[1]+(char)34+
										">"+(char)10+"<Name>"+analyzedHeader[2]+"</Name>"+(char)10+
										"<References>"+analyzedHeader[3]+"</References>"+(char)10);
						}
						else if(Integer.parseInt(analyzedHeader[0])==5)
						{
							analyzedHeader[1]=analyzedHeader[1].replace((char)32,(char)95); // Replace "Space" with "Underline"
//							System.out.println("--->"+analyzedHeader[1]);
/*CALL*/					writeUMLFile("<"+analyzedHeader[1]+">"+(char)10);
							tempHeaderNumberFive=analyzedHeader[1];
						}
						else if(Integer.parseInt(analyzedHeader[0])==6)
						{
							writeUMLFile("<Annex Number="+(char)34+analyzedHeader[2]+(char)34+
										">"+(char)10+"<Name>"+analyzedHeader[3]+"</Name>"+(char)10);
						}
					}
				}
				else
				// I found a regular line which has NOT the "LinkTarget" string
				// Therefore, I would like to do some cleaning on the XML file
				// by removing some useless lines/tags
				{
					if(startAnalysis==true &&
					   lineSt.compareTo("<Part>")!=0 && lineSt.compareTo("</Part>")!=0 &&
					   lineSt.compareTo("<Sect>")!=0 && lineSt.compareTo("</Sect>")!=0 &&
					   lineSt.compareTo("<Div>")!=0 && lineSt.compareTo("</Div>")!=0 &&
					   lineSt.compareTo("")!=0 && lineSt.compareTo("</TaggedPDF-doc>")!=0 &&
//               	   lineSt.compareTo("<Table>")!=0 && lineSt.compareTo("</Table>")!=0 &&
//!!! TD: Table Data   lineSt.compareTo("<TD>")!=0 && lineSt.compareTo("</TD>")!=0 &&
//					   lineSt.compareTo("<TR>")!=0 && lineSt.compareTo("</TR>")!=0 &&
					   lineSt.compareTo("<P>UML Superstructure Specification, v2.0 </P>")!=0)
					{
//						System.out.println(lineSt);
						writeUMLFile(lineSt+(char)10);
					}
				}
			} // End of the WHILE loop (End of the file)
//			System.out.println("--->"+stackPointer);
			while(stackPointer!=-1) // We have to empty the "stack"
			{
				if(tempStack[stackPointer]==1)
				{
/*CALL*/						writeUMLFile("</Part>"+(char)10);
				}
				else if(tempStack[stackPointer]==2)
				{
/*CALL*/						writeUMLFile("</Chapter>"+(char)10);
				}
				else if(tempStack[stackPointer]==3)
				{
/*CALL*/						writeUMLFile("</Section>"+(char)10);
				}
				else if(tempStack[stackPointer]==4)
				{
/*CALL*/						writeUMLFile("</Subsection>"+(char)10);
				}
				else if(tempStack[stackPointer]==5)
				{
					tempHeaderNumberFive=tempHeaderNumberFive.replace((char)32,(char)95); // Replace "Space" with "Underline"
//					System.out.println("--->"+tempHeaderNumberFive);
/*CALL*/						writeUMLFile("</"+tempHeaderNumberFive+">"+(char)10);
				}
				else if(tempStack[stackPointer]==6)
				{
/*CALL*/						writeUMLFile("</Annex>"+(char)10);
				}
/*POP*/			stackPointer --;
//				System.out.println("--->"+stackPointer);
			}
			inputFileReader.close();
		} // End of the TRY
		catch(FileNotFoundException e)
		{
			System.out.println("Unable to Open INPUT File");
		}
		catch(IOException e)
		{
			System.out.println("Unable to Close INPUT File");
		}
	}
    // ************************************************************
	// *														  *
	// *                    headersAnalysis Method     			  *
	// *														  *
    // ************************************************************
	public static String[] headersAnalysis(String tempStHeader)
	{
		int headerType;
		int lengthHeader;
		int periodCounter=0;
		int firstIndex=0, secondIndex=0;
		char tempChar=' ';
		boolean type234=false;
		String firstPartHeader="";
		String secondPartHeader="";
		String thirdPartHeader="";
		String[] finalHeader={"","","",""}; // Type,firstPart,secondPart,thirdPart
		// Type#	Sample Heading							Type
		// ------------------------------------------------------------
		// 1		[Part] [I] [Structure]						Part
		// 2		[7] [Classes]								Chapter
		// 3		[7.3] [Class Descriptions] 					Section
		// 4		[7.3.1] [Abstraction] (from [Dependencies])	Subsection
		// 5		[Generalization], etc						Keyword
		// 6		[Annex] [A] [Diagrams]						End part
		// 7		[Index] 									Last Part : Cancelled
		// ------------------------------------------------------------
		lengthHeader=tempStHeader.length();
		firstIndex=tempStHeader.indexOf(" "); // Find the first "space" to seperate numbers
//		System.out.println(firstIndex);
		for(int i=0;i<firstIndex;i++)
		{
			tempChar=tempStHeader.charAt(i);
			if(49<=tempChar && tempChar<=57) // 1 to 9
			{
				type234=true;
			}
			else if(tempChar==46) // Period "."
			{
				periodCounter ++;
			}
			firstPartHeader=firstPartHeader+tempChar;
		}
		firstIndex ++; // To skip the "space" for the next while loop
		if(type234==true)
		{
			if(periodCounter==0)
			{
				headerType=2;
			}
			else if(periodCounter==1)
			{
				headerType=3;
			}
			else
			{
				headerType=4;
			}
			while(firstIndex<lengthHeader)
			// We isolate each part of the header TYPE 2,3,4
			{
				tempChar=tempStHeader.charAt(firstIndex);
				if(tempChar==40) // If you found the "(", it means we have third part which is "refrence part"
				{
					// To remove one char which is "space" before "("
					int tempLength;
					tempLength=secondPartHeader.length();
					tempLength --;
					secondPartHeader=secondPartHeader.substring(0, tempLength);
					break;
				}
				secondPartHeader=secondPartHeader+tempChar;
				firstIndex ++;
			}
			secondIndex=tempStHeader.indexOf(" (from"); //Find the " (" to seperate the refrence part
			if(secondIndex!=-1) // I found the " (from"
			{
				secondIndex=secondIndex+7; // To skip the " (from "
				while(secondIndex<(lengthHeader-1))
				{
					tempChar=tempStHeader.charAt(secondIndex);
					thirdPartHeader=thirdPartHeader+tempChar;
					secondIndex ++;
				}
			}
		} // End of the type234==true
		else if(firstPartHeader.equals("Part")==true)
		{
			headerType=1;
		}
		else if(firstPartHeader.equals("Annex")==true)
		{
			headerType=6;
		}
		else
		{
			headerType=5;
			if(firstIndex!=0) // Type 5 consists of many words: "Changes from previous UML"
			{
				firstIndex --;
			}
			while(firstIndex<lengthHeader)
			{
				tempChar=tempStHeader.charAt(firstIndex);
				firstPartHeader=firstPartHeader+tempChar;
				firstIndex ++;
			}
		}
		if(headerType==1 || headerType==6)
		// We isolate each part of the header TYPE 1,6
		{
			while(true)
			{
				tempChar=tempStHeader.charAt(firstIndex);
				if(tempChar==32) // Space
				{
					break;
				}
				secondPartHeader=secondPartHeader+tempChar;
				firstIndex ++;
			}
			firstIndex ++;
			while(firstIndex<lengthHeader)
			{
				tempChar=tempStHeader.charAt(firstIndex);
				thirdPartHeader=thirdPartHeader+tempChar;
				firstIndex ++;
			}
		}
//		System.out.println("T= "+headerType);
//		System.out.println("[1]"+firstPartHeader);
//		System.out.println("[2]"+secondPartHeader);
//		System.out.println("[3]"+thirdPartHeader);
		finalHeader[0]=headerType+"";
		finalHeader[1]=firstPartHeader;
		finalHeader[2]=secondPartHeader;
		finalHeader[3]=thirdPartHeader;
		return finalHeader;
	}
	// ************************************************************
	// *														  *
	// *                    writeUMLFile Method     			  *
	// *														  *
    // ************************************************************
	public static void writeUMLFile(String tempString)
	{
		boolean x=true; //Each time you add a new string at the end of the FILE

		try // Creat a new file
		{
			FileWriter outputFileWriter = new FileWriter("Extracted UML.xml",x);
			outputFileWriter.write(tempString);
			outputFileWriter.close();
		}
		catch(FileNotFoundException e)
		{
			System.out.println("Unable to Open OUTPUT File");
		}
		catch(IOException e)
		{
			System.out.println("Unable to close OUTPUT File");
		}
	}
    // ************************************************************
	// ************************************************************
	// ********************End Of the Program**********************
	// ************************************************************
    // ************************************************************
}