package mypi.service;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collections;
import java.util.Iterator;
import mypi.IO.FileReadAndWrite;
import mypi.pojo.Events;

/**
 *
 * @author trav custom linked list that holds Events.java
 *
 */
public class EventLinkedList extends FileReadAndWrite implements Iterable<Events>, Serializable {

    private class Node implements Serializable {

        Events event;
        Node next;

        public Node(Events event) {
            this(event, null);
        }

        public Node(Events event, Node next) {
            this.event = event;
            this.next = next;
        }
    }//end node class

    /**
     * Allows enhacned for loop to be used on this List
     *
     * @return
     */
    @Override
    public Iterator<Events> iterator() {
        if (start == null) {
            return Collections.<Events>emptyList().iterator();
        }
        return new Iterator<Events>() {
            private Node currentNode = start;

            @Override
            public boolean hasNext() {
                return currentNode != null;
            }

            @Override
            public Events next() {
                if (currentNode == null) {

                }
                Events toReturn = currentNode.event;
                currentNode = currentNode.next;
                return toReturn;
            }

        };
    }

    private Node start;
    private static EventLinkedList uniqueEventList = new EventLinkedList();
//    public EventLinkedList() {
//        start = null;
//    }
    private EventLinkedList() {
        if (!getFile().exists()) {
            start = null;
        } else {//meaning file does exsist so there is eventList in the file
            try (ObjectInputStream inputObject = getObjectInputStream()) {
                uniqueEventList = (EventLinkedList) inputObject.readObject();
                start=uniqueEventList.start;//setting start
            } catch (IOException | ClassNotFoundException ex) {
                System.out.println("List is loaded");
            }
        }//end of else
    }

    public static EventLinkedList instanceOf() {
        return uniqueEventList;
    }
    
    private void writeEventListToFile() {
        try (ObjectOutputStream sendToFile = getObjectOutputStream()) {
            sendToFile.writeObject(uniqueEventList);
        } catch (IOException io) {
            System.out.println("COULD NOT Write To File Error Check File path?!!");
        }
    }

    /**
     * removes specified event object by its toString
     *
     * @param eventToString
     */
    public void remove(String eventToString) {
        Node currentNode = start;
        if (currentNode.event.toString().equals(eventToString)) {
            start = start.next;
            writeEventListToFile();
            return;
        }
        Node previousNode = null;

        while (currentNode != null && !currentNode.event.toString().equals(eventToString)) {
            previousNode = currentNode;
            currentNode = currentNode.next;
        }//ends while when currentNode equals eventToString 

        if (currentNode == null) {//no node was found
            return;
        }
        //erasing the event in the list
        previousNode.next = currentNode.next;
        writeEventListToFile();//writing to file after removing
    }

    /**
     *
     * method will keep event object sorted during the add process
     *
     * @param event
     *
     *
     */
    public void add(Events event) {
        if (start == null) {
            start = new Node(event);
        } else if (event.compareTo(start.event) <= -1) {//seeing if new event is before the current sorted event
            start = new Node(event, start);

        } else {
            Node nodePointer = start;
            //finding the location where @param event fits in sorted order
            while (nodePointer.next != null && event.compareTo(nodePointer.next.event) > 0) {
                nodePointer = nodePointer.next;
            }//end while   
            nodePointer.next = new Node(event, nodePointer.next);
        }
        writeEventListToFile();//writing list to file after adding
    }


    public String toString() {
        StringBuilder formListString = new StringBuilder();
        if (start == null) {
            return "List is empty";
        } else {
            Node currentNode = start;
            while (currentNode != null) {
                formListString.append(currentNode.event.toString());
                currentNode = currentNode.next;
                if (currentNode != null) {//handles the last element in the list
                    formListString.append(", ");
                }
            }

        }
        return formListString.toString();
    }

}//end event linked list

@@ -495,24 +495,82 @@
 izable %7B%0D%0A%0D%0A
+        private static final long serialVersionUID = 1L;%0D%0A
         Even
@@ -572,32 +572,32 @@
  Events event;%0D%0A
-
         Node nex
@@ -1713,74 +1713,89 @@
 );%0D%0A
-//
     p
-ublic EventLinkedList() %7B%0D%0A//        start = null
+rivate static final long serialVersionUID = 1L;%0D%0A    private int size
 ;%0D%0A
-//
     
-%7D
 %0D%0A  
@@ -2182,16 +2182,74 @@
  start%0D%0A
+                size=uniqueEventList.size;//setting size%0D%0A
         
@@ -2496,32 +2496,94 @@
 ;%0D%0A    %7D%0D%0A    %0D%0A
+    public int getSize()%7B%0D%0A        return size;%0D%0A    %7D%0D%0A    %0D%0A
     private void
@@ -3203,24 +3203,45 @@
 tToFile();%0D%0A
+            size--;%0D%0A
             
@@ -3708,32 +3708,49 @@
 rentNode.next;%0D%0A
+        size--;%0D%0A
         writeEve
@@ -4210,18 +4210,16 @@
 tart);%0D%0A
-%0D%0A
         
@@ -4579,24 +4579,24 @@
 ter.next);%0D%0A
-
         %7D%0D%0A 
@@ -4586,32 +4586,49 @@
 t);%0D%0A        %7D%0D%0A
+        size++;%0D%0A
         writeEve

update EventLinkedList