/*
 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*global define, document, history, tau*/
/*jshint maxparams:7*/

/**
 * Module edit.
 */

define({
    name: 'views/edit',
    requires: [
        'core/event',
        'helpers/duration',
        'models/calendar',
        'models/date',
        'views/alarm',
        'views/popup'
    ],
    def: function viewsEdit(req) {
        'use strict';

        /**
         * Event module object.
         * @type {Object}
         */
        var e = req.core.event,
            /**
             * Duration module object.
             * @type {Object}
             */
            duration = req.helpers.duration,
            /**
             * Calendar module object.
             * @type {Object}
             */
            calendar = req.models.calendar,
            /**
             * Date module object.
             * @type {Object}
             */
            date = req.models.date,
            /**
             * Alarm module object.
             * @type {Object}
             */
            alarm = req.views.alarm,
            /**
             * Popup module object.
             * @type {Object}
             */
            popup = req.views.popup,
            /**
             * Currently edited event id.
             * @type {number}
             */
            currentId = 0,

            /**
             * Reference to the event type button.
             * @type {HTMLElement}
             */
            eventType = null;

        /**
         * Updates state of fields dependent on event type.
         * If the type is 'all day' then time fields should be hidden. Otherwise
         * time fields should be visible.
         * Type button should display name of type.
         */
        function updateTypeDependentFields() {
            var startTime = document.getElementById('event-start-time'),
                endTime = document.getElementById('event-end-time'),
                isAllDay = parseInt(eventType.dataset.value) === 1;

            if (isAllDay) {
                eventType.innerText = 'All day';
                startTime.classList.add('hidden');
                endTime.classList.add('hidden');
            } else {
                eventType.innerText = 'Period';
                startTime.classList.remove('hidden');
                endTime.classList.remove('hidden');
            }
        }

        /**
         * Handles click event on the event type button.
         */
        function onTypeClick() {
            var newValue = !Number(eventType.dataset.value);
            eventType.dataset.value = Number(newValue);
            updateTypeDependentFields();
        }

        /**
         * Handles start date change.
         * Checks if end date is greater than start date.
         */
        function onStartDateChanged() {
            var startDate = document.getElementById('event-start-date'),
                startTime = document.getElementById('event-start-time'),
                endDate = document.getElementById('event-end-date'),
                endTime = document.getElementById('event-end-time');

            if (startDate.value > endDate.value) {
                endDate.value = startDate.value;
            } else if (startDate.value === endDate.value &&
                startTime.value > endTime.value) {
                endTime.value = startTime.value;
            }
        }

        /**
         * Shows error popup.
         */
        function onDateError() {
            var pageId = tau.activePage.id;
            popup.show(pageId, 'End date cannot be earlier than start date.');
        }

        /**
         * Handles end date change.
         * Checks if end date is greater than start date.
         */
        function onEndDateChanged() {
            var startDate = document.getElementById('event-start-date'),
                startTime = document.getElementById('event-start-time'),
                endDate = document.getElementById('event-end-date'),
                endTime = document.getElementById('event-end-time');

            if (startDate.value > endDate.value) {
                onDateError();
                endDate.value = startDate.value;
                if (startTime.value > endTime.value) {
                    endTime.value = startTime.value;
                }
            } else if (startDate.value === endDate.value) {
                if (startTime.value > endTime.value) {
                    onDateError();
                    endTime.value = startTime.value;
                }
            }
        }

        /**
         * Assigns variables to page fields.
         * @param {string} summary
         * @param {boolean} type
         * @param {Date} startDate
         * @param {Date} endDate
         * @param {number} alarm
         */
        function assignToFields(summary, type, startDate, endDate, alarm) {
            var name = document.getElementById('event-name'),
                eventStartDate = document.getElementById('event-start-date'),
                eventStartTime = document.getElementById('event-start-time'),
                eventEndDate = document.getElementById('event-end-date'),
                eventEndTime = document.getElementById('event-end-time'),
                alarmValue = document.getElementById('event-alarm');

            name.value = summary;
            eventType.dataset.value = Number(type);
            eventStartDate.value = date.getDateString(startDate);
            eventStartTime.value = date.getTimeString(startDate);
            eventEndDate.value = date.getDateString(endDate);
            eventEndTime.value = date.getTimeString(endDate);
            alarmValue.innerHTML = duration.minutesToString(alarm);
            alarmValue.dataset.duration = alarm;

            updateTypeDependentFields();
        }

        /**
         * Shows event page and fills the fields.
         * @param {number} id Id of event to edit
         */
        function show(id) {
            var dateNow = new Date(),
                event = null,
                minutes = -1;

            currentId = id;

            if (currentId) {
                event = calendar.get(currentId);
                if (event.alarms.length) {
                    minutes = duration.durationToMinutes(
                        event.alarms[0].before
                    );
                }
                assignToFields(
                    event.summary,
                    event.isAllDay,
                    event.startDate,
                    event.endDate,
                    minutes
                );
            } else {
                assignToFields(
                    '',
                    false,
                    dateNow,
                    dateNow,
                    -1
                );
            }

            tau.changePage('#edit-page');
        }

        /**
         * Handles alarm set event.
         * @param {event} event
         */
        function onAlarmSet(event) {
            var alarmValue = document.getElementById('event-alarm'),
                minutes = Number(event.detail.duration);

            alarmValue.innerHTML = duration.minutesToString(minutes);
            alarmValue.dataset.duration = minutes;
        }

        /**
         * Handles set alarm button click.
         * Shows alarm page.
         */
        function onAlarmClicked() {
            var alarmValue = document.getElementById('event-alarm');
            alarm.show(alarmValue.dataset.duration);
        }

        /**
         * Handles save button click.
         * Adds event to calendar and moves to main page.
         */
        function onSaveClicked() {
            var name = document.getElementById('event-name').value,
                startDate = document.getElementById('event-start-date'),
                startTime = document.getElementById('event-start-time'),
                endDate = document.getElementById('event-end-date'),
                endTime = document.getElementById('event-end-time'),
                alarmValue = document.getElementById('event-alarm'),
                minutes = Number(alarmValue.dataset.duration),
                alarm = minutes >= 0 ? calendar.createAlarm(
                    duration.minutesToDuration(minutes)
                ) : null;

            if (currentId) {
                calendar.update(
                    currentId,
                    name,
                    parseInt(eventType.dataset.value, 10),
                    date.toTZDate(startDate.value, startTime.value),
                    date.toTZDate(endDate.value, endTime.value),
                    alarm
                );
            } else {
                calendar.add(
                    name,
                    parseInt(eventType.dataset.value, 10),
                    date.toTZDate(startDate.value, startTime.value),
                    date.toTZDate(endDate.value, endTime.value),
                    alarm
                );
            }
            history.back();
        }

        /**
         * Handles cancel button click.
         * Moves back to main page.
         */
        function onCancelClicked() {
            history.back();
        }

        /**
         * Binds events.
         */
        function bindEvents() {
            var startDate = document.getElementById('event-start-date'),
                startTime = document.getElementById('event-start-time'),
                endDate = document.getElementById('event-end-date'),
                endTime = document.getElementById('event-end-time'),
                alarmBtn = document.getElementById('event-alarm-set'),
                cancelBtn = document.getElementById('event-cancel'),
                saveBtn = document.getElementById('event-save');

            eventType.addEventListener('click', onTypeClick);
            startDate.addEventListener('input', onStartDateChanged);
            startTime.addEventListener('input', onStartDateChanged);
            endDate.addEventListener('input', onEndDateChanged);
            endTime.addEventListener('input', onEndDateChanged);
            cancelBtn.addEventListener('click', onCancelClicked);
            saveBtn.addEventListener('click', onSaveClicked);
            alarmBtn.addEventListener('click', onAlarmClicked);
        }

        /**
         * Initializes module.
         */
        function init() {
            eventType = document.getElementById('event-type');
            bindEvents();
        }

        e.listen('views.alarm.selected', onAlarmSet);

        return {
            init: init,
            show: show
        };
    }
});
