package ru.vsu.cs.solution;

import java.util.ArrayList;
import java.util.List;

public class MyList<Integer> {


    private MyListItem<Integer> head = null;
    private MyListItem<Integer> tail = null;
    private int count = 0;

    public static MyList<java.lang.Integer> convertLinkedListToArray(int[] arr) throws Exception {
        MyList<java.lang.Integer> list = new MyList<>();
        for (int i = 0; i < arr.length; i++) {
            list.add(arr[i]);
        }
        return list;
    }

    private static int myComparator(int a, int b) {
        if (a > b) {
            return 1;
        }
        return 0;
    }


    public void del() {
        if (head.next == null || head == null) {
            return;
        }
        while ((int) head.value % 2 == 0 && (int) head.next.value % 2 == 0) {
            head = head.next;
            count--;
            if (head.next == null) {
                tail = head;
                return;
            }
        }
        MyListItem curr = head;
        MyListItem next = head.next;
        int del = 0;
        while (curr.next != null) {
            if ((int) curr.next.value % 2 == 0) {
                if (del == 0) {
                    next = curr;
                }
                del += 1;
                curr = curr.next;
            } else if ((int) curr.next.value % 2 == 1) {
                if (del > 1) {
                    next.next = curr;
                    count -= del;
                }
                curr = curr.next;
            }
            if (del > 1) {
                next.next = curr;
                count -= del;
            }
        }
        tail = curr;
    }


    public int[] convertLinkedListToArray() {
        List<java.lang.Integer> list = new ArrayList<>();

        while (head != null) {
            list.add((java.lang.Integer) head.value);
            head = head.next;
        }

        int[] array = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            array[i] = list.get(i);
        }
        return array;
    }

    private void checkEmpty() throws Exception {
        if (isEmpty()) {
            throw new Exception("List is empty");
        }
    }

    public Integer getFirst() throws Exception {
        checkEmpty();
        return head.value;
    }

    private void setFirst(Integer value) {
        head = new MyListItem<>(value, head.next);
    }

    public Integer getLast() throws Exception {
        checkEmpty();
        return tail.value;
    }

    private void setLast(Integer value) {
        tail = new MyListItem<>(value);
    }

    private void addFirst(Integer value) {
        head = new MyListItem<>(value, head);
        if (tail == null) {
            tail = head;
        }
        count++;
    }

    private void addLast(Integer value) {
        if (tail == null) {
            head = tail = new MyListItem<>(value);
        } else {
            tail = tail.next = new MyListItem<>(value);
        }
        count++;
    }


    public void clear() {
        head = tail = null;
        count = 0;
    }

    public int size() {
        return count;
    }

    public boolean isEmpty() {
        return size() == 0;
    }

    public void add(int index, Integer value) throws Exception {
        if (index < -1 || index > count) {
            throw new Exception("Incorrect index");
        }
        if (index == 0) {
            addFirst(value);
        } else if (index == -1) {
            addLast(value);
        } else {
            MyListItem<Integer> prev = getItem(index - 1);
            prev.next = new MyListItem<>(value, prev.next);
            if (prev.next.next == null) {
                tail = prev.next;
            }
            count++;
        }
    }

    public void set(int index, Integer value) throws Exception {
        if (index < -1 || index > count) {
            throw new Exception("Incorrect index");
        }
        if (index == 0) {
            setFirst(value);
        } else if (index == -1) {
            setLast(value);
        } else {
            MyListItem<Integer> prev = getItem(index - 1);
            if (index + 1 < count) {
                prev.next = new MyListItem<>(value, getItem(index + 1));
            } else {
                prev.next = new MyListItem<>(value, null);
            }
        }
    }

    public void add(Integer value) throws Exception {
        if (count == 0) {
            addFirst(value);
        } else {
            MyListItem<Integer> prev = getItem(count - 1);
            prev.next = new MyListItem<>(value, prev.next);
            tail = prev.next;
            count++;
        }
    }


    public void sorted(MyList<java.lang.Integer> list) throws Exception {
        for (int i = 1; i < list.size(); i++) {
            int value = list.get(i);
            int j;
            for (j = i - 1; j >= 0 && (myComparator(list.get(j), value)) > 0; j--) {
                list.set(j + 1, list.get(j));     // сдвигаем элемент направо, пока не дошли 
            }
            list.set(j + 1, value);
        }
    }

    public Integer get(int index) throws Exception {
        return getItem(index).value;
    }

    private MyListItem<Integer> getItem(int index) throws Exception {
        if (index < 0 || index > size()) {
            throw new Exception("Incorrect index");
        } else {
            MyListItem<Integer> curr = head;
            for (int i = 0; i < index; i++) {
                curr = curr.next;
            }
            return curr;
        }
    }

    public void removeFirst() {
        head = head.next;
        if (head == null) {
            tail = null;
        }
        count--;
    }

    public void removeLast() throws Exception {
        checkEmpty();

        if (count == 1) {
            removeFirst();
        } else {
            tail = getItem(size() - 2);
            tail.next = null;
            count--;
        }
    }


    public void remove(int index) throws Exception {
        if (index < 0 || index > size()) {
            throw new Exception("Incorrect index");
        }
        if (index == 0) {
            removeFirst();
        } else if (index == size()) {
            removeLast();
        } else {
            MyListItem<Integer> prev = head;
            for (int i = 0; i < index - 1; i++) {
                prev = prev.next;
            }
            prev.next = prev.next.next;
            if (prev.next == null) {
                tail = prev;
            }
            count--;
        }
    }

    public int solve() {
        MyListItem<Integer> curr = head;
        while (head != null && (int) curr.value % 2 == 0) {
            head = head.next;
        }
        int maxCurrent = 1;
        int current = 1;
        while (curr.next != null) {
            if (curr.value == curr.next.value) {
                current++;
            } else if (maxCurrent < current) {
                maxCurrent = current;
                current = 1;
            }
            curr = curr.next;

        }
        return 0;
    }

    public void deleteUneven(MyList<java.lang.Integer> list) {
        MyListItem<Integer> curr = head;
        for (int i = 0; i < count; i++) {
            if ((int) curr.value % 2 == 1) {
                if (i == 0) {
                    head = head.next;
                } else {
                    MyListItem<Integer> prev = head;
                    for (int j = 0; j < i; j++) {
                        if (j == i - 1) {
                            if (prev.next == tail) {
                                tail = prev;
                                tail.next = null;
                            } else {
                                prev.next = prev.next.next;
                            }
                        }
                        prev = prev.next;
                    }
                }
                i--;
                count--;
            }
            curr = curr.next;
        }
    }

    public void deletePovtor() {
        MyListItem<Integer> curr = head;
        while (curr.next != null) {
            if (curr.value == curr.next.value) {
                curr.next = curr.next.next;
                count--;
            } else {
                curr = curr.next;
            }
        }
    }

    public void deleteElementForKToTail(int k) {
        MyListItem<Integer> curr = head;
        if (k >= count) {
            head = tail = head.next = null;
            count = 0;
            return;
        }
        for (int i = 1; i < k - 1; i++) {
            curr = curr.next;
        }
        int del = count - k;
        tail = curr.next;
        tail.next = null;
        count -= del;
    }

    public void deleteElementK(int k) {
        MyListItem<Integer> curr = head;
        if (k < size()) {
            head = tail = head.next = null;
            count = 0;
            return;
        }
        for (int i = 0; i < k - 1; i++) {
            curr = curr.next;
        }
        int del = count - k;
        tail = curr.next;
        tail.next = null;
        count -= del;
    }

    private class MyListItem<Integer> {
        public Integer value;
        public MyListItem<Integer> next;

        public MyListItem(Integer value, MyListItem<Integer> next) {
            this.value = value;
            this.next = next;
        }

        public MyListItem(Integer value) {
            this(value, null);
        }

    }
} переделай под циклический список