

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import java.util.StringTokenizer;


public class ShoppingList {

    public static final int maxItems = 100;     //max array size
    private static int countItems = 0;          //countItems keep track of the item
    private String fileName = "shopping.dat";
    //Item reference array
    private Item items[] = new Item[maxItems];;

    // Flag that tracks changes
    private boolean upToDate;

    //default constructor
    public ShoppingList()
    {
        try
        {
            readFile();         //laod the file by calling readFile method
            upToDate = true;    //set upToDate to true that mean the list not yet change
        }
        catch(Exception e){e.printStackTrace();}
    } // Constructor

    //readFile method
    public void readFile() throws IOException
    {
        String descr,line = null,token = null;
        StringTokenizer st= null;
        double cost;
        int quan;
        File file = new File(fileName);
        Scanner scanner = new Scanner(file);
        while (scanner.hasNextLine()) {                                 //loop through the file
            line = scanner.nextLine();                                  // read the first line
            st = new StringTokenizer(line," ");                         //split by space
            cost = Double.parseDouble(st.nextElement().toString());     //get first token and parse it to double
            quan = Integer.parseInt(st.nextElement().toString());       //get second token and parse it to int
            descr = st.nextElement().toString();                        //get third token and parse it to int
            addItem(descr,cost,quan);                                   //call addItem method
        }
    }

    public void addItem(String descr, double cost, int quan) throws IOException //add object item to the array
    {
        int index = getItemRow(descr);  // see if the item exist if exist it will return the row index if not -1
        if( index != -1)                //if not exist insert new item
        {
            ((Item)items[index]).setQuantity(((Item)items[index]).getQuantity()+quan);
        }
        else                            // if exist change the cost and increase the quantity by adding the new + the old quantity
        {
            if(items.length < countItems)
            {
                ((Item)items[index]).setCost(cost);
                ((Item)items[index]).setDescription(descr);
                ((Item)items[index]).setQuantity(quan);
                //items[countItems] = new Item(descr, cost, quan); //store the Item object in to item array
                countItems++;                                   //increment countItems by 1
            }
            else
            {
                System.out.println("Item Can not be added since the array is full");
            }
            
        }
        upToDate = false;
    }

    public int getItemRow(String descr) // method to check if the item exist if exist return the index else -1
    {
        for(int i=0;i<countItems;i++)
        {
            if(descr.equalsIgnoreCase(((Item)items[i]).getDescription()))
            {
                return i;
            }
        }
        return -1;
    }

    public void output()
    {
        System.out.println("Item Cost\tQuantity\tDescription" );
        System.out.println("==================================================" );

        for(int i=0;i<countItems;i++) //loop throuh the array and get the object then downcast it to get the item and print details
        {
            System.out.println("     "+((Item)items[i]).getCost()+"\t"+((Item)items[i]).getQuantity()+"\t\t"+((Item)items[i]).getDescription());
        }
        System.out.println("==================================================" );
        System.out.println(" ");
    }

    public double totalCost()
    {
        double total = 0;
        for(int i=0;i<countItems;i++) //loop throuh the array and get the object then downcast it to get the cost for eacj item one by one
        {
            total = total +((Item)items[i]).getCost(); //add the privous value and the new value and save it again in total variable
        }
        return total;

    }

    public void save() //save the changes (create new file)
    {
         FileWriter fstream;
        try {
            fstream = new FileWriter(fileName);
            BufferedWriter out = new BufferedWriter(fstream);
            for(int i=0;i<countItems;i++)
            {
                out.write(((Item)items[i]).getCost()+" "+((Item)items[i]).getQuantity()+"  "+((Item)items[i]).getDescription());
                out.newLine(); //new line
            }
            upToDate = true;    // true that mean list up to date
            out.close();        //close BufferedWriter to reflect the changes
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public boolean isUpToDate()
    {
        return upToDate;    //return upToDate value
    }

}
