/*
 * Licensed Materials - Property of IBM
 * 
 * IBM Cognos Products: SHARE
 * 
 * (C) Copyright IBM Corp. 2015, 2017
 * 
 * US Government Users Restricted Rights - Use, duplication or disclosure
 * restricted by GSA ADP Schedule Contract with IBM Corp.
 */
define([
        'bi/schedule/views/CadencePickerView',
        'bi/schedule/app/appControler',
        'jquery',
        'bi/sharecommon/utils/translator',
        'q',
        'bi/sharecommon/utils/simpledoT',
        'bi/commons/utils/ContentFormatter',
        'text!bi/schedule/templates/WeeklyCadencePicker.html',
        'underscore',
        'moment-timezone',
    "bi/schedule/views/DailyIntervalCadencePickerView"
    ],
    function (View, controler, $, t, Q, dot, stringFormatter, template, _, moment, DailyIntervalCadencePicker) {
        'use strict';

        var weeklyCadence = View.extend({
        	isEditMode: false,
            buttonClassName: [
                'weeklySunday',
                'weeklyMonday',
                'weeklyTuesday',
                'weeklyWednesday',
                'weeklyThursday',
                'weeklyFriday',
                'weeklySaturday'
            ],
            dayNumberMap: {
            	'weeklySunday': 0,
                'weeklyMonday': 1,
                'weeklyTuesday': 2,
                'weeklyWednesday': 3,
                'weeklyThursday': 4,
                'weeklyFriday': 5,
                'weeklySaturday': 6
            },

            /**
             * @constructor
             */
            init: function(options) {
                weeklyCadence.inherited('init', this, arguments);
                $.extend(this, options);

                if(typeof this.objectInformation.descriptor !== "undefined") {
                    this.scheduleInfo = this.objectInformation.descriptor.scheduleInfo;
                    this.isEditMode = true;
                }
                this.readOnly = false;
                this.timezone = this.glassContext.services.userProfile.preferences.timeZoneID;
            },

            /**
             * Render the new schedule view day picker section
             * 
             */
            render: function() {
                var deferred = Q.defer();

                var htmlGenerator = dot.simpleTemplate(template);
                var defaultPeriod = 1;
                if (typeof this.scheduleInfo !== 'undefined' && this.scheduleInfo.everyNPeriods > 1) {
                    defaultPeriod = this.scheduleInfo.everyNPeriods;
                }
                this.readOnly = this.isEditMode && this.hasPermission && !this.hasPermission.write && this.hasPermission.read;
                
                var attributes = {
                    weekly_cadence_buttons_description: t.translate('weekly_cadence_buttons_description'),
                    schedule_run_every_label: t.translate("schedule_run_every_label"),
                    schedule_run_every_week_label: t.translate("schedule_run_every_week_label"),
                    schedule_weekly_on_days_label: t.translate("schedule_weekly_on_days_label"),
                    schedule_every_weeks_value: defaultPeriod,
                    schedule_weekday_Sunday: t.translate("schedule_run_on_the_sun_label"),
                    schedule_weekday_Saturday: t.translate("schedule_run_on_the_sat_label"),
                    schedule_weekday_Friday: t.translate("schedule_run_on_the_fri_label"),
                    schedule_weekday_Thursday: t.translate("schedule_run_on_the_thu_label"),
                    schedule_weekday_Wednesday: t.translate("schedule_run_on_the_wed_label"),
                    schedule_weekday_Tuesday: t.translate("schedule_run_on_the_tue_label"),
                    schedule_weekday_Monday: t.translate("schedule_run_on_the_mon_label"),                    
                    schedule_weekday_button_Sunday: t.translate("schedule_weekday_button_Sunday_t"),
                    schedule_weekday_button_Saturday: t.translate("schedule_weekday_button_Saturday_t"),
                    schedule_weekday_button_Friday: t.translate("schedule_weekday_button_Friday_t"),
                    schedule_weekday_button_Thursday: t.translate("schedule_weekday_button_Thursday_t"),
                    schedule_weekday_button_Wednesday: t.translate("schedule_weekday_button_Wednesday_t"),
                    schedule_weekday_button_Tuesday: t.translate("schedule_weekday_button_Tuesday_t"),
                    schedule_weekday_button_Monday: t.translate("schedule_weekday_button_Monday_t"),
                    run_everyid: _.uniqueId(),
                    showRunEvery: this.objectInformation.showRunEvery
                };
                this.$el.append(htmlGenerator(attributes));
                this._setDay();
                
                if(this.objectInformation.showDailyInterval) {
                    this.dailyInterval = new DailyIntervalCadencePicker({
                        $el: this.$el,
                        objectInformation: {
         					descriptor: this.objectInformation.descriptor,
         					showDailyIntervalCheckbox: true
         					},
         				glassContext: this.glassContext,
         				readOnly: this.readOnly
                    });
                    this.dailyInterval.render();
                }
                
                // in update mode the permissions are passed
                if ( this.readOnly ) {
                    for(var i=0; i<this.buttonClassName.length; i++) {
                        this.$el.find('.' + this.buttonClassName[i]).prop('disabled', true);
                    }
                }

                stringFormatter.middleShortenString(this.$el.find('.weekly_on_days_label'));
                
                this._setEvents();

                deferred.resolve(this);
                return deferred.promise;
            },

            /** All views should overwrite this function.
             * It takes a partially populated json schedule descriptor and adds to it 
             * based on the properties of this view.
             * @param desc the partial JSON schedule descriptor
             * @returns the descriptor passed in, with added attributes.
             */
            toDescriptor: function(descriptor) {
                // compute the day of the week 
                var weekly = {
                    weeklySunday: false,
                    weeklyMonday: false,
                    weeklyTuesday: false,
                    weeklyWednesday: false,
                    weeklyThursday: false,
                    weeklyFriday: false,
                    weeklySaturday: false
                };

                for (var key in weekly) {
                    if (this.$el.find("." + key).hasClass("selectedButton")) {
                        weekly[key] = true;
                    }
                }
                descriptor.weekly = weekly;

                var everyNPeriods = (this.objectInformation.showRunEvery) ? parseInt(this.$el.find('.schedule_every_weeks_input').val(), 10) : 1;
                descriptor.everyNPeriods = everyNPeriods;

                // set type
                descriptor.type = "weekly";

                 // set time or daily interval
                 if(this.dailyInterval) {
                     descriptor = this.dailyInterval.toDescriptor(descriptor);
                 }

                return descriptor;
            },
            
            validate: function(msgs) {
                if(this.dailyInterval) {
                    msgs = this.dailyInterval.validate(msgs);
                    // One warning at a time
                    if ( msgs.length > 0) {
                    	return msgs;
                    }
                }                
                var parameters = {};
                var $everyNPeriodDiv = this.$el.find(".schedule_frequency_input_container");
                $everyNPeriodDiv.removeAttr('aria-invalid aria-describedby');
                var everyNPeriods = (this.objectInformation.showRunEvery) ? parseInt(this.$el.find('.schedule_every_weeks_input').val(), 10) : 1;
                if ( isNaN(everyNPeriods) || everyNPeriods === 0 ) {
 					parameters.param1 = t.translate("schedule_run_every_label");
 					parameters.param2 = t.translate("schedule_run_every_week_label");
 					msgs.push(t.translate("schedule_invalid_form_input", parameters));
 					$everyNPeriodDiv.attr({
						'aria-invalid': 'true',
						'aria-describedby': msgs[0]
					});
                }
                return msgs;
            },

            _setEvents: function() {
                var btnHandler = function(e) {
                    /* Handle button clicked event
                     When button clicked, the background color should change
                     */
                    var btnClassNames = e.currentTarget.className.split(/\s+/);
                    for (var i = 0; i < btnClassNames.length; i++) {
                        if (btnClassNames[i].indexOf('weekly')===0) {
                            this._toggleWeekday(btnClassNames[i]);
                        }
                    }

                }.bind(this);

                for(var i=0; i<this.buttonClassName.length; i++) {
                    this.$el.find('.' + this.buttonClassName[i]).on('clicktap', btnHandler);
                }
                
                $('.schedule_every_weeks_input').on('input', function (event) { 
                    this.value = this.value.replace(/[^0-9]/g, '');
                });
            },

            _setDay: function() {
                var hasDays = false;
                if(typeof this.scheduleInfo !== 'undefined' && this.scheduleInfo.weekly) {
                    for(var day in this.scheduleInfo.weekly) {
                        if (this.scheduleInfo.weekly[day] === true) {
                        	var converted = this._convertTimezone(this.dayNumberMap[day]);
                        	this._toggleWeekday(this.buttonClassName[converted]);
                            hasDays = true;
                        }
                    }
                }

                // Select the current day if no other days were selected
                if(!hasDays) {
                    var currentDayNumber = moment().tz(this.timezone).day();
                    this._toggleWeekday(this.buttonClassName[currentDayNumber]);
                }
            },
            
            // takes a day number in the original timezone, and returning the day number
            // in the new timezone.
            _convertTimezone: function(day) {
            	// calculate the difference in days between source and target timezones
            	
            	var sourceDay = moment(this.scheduleInfo.startDate).tz(this.scheduleInfo.timezone).day();
            	var targetDay = moment(this.scheduleInfo.startDate).tz(this.timezone).day();
            	
            	var newDay = day + (targetDay - sourceDay);

            	if(newDay < 0) {
            		newDay = newDay + 7;
            	}
            	else if(newDay > 6) {
            		newDay = newDay - 7;
            	}
            	
            	return newDay;            	
            },

            /*highlight the button when a button is selected or it is the day of the week
             */
            _toggleWeekday: function(buttonclassName) {
                var aButtonclassName = "." + buttonclassName;
                var $button = this.$el.find(aButtonclassName);
                if ($button.hasClass('selectedButton')) {
                    if (this.$el.find(".selectedButton").length > 1 ) {
                    	$button.removeClass('selectedButton');
                    	$button.attr("aria-pressed", "false");
                    }
                } else {
                	$button.addClass('selectedButton');
                	$button.attr("aria-pressed", "true");
                }
            }
        });

        return weeklyCadence;
    });