/*
 * Copyright (c) 2014 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*/

/**
 * Month module.
 *
 * @requires {@link helpers/date}
 * @namespace models/month
 * @memberof models
 */
define({
    name: 'models/month',
    requires: [
        'helpers/date'
    ],
    def: function modelsMonth(d) {
        'use strict';

        /**
         * Count of days in one week.
         *
         * @private
         * @const {number}
         */
        var DAYS_IN_WEEK = 7;

        /**
         * Prepares data array with date.
         *
         * @private
         * @param {object} date
         * @param {number} day
         * @param {number} shift Month shift.
         * @returns {object}
         */
        function getDayData(date, day, shift) {
            var newDate = d.clone(date);

            if (shift) {
                newDate.setMonth(date.getMonth() + shift);
            }
            newDate.setDate(day);

            return {
                'day': day,
                'dateString': d.toDataString(newDate),
                'inactive': shift ? 'inactive' : ''
            };
        }

        /**
         * Creates matrix of days in months.
         * Example: [ [29,30,1,2,3,4,5], [6,7,8,9,10,11,12], ...]
         *
         * @memberof models/month
         * @public
         * @param {Date} date Date object.
         * @returns {number[][]} daysMatrix Days matrix.
         */
        function getDaysMatrix(date) {
            var daysNumber = d.daysInMonth(date),
                daysPad = d.getFirstDay(date),
                previous = d.getPreviousMonth(date),
                previousDaysNumber = d.daysInMonth(previous),
                rowsLength = Math.ceil((daysNumber + daysPad) / DAYS_IN_WEEK),
                data = [],
                daysMatrix = [],
                start = 0,
                next = 1,
                i = 1,
                j = 0,
                dayNumber = -1;

            // previous month days fill
            while (daysPad) {
                daysPad -= 1;
                data.push(getDayData(date, previousDaysNumber - daysPad, -1));
            }

            // current month days
            for (i = 1; i <= daysNumber; i = i + 1) {
                data.push(getDayData(date, i, 0));
            }

            dayNumber = data.length % DAYS_IN_WEEK;
            // next month days fill
            while (dayNumber) {
                dayNumber = data.push(getDayData(date, next, 1)) % DAYS_IN_WEEK;
                next += 1;
            }

            for (j = 0; j < rowsLength; j = j + 1) {
                start = j * DAYS_IN_WEEK;
                daysMatrix.push(data.slice(start, start + DAYS_IN_WEEK));
            }

            return daysMatrix;
        }

        return {
            getDaysMatrix: getDaysMatrix
        };
    }

});
