-View = require '../lib/view'
-AlarmFormView = require './alarm_form_view'
-AlarmPopOver = require './alarm_popover'
-AlarmsListView = require '../views/alarms_list_view'
-EventPopOver = require './event_popover'
-helpers = require '../helpers'
+app = require 'application'
+BaseView = require '../lib/base_view'
+AlarmPopOver = require './calendar_popover_alarm'
+EventPopOver = require './calendar_popover_event'
+helpers = require 'helpers'
 timezones = require('helpers/timezone').timezones
 
-Alarm = require '../models/alarm'
-Event = require '../models/event'
-formSmallTemplate = {}
-formSmallTemplate.alarm = require('./templates/alarm_form_small')
-formSmallTemplate.event = require('./templates/event_form_small')
-
-
-module.exports = class CalendarView extends View
-
-    el: '#viewContainer'
-
-    initialize: (alarm, evt) ->
-        @caldata = {}
-        @model.alarm = alarm
-        @model.event = evt
-        @listenTo @model.alarm, 'add', @onAddAlarm
-        @listenTo @model.alarm, 'reset', @onResetAlarm
-        @listenTo @model.event, 'add', @onAddEvent
-        @listenTo @model.event, 'reset', @onResetEvent
-
-    template: ->
-        require('./templates/calendarview')
+Alarm = require 'models/alarm'
+Event = require 'models/event'
+# formSmallTemplate = {}
+# formSmallTemplate.alarm = require('./templates/alarm_form_small')
+# formSmallTemplate.event = require('./templates/event_form_small')
+
+
+module.exports = class CalendarView extends BaseView
+
+    id: 'viewContainer'
+    template: require('./templates/calendarview')
+
+    initialize: (options) ->
+        @alarmCollection = @model.alarms
+        @listenTo @alarmCollection, 'add'  , @refresh
+        @listenTo @alarmCollection, 'reset', @refresh
+        @listenTo @alarmCollection, 'remove', @onRemove
+        @listenTo @alarmCollection, 'change', @refreshOne
+
+        @eventCollection = @model.events
+        @listenTo @eventCollection, 'add'  , @refresh
+        @listenTo @eventCollection, 'reset', @refresh
+        @listenTo @eventCollection, 'remove', @onRemove
+        @listenTo @eventCollection, 'change', @refreshOne
+        @model = null
 
     afterRender: ->
-        @cal = @$('#alarms').fullCalendar
+        locale = Date.getLocale(app.locale) # thanks sugarjs
+        @cal = @$('#alarms')
+        @cal.fullCalendar
             header:
                 left: 'prev,next today'
                 center: 'title'
-                right: 'month,agendaWeek,agendaDay'
+                right: 'month,agendaWeek'
             editable: true
-            firstDay: 1 # first day of the week is monday ffs
+            firstDay: 1 # first day of the week is monday
             weekMode: 'liquid'
-            aspectRatio: 2.031
-            defaultView: 'month'
-            columnFormat:
-                month: 'dddd'
-                week: 'ddd dd/MM'
-                day: 'dddd dd/MM'
+            height: @handleWindowResize('initial') # initial ratio
+            defaultView: @options.view
+            viewDisplay: @onChangeView # beware, deprected in next FC
+
+            #i18n by SugarJs
+            monthNames: locale.full_month.split('|').slice(1,13)
+            monthNamesShort: locale.full_month.split('|').slice(13, 26)
+            dayNames: locale.weekdays.slice(0, 7)
+            dayNamesShort: locale.weekdays.slice(0, 7)
+            buttonText:
+                today: locale.day.split('|')[1]
+                month: locale.units[6]
+                week:  locale.units[5]
+                day:   locale.units[4]
+
             timeFormat:
-                '': 'HH:mm'
-                'agenda': 'HH:mm{ - HH:mm}'
-            axisFormat: 'HH:mm'
-            buttonText:
-                today: t 'Today'
-                month: t 'Month'
-                week:  t 'Week'
-                day:   t 'Day'
-            dayNames : [
-                t 'Sunday'
-                t 'Monday'
-                t 'Tuesday'
-                t 'Wednesday'
-                t 'Thursday'
-                t 'Friday'
-                t 'Saturday']
-            dayNamesShort: [
-                t 'Sun'
-                t 'Mon'
-                t 'Tue'
-                t 'Wed'
-                t 'Thu'
-                t 'Fri'
-                t 'Sat']
-            monthNames: [
-                t 'January'
-                t 'February'
-                t 'March'
-                t 'April'
-                t 'May'
-                t 'June'
-                t 'July'
-                t 'August'
-                t 'September'
-                t 'October'
-                t 'November'
-                t 'December']
-            monthNamesShort: [
-                t 'Jan'
-                t 'Feb'
-                t 'Mar'
-                t 'Apr'
-                t 'May'
-                t 'Jun'
-                t 'Jul'
-                t 'Aug'
-                t 'Sep'
-                t 'Oct'
-                t 'Nov'
-                t 'Dec']
+                '' : '' # do not display times on event
+                'agendaWeek': ''
+            axisFormat: "H:mm"
+            allDaySlot: false
             selectable: true
             selectHelper: false
             unselectAuto: false
-            eventRender: @onRender
+            eventRender: @onEventRender
             select: @onSelect
             eventDragStop: @onEventDragStop
             eventDrop: @onEventDrop
             eventClick: @onEventClick
             eventResizeStop: @onEventResizeStop
             eventResize: @onEventResize
-        @popover = {}
-        @popover.alarm = new AlarmPopOver @cal
-        @popover.event = new EventPopOver @cal
-
-    onAddAlarm: (alarm, alarms) ->
-        index = alarm.getFormattedDate "{MM}-{dd}-{yyyy}"
-        time = alarm.getFormattedDate "{hh}:{mm}"
-        content = "#{time} #{alarm.get("description")}"
-        endAlarm = alarm.getDateObject().clone()
-        endAlarm.advance minutes: 30
-
-        event =
-            id: alarm.cid
-            title: alarm.get 'description'
-            timezone: alarm.get 'timezone'
-            start: alarm.getFormattedDate(Date.ISO8601_DATETIME)
-            end: endAlarm.format(Date.ISO8601_DATETIME)
-            timezoneHour: alarm.get 'timezoneHour'
-            allDay: false
-            backgroundColor: '#5C5'
-            borderColor: '#5C5'
-            type: 'alarm' # non standard field
-
-        @cal.fullCalendar 'addEventSource', [event]
-
-
-    onResetAlarm: ->
-        @model.alarm.forEach (item) => @onAddAlarm item, @model.alarm
-
-    onAddEvent: (evt, events) ->
-        index = evt.getFormattedDate "{MM}-{dd}-{yyyy}"
-        time = evt.get("start")
-        content = "#{time} #{evt.get("description")}"
-        endEvt = evt.get("end")
-
-        event =
-            id: evt.cid
-            title: evt.get 'description'
-            start: evt.getFormattedStartDate(Date.ISO8601_DATETIME)
-            end: evt.getFormattedEndDate(Date.ISO8601_DATETIME)
-            allDay: false
-            diff: evt.get "diff"
-            place: evt.get 'place'
-            backgroundColor: '#EB1'
-            borderColor: '#EB1'
-            type: 'event' # non standard field
-
-        @cal.fullCalendar 'addEventSource', [event]
-
-    onResetEvent: ->
-        @model.event.forEach (item) => @onAddEvent item, @model.event
+            handleWindowResize: false
+
+        @cal.fullCalendar 'addEventSource', @eventCollection.asFCEventSource
+        @cal.fullCalendar 'addEventSource', @alarmCollection.asFCEventSource
+        $(window).resize _.debounce @handleWindowResize, 10
+
+
+    handleWindowResize: (initial) => # BLACK MAGICK AT WORK
+        targetHeight = $(window).height() - 2 * $('#menu').outerHeight(true) - 60
+        width = @cal.width() + 40
+        @cal.height targetHeight + 20
+        unless initial is 'initial'
+            console.log "HEY"
+            @cal.fullCalendar 'option', 'height', targetHeight
+            # @cal.fullCalendar 'render'
+        return targetHeight
+
+    refresh: (collection) ->
+        @cal.fullCalendar 'refetchEvents'
+
+    onRemove: (model) ->
+        @cal.fullCalendar 'removeEvents', model.cid
+
+    refreshOne: (model) =>
+        return @refresh() if model.getRRuleObject() #@TODO: may be smarter
+
+        data = model.toFullCalendarEvent()
+        [fcEvent] = @cal.fullCalendar 'clientEvents', data.id
+        _.extend fcEvent, data
+        console.log fcEvent
+        @cal.fullCalendar 'updateEvent', fcEvent
+
+    showPopover: (options) ->
+        klass = if options.model instanceof Event then EventPopOver
+        else AlarmPopOver
+        options.container = @cal
+        @popover.close() if @popover
+        @popover = new(klass) options
+
+    onChangeView: (view) =>
+        switch view.name
+            when 'month' then app.router.navigate 'calendar'
+            when 'agendaWeek' then app.router.navigate 'calendarweek'
 
     onSelect: (startDate, endDate, allDay, jsEvent, view) =>
-        @handleSelectionInView startDate, endDate, allDay, jsEvent, view.name
-
-    onRender: (event, element) ->
-        if event.type is 'alarm'
-            selector = '.ui-resizable-handle.ui-resizable-s'
-            $(element).find(selector).remove()
-
-        if event.type is 'event'
-            selector = '.ui-resizable-handle.ui-resizable-s'
-            $(element).find(selector).remove()
-
+        @showPopover
+            target: $(jsEvent.target)
+            model: new Event
+                start: startDate
+                end: endDate
+                place: ''
+                description: ''
+
+    onEventRender: (event, element) ->
         if event.isSaving? and event.isSaving
             spinTarget = $(element).find('.fc-event-time')
             spinTarget.addClass 'spinning'

            data = trigg: alarm.getFormattedDate Alarm.dateFormat
            storeEvent alarm, data
        else
            evt = @model.event.get event.id
            evt.getStartDateObject().advance
                days: dayDelta
                minutes: minuteDelta

            evt.getEndDateObject().advance
                days: dayDelta 
                minutes: minuteDelta
            data =
                start: evt.getFormattedStartDate Event.dateFormat
                end: evt.getFormattedEndDate Event.dateFormat
            storeEvent evt, data

    onEventResizeStop: (event, jsEvent, ui, view) -> event.isSaving = true

    onEventResize: (event, dayDelta, minuteDelta, revertFunc, 
                    jsEvent, ui, view) =>
        storeEvent = (model, data) =>
            model.save data,
                wait: true
                success: =>
                    event.isSaving = false
                    @cal.fullCalendar 'renderEvent', event
                error: =>
                    event.isSaving = false
                    @cal.fullCalendar 'renderEvent', event
                    revertFunc()
                    
        if event.type is "alarm"
            event.isSaving = false   
            @cal.fullCalendar 'renderEvent', event
            revertFunc()
            return

        evt = @model.event.get event.id

        evt.getEndDateObject().advance
            days: dayDelta 
            minutes: minuteDelta

        diff = event.diff + dayDelta
        data =
            end: evt.getFormattedEndDate Event.dateFormat
            diff: diff
        event.diff = data.diff
        event.end = data.end
        storeEvent evt, data


    onEventClick: (event, jsEvent, view) =>

        createPopover = () =>

            @popover.alarm.clean()
            @popover.event.clean()

            target = $(jsEvent.currentTarget)
            eventStartTime = event.start.getTime()
            isDayView = view.name is 'agendaDay'
            end = event.end.format '{HH}:{mm}'
            startDate = event.start
            if event.timezoneHour?
                start = event.timezoneHour
            else
                start = event.start.format '{HH}:{mm}'

            direction = helpers.getPopoverDirection isDayView, event.start, \
                                                            event.end, true

            # Create new popover to edit alarm or event
            @popover[event.type].createNew
                field: $(target)
                date: startDate
                action: 'edit'
                model: @model[event.type]
                event: event

            if event.type is 'alarm'
                timezoneData = []
                for timezone in timezones
                    timezoneData.push value: timezone, text: timezone
                formTemplate = formSmallTemplate.alarm
                    editionMode: true
                    defaultValue: event.title
                    defaultTime: start
                    #timezones: timezoneData
                    #defaultTimezone: event.timezone
                    timezone: event.timezone

                @popover.alarm.show t("Alarm edition"), direction, formTemplate

            else
                diff = event.diff
                defaultValueEnd = end + "+" + diff
                formTemplate = formSmallTemplate.event
                    editionMode: true
                    defaultValueStart: start
                    defaultValueEnd: defaultValueEnd
                    defaultValuePlace: event.place
                    defaultValueDesc: event.title
                @popover.event.show t("Event edition"), direction, formTemplate

            @popover[event.type].bindEditEvents()


        if $('.popover').is(':visible') and @popover[event.type].event?.id is event.id
            setTimeout () => 
                createPopover()
            , 20
        else
            createPopover()

    # Display popover to create alarm or event if user selects several cases
    handleSelectionInView: (startDate, endDate, allDay, jsEvent, view) ->

        createPopover = () =>
            @popover.alarm.clean()
            @popover.event.clean()

            startHour = startDate.format('{HH}:{mm}')
            endHour = endDate.format('{HH}:{mm}')
            target = $(jsEvent.target)
            isDayView = view is "agendaDay"
            direction = helpers.getPopoverDirection isDayView, startDate

            if view is "month"
                startHour = ""
                endHour = ""
            type = "event"
            formTemplate = formSmallTemplate.event
                editionMode: false
                defaultValueStart: startHour
                defaultValueEnd: endHour
                defaultValuePlace: ''
                defaultValueDesc: ''
            title = t "Event creation"

            # Create popover to create alarm or event
            @popover[type].createNew
                field: $(target)
                date: startDate
                action: 'create'
                model: @model[type]
                modelEvent: @model.event
            @popover[type].show title, direction , formTemplate
            @popover[type].bindEvents startDate

        isVisible = $('.popover').is(':visible')
        isSameDate = @popover.event.date?.format('{dd}:{MM}:{yyyy}') is 
            startDate.format('{dd}:{MM}:{yyyy}')
        isCreate = @popover.event.action is "create"

        if isVisible and isSameDate and isCreate
            setTimeout () => 
                createPopover()
            , 20
        else
            createPopover()

        


        return element

    onEventDragStop: (event, jsEvent, ui, view) ->
        event.isSaving = true

    onEventDrop: (event, dayDelta, minuteDelta, allDay,
                  revertFunc, jsEvent, ui, view) =>

        # Update new dates of event
        if event.type is 'alarm'
            alarm = @alarmCollection.get event.id

            if alarm.get('timezoneHour')?
                # Hour should correspond to alarm timezone
                startRaw = alarm.get('timezoneHour')
                alarm.getDateObject().setHours(startRaw.substring(0, 2))
                alarm.getDateObject().setMinutes(startRaw.substring(3, 5))
