package ru.yandex.autotests.direct.web.webelements;

import java.util.Calendar;
import java.util.Date;

import org.openqa.selenium.WebElement;

import ru.yandex.autotests.direct.web.util.DateHelper;
import ru.yandex.qatools.htmlelements.element.TypifiedElement;

/**
 * @author Roman Kuhta (kuhtich@yandex-team.ru)
 */
public abstract class AbstractCalendarInput extends TypifiedElement {
    protected AbstractCalendarInput(WebElement wrappedElement) {
        super(wrappedElement);
    }

    protected abstract CalendarPopupBlock getPopup();

    protected abstract WebElement getOpenPopupButton();

    public Date getDate() {
        return DateHelper.parseDate(getWrappedElement().getAttribute("value"));
    }

    protected abstract void fillDate(Date date);

    protected abstract class CalendarPopupBlock extends TypifiedElement {
        protected CalendarPopupBlock(WebElement wrappedElement) {
            super(wrappedElement);
        }

        protected abstract WebElement getTodayButton();

        protected abstract Year getYear();

        protected abstract Month getMonth();

        protected abstract WebElement getDayOfMonth(int day);

        public void fillDate(Date date) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            selectYear(cal.get(Calendar.YEAR));
            selectMonth(cal.get(Calendar.MONTH));
            selectDay(cal.get(Calendar.DAY_OF_MONTH));
        }

        public void selectYear(int year) {
            int selectedYear = this.getYear().getValue();
            if (selectedYear == year)
                return;
            if (selectedYear > year) {
                this.getYear().getSelectPrev().click();
                selectYear(year);
            }
            if (selectedYear < year) {
                this.getYear().getSelectNext().click();
                selectYear(year);
            }
        }

        public void selectMonth(int month) {
            int selectedMonth = this.getMonth().getValue();
            if (selectedMonth == month)
                return;
            if (selectedMonth > month) {
                this.getMonth().getSelectPrev().click();
                selectMonth(month);
            }
            if (selectedMonth < month) {
                this.getMonth().getSelectNext().click();
                selectMonth(month);
            }
        }

        public void selectDay(int day) {
            getDayOfMonth(day).click();
        }
    }

    protected abstract class Year extends TypifiedElement {
        protected Year(WebElement wrappedElement) {
            super(wrappedElement);
        }

        protected abstract WebElement getSelectPrev();

        protected abstract WebElement getSelectNext();

        protected abstract int getValue();
    }

    protected abstract class Month extends TypifiedElement {
        protected Month(WebElement wrappedElement) {
            super(wrappedElement);
        }

        protected abstract WebElement getSelectPrev();

        protected abstract WebElement getSelectNext();

        protected abstract int getValue();
    }
}
