BemsWebApplication.WorkHistoryScheduleCalendar = function (params, viewInfo) {
    "use strict";
    var endpointSelector;
    var useBusinessFiltering = BWA.UserInfo.isDependBusinessField(viewInfo.viewName);
    if (BemsWebApplication.config.mode == "production") {
        endpointSelector = new DevExpress.EndpointSelector(BemsWebApplication.config.endpoints).config.db.production;
    } else {
        endpointSelector = new DevExpress.EndpointSelector(BemsWebApplication.config.endpoints).config.db.local;
    }
    var eq = BWA.DataUtil.constructEqualFilter,
        and = BWA.DataUtil.andFilter,
        noteq = BWA.DataUtil.constructNotEqualFilter;
    var workHistoryScheduleCalendarPopup = null;
    var SiteId = BWA.UserInfo.SiteId();
    var holidayDataSource = BemsWebApplication.db.createDataSource('CmHoliday', true, true);
    var holidayCustomDataSource = BemsWebApplication.db.createDataSource('CmHolidayCustom', true);
    var holidayWeekendDataSource = BemsWebApplication.db.createDataSource('CmHolidayWeekend', true);
    var checkBox_regular = true, checkBox_legal = true, checkBox_any = true;

    var workScheduleDataSource = BWA.DataUtil.createDataSource({
        dataSourceOptions: {
            select: [
                'SiteId', 'WorkScheduleId', 'WorkTypeId', 'BusinessFieldId', 'Title', 'FmsWorkSchedule/CycleUnitId',
                'FmsWorkSchedule/CycleSize', 'FmsWorkSchedule/IsUse', 'FmsWorkSchedule/IsAutoOrder', 'StartWorkDate',
                'CmUser/Name', 'CmBusinessField/Name', 'FmsWorkResult/EndDate', 'FmsWorkResult/IsConfirmed',
                'CmPartner/Name', 'FmsWorkSchedule/HolidayWorkTypeId'
            ],
            expand: ['FmsWorkSchedule', 'CmUser', 'CmBusinessField', 'CmPartner', 'FmsWorkResult'],
            extendOptions: {
                forceOriginalField: true
            }
        }
    }, 'FmsWorkRequest');

    var holidaySources;
    var holidayCustomSources;
    var workScheduleSources;
    var popupWeekendSetupVisible = ko.observable(false),
        popupInsertVisible = ko.observable(false),
        hasnotModificationPermission = ko.observable(true);

    var holidayModel = {
        SiteId: ko.observable(),
        HolidayMonth: ko.observable(),
        HolidayDay: ko.observable(),
        IsLunar: ko.observable(),
        HolidayDate: ko.observable(),
        IsYearlyHoliday: ko.observable(false),
        Name: ko.observable(),
    };
    var cc = new CalendarConverter;
    var holidayWeekendDataViewModel = new BemsWebApplication.CmHolidayWeekendViewModel();
    var loadedYears = [];
    var viewDate = null;
    var currentYear = null;
    var holidays = [];
    var weekends = [];
    var isSaturday = false;
    var isSunday = false;
    var holidayCalendar = null;
    var calendarOptions = {
        selectable: true,
        editable: false,
        weekends: true,
        weekNumbers: true,
        height: 680,
        select: handleSelectInCalendar,
        eventClick: handleEventClickInCalendar,

        changedMonth: function (view) {
            var date = view.calendar.getDate();
            viewDate = date; //hcLee 2016 03 21
            if (currentYear !== null && date.year() !== currentYear) {
                currentYear = date.year();
                check_button();
            }
            else {
                applyWeekends(date);
            }
        }

        // Tooltip 관련
        //eventMouseover: function (calEvent, jsEvent) {
        //    if (!calEvent.holiday) {
        //        var xOffset = 10;
        //        var yOffset = 30;
        //        var tooltip = '<div class="tooltipevent" style="background: #333; background: rgba(0,0,0,.8); border-radius: 5px; color: #fff;padding: 5px 15px;position:absolute;z-index:10001;">';
        //        tooltip += '신청제목: ' + calEvent.title + '<br />';
        //        tooltip += '신청내용: ' + calEvent.content;
        //        tooltip += '</div>';
        //        $("body").append(tooltip);
        //        $('.tooltipevent')
        //            .css("top", (jsEvent.clientY - xOffset) + "px")
        //            .css("left", (jsEvent.clientX + yOffset) + "px")
        //            .fadeIn("fast");
        //    }
        //},
        //eventMouseout: function (calEvent, jsEvent) {
        //    $('.tooltipevent').remove();
        //}
    };

    var selectedDates = {};

    function handleSelectInCalendar(start, end) {
        //var date = start.startOf('hour');
        //var isExist = holidayCalendar.isExistEvent(date, function (i, event) {
        //    utils.toast.show('이미 등록된 휴일이 있습니다.', 'error');
        //});
        //if (isExist) return;
        //selectedDates.start = start;
        //selectedDates.end = end;
        //popupInsertVisible(true);
    }

    function handleEventClickInCalendar(event) {
        if (event.holiday === true) { return; }
        event.item.CycleUnitName = $KoSet(event.item.CycleUnitName, event.item['FmsWorkCodeCycleUnit/Name']);
        event.item.BusinessFieldName = $KoSet(event.item.BusinessFieldName, event.item['CmBusinessField/Name']);
        event.item.UpdateUserName = $KoSet(event.item.UpdateUserName, event.item['CmUser/Name']);
        event.item.InspectionAgencyName = $KoSet(event.item.InspectionAgencyName, event.item['CmPartner/Name']);
        event.item.IsAutoOrder = $KoSet(event.item.IsAutoOrder, event.item['FmsWorkSchedule/IsAutoOrder']);
        event.item.EndDate = $KoSet(event.item.EndDate, event.item['FmsWorkResult/EndDate']);

        if (event.item.WorkTypeId() == 1 || event.item.WorkTypeId() == 2 || event.item.WorkTypeId() == 4) {
            event.item.WorkTypevisible = true;
            var CycleSize = event.item['FmsWorkSchedule/CycleSize']();
            var CycleUnitId = event.item['FmsWorkSchedule/CycleUnitId']();
            var FmsWorkCodeCycleUnitdataSource = new DevExpress.data.DataSource({
                store: {
                    type: "odata",
                    url: endpointSelector + "/FmsWorkCodeCycleUnit"
                },
                requireTotalCount: true,
                pageSize: 1
            });
            FmsWorkCodeCycleUnitdataSource.filter([
                    ["SiteId", "=", SiteId],
                    "and",
                    ["CycleUnitId", "=", CycleUnitId]
            ]);
            FmsWorkCodeCycleUnitdataSource.load()
            .done(function (result) {
                var CycleUnitName = result[0].Name;
                var dispText = CycleSize + ' ' + CycleUnitName;
                event.item.CycleSizeText = $KoSet(event.item.CycleSizeText, dispText);

                var HolidayWorkTypeId = event.item['FmsWorkSchedule/HolidayWorkTypeId']();
                var FmsWorkCodeHolidayWorkTypedataSource = new DevExpress.data.DataSource({
                    store: {
                        type: "odata",
                        url: endpointSelector + "/FmsWorkCodeHolidayWorkType"
                    },
                    requireTotalCount: true,
                    pageSize: 1
                });
                FmsWorkCodeHolidayWorkTypedataSource.filter([
                        ["SiteId", "=", SiteId],
                        "and",
                        ["HolidayWorkTypeId", "=", HolidayWorkTypeId]
                ]);
                FmsWorkCodeHolidayWorkTypedataSource.load()
                .done(function (result) {
                    event.item.HolidayWorkTypeName = result[0].Name;
                    workHistoryScheduleCalendarPopup.selectedWorkSchedule(event.item);
                    workHistoryScheduleCalendarPopup.show();
                })
                .fail(function (error) {
                    utils.toast.show(error);
                });
            })
            .fail(function (error) {
                utils.toast.show(error);
            });
        }
        else {
            event.item.WorkTypevisible = false;
            workHistoryScheduleCalendarPopup.selectedWorkSchedule(event.item);
            workHistoryScheduleCalendarPopup.show();
        }
    }

    function refreshList() {
        //var date = moment();
        //loadHolidays(date);
        //hcLee 2016 03 21
        currentYear = viewDate.year();
        //loadHolidays(viewDate);
        Data_fliter(viewDate);
    }

    // hcLee 2016 10 18 추가
    var initialized = false;

    function handleViewShown() {
        $SideMenu.showSideMenuIfWill(params.view);
        if (initialized === false) { // hcLee 2016 10 18 추가
            holidayCalendar = utils.fullCalendar.create('holidayCalendar', calendarOptions);
            var date = moment();
            currentYear = date.year();
            check_button();
        }
        else
            refreshList(); // hcLee 2016 10 18 추가
    }
    function check_button() {
        $("#checkBox_regular").dxCheckBox({
            text: "정기 점검",
            value: true,
            onValueChanged: function (e) {
                switch (e.value) {
                    case true:
                        checkBox_regular = true;
                        break;
                    case false:
                        checkBox_regular = false;
                        break;
                }
                Data_fliter(viewDate);
            }
        });
        $("#checkBox_legal").dxCheckBox({
            text: "법정 검사",
            value: true,
            onValueChanged: function (e) {
                switch (e.value) {
                    case true:
                        checkBox_legal = true;
                        break;
                    case false:
                        checkBox_legal = false;
                        break;
                }
                Data_fliter(viewDate);
            }
        });
        $("#checkBox_any").dxCheckBox({
            text: "수시 점검",
            value: true,
            onValueChanged: function (e) {
                switch (e.value) {
                    case true:
                        checkBox_any = true;
                        break;
                    case false:
                        checkBox_any = false;
                        break;
                }
                Data_fliter(viewDate);
            }
        });
        Data_fliter(viewDate);
    }

    function Data_fliter(date) {
        workScheduleDataSource.filter([]);
        if (checkBox_regular) {//1
            if (checkBox_legal) {//2
                if (checkBox_any) {//5
                    workScheduleDataSource.filter().push(["WorkTypeId", ">=", 1]);//1,2,5
                }
                else {
                    workScheduleDataSource.filter().push([["WorkTypeId", "=", 1], 'or', ["WorkTypeId", "=", 2]]);//1,2
                }
            }
            else {
                if (checkBox_any) {//5
                    workScheduleDataSource.filter().push([["WorkTypeId", "=", 1], 'or', ["WorkTypeId", "=", 5]]);//1,5
                }
                else {
                    workScheduleDataSource.filter().push(["WorkTypeId", "=", 1]);//1
                }
            }
        }
        else {
            if (checkBox_legal) {//2
                if (checkBox_any) {//5
                    workScheduleDataSource.filter().push([["WorkTypeId", "=", 2], 'or', ["WorkTypeId", "=", 5]]);//2,5
                }
                else {
                    workScheduleDataSource.filter().push(["WorkTypeId", "=", 2]);//2
                }
            }
            else {
                if (checkBox_any) {//5
                    workScheduleDataSource.filter().push(["WorkTypeId", "=", 5]);//5
                }
                else {
                    workScheduleDataSource.filter().push(["WorkTypeId", "=", 0]);//0
                }
            }
        }
        loadHolidays(date);
        hasnotModificationPermission(!BWA.UserInfo.hasPermissionOfModification(viewInfo.viewName));
        $SearchView.setPopupVisibleObservable(null);
        initialized = true;
    }

    function refreshHolidays(date) {
        holidays = [];
        var currentYear = date.year();
        if (loadedYears.indexOf(currentYear) < 0) {
            loadedYears.push(currentYear);
            var year;
            var month;
            var day;
            var solar;
            $.each(holidaySources, function (i, item) {
                year = currentYear;
                month = item.HolidayMonth() - 1;
                day = item.HolidayDay();
                if (item.IsLunar()) {
                    solar = cc.lunar2solar(new Date(year - 1, month, day));
                    if (solar.sYear !== year) {
                        solar = cc.lunar2solar(new Date(year, month, day));
                    }
                    year = solar.sYear;
                    month = solar.sMonth - 1;
                    day = solar.sDay;
                }
                utils.holiday.pushHolidayEventInArray(holidays, item.Name(), moment([year, month, day]), true, undefined, 0);
            });

            $.each(holidayCustomSources, function (i, item) {
                var itemDate = item.HolidayDate();
                if (itemDate.getFullYear() === currentYear) {
                    utils.holiday.pushHolidayEventInArray(holidays, item.Name(), moment([itemDate.getFullYear(), itemDate.getMonth(), itemDate.getDate()]), false, undefined, 1);
                }
            });

            $.each(workScheduleSources, function (i, item) {
                var itemDate = item['FmsWorkResult/EndDate']();//추가
                item.Name = item.Title;
                if (itemDate.getFullYear() === currentYear) {
                    utils.holiday.pushWorkScheduleEventInArray(holidays, item, moment([itemDate.getFullYear(), itemDate.getMonth(), itemDate.getDate()]), false, undefined, item.WorkTypeId());
                }
            });
        }
        applyWeekends(date);
    }
    function loadHolidays(date) {
        holidays = [];
        loadedYears = [];

        workScheduleDataSource.filter().push('and', eq("SiteId", SiteId));
        if (useBusinessFiltering)
            workScheduleDataSource.filter().push('and', [eq('BusinessFieldId', BWA.UserInfo.BusinessFieldId()), 'or', eq('BusinessFieldId', 1)]);
        $.when(
            holidayDataSource.load(),
            holidayCustomDataSource.load(),
            holidayWeekendDataSource.load(),
            workScheduleDataSource.load())//수정
            .done(function (result1, result2, result3, result4) {

                holidaySources = result1[0];
                holidayCustomSources = result2[0];
                var tempworkScheduleSources = result4[0];
                workScheduleSources = [];
                for (var i = 0; i < tempworkScheduleSources.length; i++) {
                    //if (tempworkScheduleSources[i].WorkTypeId() <= $Code.WorkType.LEGAL_CHECK) {
                    //    if (tempworkScheduleSources[i]['FmsWorkSchedule/IsUse']() == true)
                    //        workScheduleSources.push(tempworkScheduleSources[i]);
                    //}
                    //else {
                    //    workScheduleSources.push(tempworkScheduleSources[i]);
                    //}
                    if (tempworkScheduleSources[i]['FmsWorkResult/IsConfirmed'] != null) {
                        if (tempworkScheduleSources[i]['FmsWorkResult/IsConfirmed']() == true) {
                            workScheduleSources.push(tempworkScheduleSources[i]);
                        }
                    }
                }
                if (result3.length > 0) {
                    var weekend = result3[0][0];
                    isSaturday = weekend.Saturday();
                    isSunday = weekend.Sunday();
                    holidayWeekendDataViewModel.SiteId(weekend.SiteId());
                    holidayWeekendDataViewModel.Saturday(weekend.Saturday());
                    holidayWeekendDataViewModel.Sunday(weekend.Sunday());
                }
                refreshHolidays(date);
            });
    }

    function applyWeekends(date) {
        if (holidayCalendar === null) return;
        if (isSunday == false && isSaturday == false) {
            holidayCalendar.updateEvents(holidays);
            return;
        }

        weekends = utils.holiday.getWeekendHolidays(date, isSaturday, isSunday);
        //var month = date.clone().startOf( 'month' );
        //var sunday = month.clone(), 
        //    saturday = month.clone();
        //weekends = [];
        //if( month.day() !== 0 ) {
        //    sunday.day( -7 );
        //}
        //if( month.day() !== 6 ) {
        //    saturday.day( -1 );
        //}
        //for( var i = 0 ; i < 7 ; i++ ) {
        //    if( isSunday ) {
        //        holidayCalendar.pushEventInArray( weekends, '주말 휴일', moment( [ sunday.year(), sunday.month(), sunday.date() ], null, true, 2 ));
        //        sunday.day( 7 );
        //    }            
        //    if( isSaturday ) {
        //        holidayCalendar.pushEventInArray( weekends, '주말 휴일', moment( [ saturday.year(), saturday.month(), saturday.date() ], null, true, 2 ));            
        //        saturday.day( 13 );                
        //    }
        //}
        holidayCalendar.updateEvents(holidays.concat(weekends));
    }

    function handleModification() {
        //shouldReload = true;
    }

    function handleViewHidden() {
        holidayCalendar.clearEvents(true);
    }

    function handleViewDisposing() {
        BemsWebApplication.db.CmHolidayWeekend.modified.remove(handleModification);
    }

    BemsWebApplication.db.CmHolidayWeekend.modified.add(handleModification);

    function popupInsertView() {
        popupWeekendSetupVisible(true);
    }

    function handleWeekendSetupPopupButtonSave() {
        BemsWebApplication.db.CmHolidayWeekend.update(SiteId, holidayWeekendDataViewModel.toJS()).done(function () {
            refreshList();
            utils.toast.show('데이터베이스 항목 수정 작업이 성공하였습니다.');
            popupWeekendSetupVisible(false);
        });
    }

    function handleWeekendPopupButtonClose() {
        popupWeekendSetupVisible(false);
    }

    function handleInsertPopupButtonSave() {
        var dbModelId;
        var dataViewModel;
        var selectedDate = selectedDates.start;
        if (holidayModel.IsYearlyHoliday()) {
            dbModelId = 'CmHoliday';
            dataViewModel = new BemsWebApplication.CmHolidayViewModel();
        }
        else {
            dbModelId = 'CmHolidayCustom';
            dataViewModel = new BemsWebApplication.CmHolidayCustomViewModel();
        }
        var promised = {};
        for (selectedDate = selectedDates.start ; selectedDate.isSame(selectedDates.end) === false ; selectedDate.add(1, 'days')) {
            if (holidayModel.IsYearlyHoliday()) {
                dataViewModel.IsLunar(holidayModel.IsLunar());
                var month = selectedDate.month() + 1,
                    date = selectedDate.date();
                if (holidayModel.IsLunar()) {
                    var lunar = cc.solar2lunar(new Date(selectedDate.year(), month - 1, date));
                    month = lunar.lMonth;
                    date = lunar.lDay;
                }
                dataViewModel.HolidayMonth(month);
                dataViewModel.HolidayDay(date);
            }
            else {
                dataViewModel.HolidayDate(new Date(selectedDate.year(), selectedDate.month(), selectedDate.date()));
            }
            dataViewModel.SiteId(SiteId);
            dataViewModel.Name(holidayModel.Name());
            dataViewModel.IsUse(true);

            promised = BemsWebApplication.db[dbModelId].insert(dataViewModel.toJS());
        }
        promised.done(function (values, newId) {
            popupInsertVisible(false);
            refreshList();
            utils.toast.show('휴일 등록 작업이 성공하였습니다.');
        }).fail(function () {
            popupInsertVisible(false);
            refreshList();
        });
    }

    function handleInsertPopupButtonClose() {
        popupInsertVisible(false);
    }

    var holidayWeekendSetupToolbarItems = [
        { location: 'before', text: '주말 휴일 설정' },
        { location: 'after', widget: 'button', options: { text: $G('save'), icon: 'save', clickAction: handleWeekendSetupPopupButtonSave } },
        { location: 'after', widget: 'button', options: { text: $G('close'), icon: 'close', clickAction: handleWeekendPopupButtonClose } }
    ];

    var insertHolidayToolbarItems = [
        { location: 'before', text: '주말 휴일 설정' },
        { location: 'after', widget: 'button', options: { text: $G('save'), icon: 'save', clickAction: handleInsertPopupButtonSave } },
        { location: 'after', widget: 'button', options: { text: $G('close'), icon: 'close', clickAction: handleInsertPopupButtonClose } }
    ];

    var popupOptions = {
        width: '480px',
        height: 'auto',
        visible: popupWeekendSetupVisible,
        closeOnOutsideClick: false,
        //showingAction: handlePopupShowing,
        //shownAction: handlePopupShown,
        animation: utils.popup.createAnimation()
    };

    var insertPopupOptions = $.extend({}, popupOptions);
    insertPopupOptions.visible = popupInsertVisible;
    workHistoryScheduleCalendarPopup = BWA.Popup.WorkHistoryScheduleCalendarPopup.create(holidayWeekendDataViewModel);

    return {
        viewShown: handleViewShown,
        viewHidden: handleViewHidden,
        viewDisposing: handleViewDisposing,
        refreshList: refreshList,
        popupInsertView: popupInsertView,
        popupOptions: popupOptions,
        insertPopupOptions: insertPopupOptions,
        holidayWeekendSetupToolbarItems: holidayWeekendSetupToolbarItems,
        insertHolidayToolbarItems: insertHolidayToolbarItems,
        dataModel: holidayWeekendDataViewModel,
        workHistoryScheduleCalendarPopup: workHistoryScheduleCalendarPopup,
        holidayModel: holidayModel,
        hasnotModificationPermission: hasnotModificationPermission
    };
};