// ALL DONE
// JUST CAN NOT REMEMBER HOW TO FIGURE OUT IF LAST TOKEN....
// SINCE NO TREATMENT HAS TAKEN PLACE ON IT!!!
// THE LOGIC ON APPLICATION WILL FAIL IF ONE WORD
//SINCE IT WILL PROCESS HASMORETOKENS   AND ALSO  !HASMORETOKENS SINCE IT DOESN'T KNOW THE ONLY TOKEN
//TRIGGERS BOTH STATES.....
// I HAVE JUST USED TRY AND CATCH OUT OF THIS AREA OF CODE....


/*
Online Java - IDE, Code Editor, Compiler

Online Java is a quick and easy tool that helps you to build, compile, test your programs online.
*/

// why do we need stringjoiner, stringbuilder        and tokenizer  (split words)  

import java.util.*;

public class Main
{
    public static void main(String[] args) {
        System.out.println("Welcome to Online IDE!! Happy Coding :)");
        
        
        //this works it has three words last sentence!!!
        //String text = "The quick brown fox jumps over the lazy dog";
        
        
        //this works, it has has two words last sentence......
        //String text = " This is a test but making it a bit longer!";
        
        // this works, it has single word only!!!!
        //String text = "My";
        
        
        String text = "My name is Amit Amlani. This is a sligthly longer test to see if the text can be spanned across multiple lines.";
        
        String lastLine="";
        int count=0;
        int k=16;
        String temp="";
        //String sentence;
        String tokentoString;
        String line;
        int wordCount=0;
        int lineLength;
        String lineBeforeLastWord="";
        int lengthLineBeforeLastWord;
        String completeLine="";
        String totalExtraPaddingBetweenWords;
        int extraPaddingBetweenWords=0;
        String temp1;
        int lengthfinalToken;
        int extraFrontPadding=0;
        String truncatedWord="";     
        String delimiter=" ";
        int wordIntoLineAfterTruncation=0;
        int buffer=0;
        int wordsLastLineNoTruncation=0;
        int completeLinelength=0;
        
        totalExtraPaddingBetweenWords=delimiter;
        
        String sentence="";
        StringJoiner sj = new StringJoiner(delimiter);
        StringJoiner sj1;
        StringJoiner sj2;
        int tokenLength;
        
        StringTokenizer st = new StringTokenizer(text, delimiter);
        StringTokenizer st1;
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb=new StringBuilder();
       
        while (st.hasMoreTokens())
        {
            //need be careful truncatedWord needs to be added once only, not each time the hasMoreTokens called...
            
            if (truncatedWord!="")
            {
                sb.append(truncatedWord);
                sj.add(sb);
                truncatedWord="";
                sb.delete(0,sb.length());
                wordIntoLineAfterTruncation++;
                
            }
            
            wordCount++;
            
            
            temp=st.nextToken();
            tokentoString = temp.toString();
            tokenLength=tokentoString.length();
            
            //System.out.println("aaaa:" + tokenLength);
            if (tokenLength>k)
            {
                System.out.println("The following character exceeds word limit of k" + "(" + k + "):  " + temp);
                System.exit(0);
            }
            
            sb.append(tokentoString);
            
            lineBeforeLastWord = sj.toString();
            
            sj.add(sb);
            sb.delete(0,sb.length());
            line = sj.toString();
            lineLength=line.length();
            
            System.out.println("your sentence getting bigger:" + line);
            
            wordIntoLineAfterTruncation++;
            
            System.out.println("ss: " + wordIntoLineAfterTruncation);
            
            //System.out.println("current length: " + lineLength);
            //System.out.println("number words: " + wordCount);
            
            //need to think about how to allocate spaces...
            //need to keep a count of the words
            
            //first thing is if the natural line has taken it over k,
            // need to truncate a word.....
            //count length of words...
            // subtract it from k....
            //if less than (wordCount-1)
            //pads at front....    (COMPLETE...)
            
            if (lineLength>k)
            {
                //need remove last token....
                //can not remember how I did that last time..remember
                
                //kept copy of stringjoiner...
                
                lengthLineBeforeLastWord= lineBeforeLastWord.length();
                
                System.out.println("rolled back:" + lineBeforeLastWord);
                //System.out.println("Length rolled back line: " + lengthLineBeforeLastWord);
                
                //wordCount;  
                
                //at this point there clearly is not enough buffer to allow an additional space between the characters...
                //it has to therefore force the spaces on the left hand side...
                
                //also, if it has rolled back, it needs to store a copy of the last word that was truncated...
                //otherwise nextToken will bypass it since it is already processed...
                truncatedWord=temp;
                
                System.out.println("this word getting cut off:" + truncatedWord);
                
                wordIntoLineAfterTruncation--;
                
                //wordIntoLineBeforeTruncation;
                
                buffer = k-lengthLineBeforeLastWord;
                
                //System.out.println("The current buffer is: " + buffer);
                //System.out.println("Number words to accomodate for: " + (wordCount-1));
                
                //The buffer (1) is less than number words (3)
                
                System.out.println("last word in tokenizer should be same as trunc word: " + temp);
                System.out.println("What is 12wordcount here: " + wordCount);
                System.out.println("What is truncated wordcount: " + wordIntoLineAfterTruncation +"(" + lineBeforeLastWord +")  " + lengthLineBeforeLastWord );
                System.out.println("The current buffer is: " + buffer);
                
                //note that for every 3 words, 2 spaces are required....
                //does this even make sense?
                // 16-14  this is correct   <   6   
                //logic is not right here at all
                
                //checking to see if there is vacant space on line
                //if it fills exactly length K the sentence, it does not qualify for padding...
                
                if (k-lengthLineBeforeLastWord>0)
                {
                    System.out.println("enter");
                
                // if extra spaces can go between words (such as two between words),
                //this is preferable than adding padding at front... as per requirements....
                //it is only possible if there is no remainder, so modulus will be taken...
                
                //System.out.println("words after truncation: " + wordIntoLineAfterTruncation);
                System.out.println("Buffer11: " + buffer);
                
                sj2 = new StringJoiner(" ");
                completeLine="";
                
                if (buffer%(wordIntoLineAfterTruncation-1)==0 && wordIntoLineAfterTruncation!=1)
                {
                    extraPaddingBetweenWords = buffer/(wordIntoLineAfterTruncation-1);
                
                System.out.println("Qualified for extra padding");
                
                 System.out.println(extraPaddingBetweenWords + " extra padding between:" + lineBeforeLastWord);
                
                        //***************** need to think which loop is this going in.... ****************
                        // it can be nested in one above, but not required....
                        
                  for (int j=0; j<=extraPaddingBetweenWords;j++)
                  {
                      totalExtraPaddingBetweenWords = totalExtraPaddingBetweenWords + " ";
                      
                  }
                  //System.out.println("terte extra: " + j);
                    //the only way to get extra spaces between the existing lineBeforeLastWord
                    // is to create another StringTokenizer with same delimiter " "
                    //Then to set up another StringJoiner with new delimiter as below...
                    // this is bit excessive since could have made the delimiter bigger in st1 instead..
                    //more room for error this way......
                    
                    System.out.println("It will now process truncated string with extra" + extraPaddingBetweenWords + " padding:" + lineBeforeLastWord);
                    
                    st1=new StringTokenizer(lineBeforeLastWord, delimiter); 
                    
                    sj2 = new StringJoiner(totalExtraPaddingBetweenWords); // it will now increase delimiter as above...
                    
                    
                    while (st1.hasMoreTokens())
                    {
                        //we know that all tokens will be part of the same line...
                        
                        temp1=st1.nextToken();
                        //sj2.add(temp);   // it has to also add the token that was removed from first string!!
                        sj2.add(temp1);
                        
                        completeLine=sj2.toString();
                        
                    }
                 
                } 
                
                else
                {
                    System.out.println(lineBeforeLastWord + " qualifies for padding at front since it has:" +  wordIntoLineAfterTruncation + " words");
                
                //all spaces appended at front to fill the buffer if 1 word in the line....
                
                sb1.append(lineBeforeLastWord);
                
                System.out.println("CURRENT LENGTH of line:" + lengthLineBeforeLastWord);
                
                
                // now its time to put padding in.....
                for (int b=0; b<buffer; b++)
                {
                    count++;
                    //since zero index, need to minus 1 from length....
                    sb1.insert(0," ");
                    //System.out.println(count + " padding added at front");
                    completeLine = sb1.toString();
                    
                    completeLinelength=completeLine.length();
                    
                //System.out.println("First line completed:" + completeLine);
                System.out.println("*********************");
                //System.out.println("Completed line to end user:" + completeLine);
                System.out.println("$$$$$$$$new length of line:$$$$$$$$$$ " + completeLinelength);
                
                }
                
                
                //at this point, it needs to wipe out all the contents in the stringjoiner
                // it also needs to keep temp back into it since this was last word that was 
                //discarded.
                sj.add(temp);
               
                }
                
                completeLinelength=completeLine.length();
                
                System.out.println("Completed line to end user1:" +completeLine);
                
                
                count=0;
                
                
                System.out.println("before reset, check values:");
                System.out.println(sj);
                System.out.println(sj2);
                 System.out.println(temp);
                 System.out.println(lastLine);
                 
                
                
                
                //reset all StringJoiners, delete all StringBuilders...
                 sj=new StringJoiner(" ");
                 //sj1=new StringJoiner(" ");
                 sj2=new StringJoiner(" ");
                 wordIntoLineAfterTruncation=0;
                totalExtraPaddingBetweenWords="";
                //wordIntoLineAfterTruncation=0;
                
                //it also has to remove contents of both StringBuilders....
                sb1.delete(0,sb1.length());
                sb.delete(0,sb.length());
                
                }
                
            }
            
            
        }   //end while (has more tokens)
        
        //unfortunately it will repeat several lines of the code above...
        //but not prepared to change the structure code too much.....
        //so need to check if it fits into k=16
        // and also need to add spaces in front if the word is shorter than k
        
        
        lastLine=sj.toString();
        
        
        // if there is nothing in the StringJoiner, it has to be given what is in temp?
        if (lastLine=="")
        {
            lastLine=temp;
        }
        
        System.out.println("WHAT IS LAST LINE: " + lastLine);
        
        
        int lengthLastLine = lastLine.length();
        
        try
        {
        while (!st.hasMoreTokens())
        {
            //need to think here
            // can there be two words here left over in StringJoiner, yes can be any length...
            //but what we know that it has hit the last token which is: lines
            
            //both same....
            System.out.println("wc:" + wordCount);
            System.out.println("wc1:" + wordIntoLineAfterTruncation);
            
            if (wordIntoLineAfterTruncation==0)
            {
                wordIntoLineAfterTruncation++;
            }
            
            //wordsLastLineNoTruncation = wordCount - wordIntoLineAfterTruncation;
            //System.out.println("wc2:" + wordsLastLineNoTruncation);
            
            System.out.println("The left over in StringJoiner:" + lastLine);
            System.out.println("words last line: " + wordIntoLineAfterTruncation);
            System.out.println("Total running words: " + wordCount);
            System.out.println("length: " + lengthLastLine);
            
            // We know content that is remaining will not form any part of truncation, since
            //it has been handled in all scenarios above....
            
            
            buffer=k-lengthLastLine;
            //extraPaddingBetweenWords = buffer%(wordIntoLineAfterTruncation-1);
            //require to minus 1 from word count since padding is divided in between words
            //i.e  3 words,  2 areas for padding....
            
            //System.out.println("padding:" + fa);
            
            System.out.println("Buffer is: " + buffer);
            
            if (buffer%(wordsLastLineNoTruncation-1)==0 && wordIntoLineAfterTruncation!=1 || wordIntoLineAfterTruncation!=0)
                {
                    extraPaddingBetweenWords = buffer/(wordIntoLineAfterTruncation-1);
                    
                    System.out.println("It will now process the string with extra: " + extraPaddingBetweenWords + " padding:" + lastLine);
                  
                        //***************** need to think which loop is this going in.... ****************
                        // it can be nested in one above, but not required....
                        
                  for (int j=0; j<=extraPaddingBetweenWords;j++)  
                  //note it has to process one extra since the convention is to put a space in between.
                  //hence j<=extraPaddingBetweenWords
                  
                  {
                      totalExtraPaddingBetweenWords = totalExtraPaddingBetweenWords + " ";
                      
                  }
                    //the only way to get extra spaces between the existing lineBeforeLastWord
                    // is to create another StringTokenizer with same delimiter ""
                    //Then to set up another StringJoiner with new delimiter as below...
                    //same as above for other lines....
                    
                    st1=new StringTokenizer(sj.toString(), " ");
                    sj = new StringJoiner(totalExtraPaddingBetweenWords);
                    
                    while (st1.hasMoreTokens())
                    {
                        //we know that all tokens will be part of the same line...
                        
                        temp1=st1.nextToken();
                        sj.add(temp1);   // it has to also add the token that was removed from first string!!
                        
                        completeLine=sj.toString();
                    }
                 
                } 
              
                else
                {
                    System.out.println("99SHOULD STAY OUT OF HERE!!!! unless 1 word");
                
                //all spaces appended at end to fill the buffer
                
                sb1.append(lastLine);
                
                for (int b=0; b<buffer; b++)
                {
                    count++;
                    //padding at end
                    sb1.insert(lengthLastLine," ");
                    
                }
                
                completeLine = sb1.toString();
                //System.out.println("First line completed:" + completeLine);
                
                //CAREFUL
                //System.out.println(completeLine);
                
                //No real housekeeping required of variables...
                //But it has to break out of the the do while loop since it will loop infinitely..
                
                }
          
        break;    
        }
    }
    
    catch (ArithmeticException e)
    {
        System.out.println("Most likely due to having one word in the sentence");
        
        sb1.append(temp);
        
        lengthLastLine=lastLine.length();
        
        buffer=k-lengthLastLine;
        
        System.out.println(lastLine + " qualifies for padding at end since it has:" +  wordIntoLineAfterTruncation + " word(s)");
        
                
                for (int b=0; b<buffer; b++)
                {
                
                    sb1.insert((lengthLastLine),"0");
                    
                    
                }
                
            System.out.println(lastLine + " qualifies for " + buffer + "padding at end since it has: " +  wordsLastLineNoTruncation + " words");
                
                completeLine = sb1.toString();
                //System.out.println("First line completed:" + completeLine);
                
                //CAREFUL
                //System.out.println(completeLine);
                //System.exit(0);
    }
        completeLinelength = completeLine.length();
        System.out.println("completed line to end user:" + completeLine);
        System.out.println("CURRENT LENGTH of line:" + completeLinelength);
        count=0;
        
    }
    
}
