/*!
 * Bootstrap v3.1.1 (http://getbootstrap.com)
 * Copyright 2011-2014 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(jQuery),+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function c(){f.trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),"string"==typeof b&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.isLoading=!1};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",f.resetText||d.data("resetText",d[e]()),d[e](f[b]||this.options[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},b.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof c&&c;e||d.data("bs.button",e=new b(this,f)),"toggle"==c?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});return this.$element.trigger(j),j.isDefaultPrevented()?void 0:(this.sliding=!0,f&&this.pause(),this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid.bs.carousel",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid.bs.carousel")},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid.bs.carousel")),f&&this.cycle(),this)};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("collapse in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);!e&&f.toggle&&"show"==c&&(c=!c),e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(jQuery),+function(a){"use strict";function b(b){a(d).remove(),a(e).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;f.toggleClass("open").trigger("shown.bs.dropdown",h),e.focus()}return!1}},f.prototype.keydown=function(b){if(/(38|40|27)/.test(b.keyCode)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var f=c(d),g=f.hasClass("open");if(!g||g&&27==b.keyCode)return 27==b.which&&f.find(e).focus(),d.click();var h=" li:not(.divider):visible a",i=f.find("[role=menu]"+h+", [role=listbox]"+h);if(i.length){var j=i.index(i.filter(":focus"));38==b.keyCode&&j>0&&j--,40==b.keyCode&&j<i.length-1&&j++,~j||(j=0),i.eq(j).focus()}}}};var g=a.fn.dropdown;a.fn.dropdown=function(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new f(this)),"string"==typeof b&&d[b].call(c)})},a.fn.dropdown.Constructor=f,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=g,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",e,f.prototype.toggle).on("keydown.bs.dropdown.data-api",e+", [role=menu], [role=listbox]",f.prototype.keydown)}(jQuery),+function(a){"use strict";var b=function(b,c){this.options=c,this.$element=a(b),this.$backdrop=this.isShown=null,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};b.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},b.prototype.toggle=function(a){return this[this.isShown?"hide":"show"](a)},b.prototype.show=function(b){var c=this,d=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(d),this.isShown||d.isDefaultPrevented()||(this.isShown=!0,this.escape(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var d=a.support.transition&&c.$element.hasClass("fade");c.$element.parent().length||c.$element.appendTo(document.body),c.$element.show().scrollTop(0),d&&c.$element[0].offsetWidth,c.$element.addClass("in").attr("aria-hidden",!1),c.enforceFocus();var e=a.Event("shown.bs.modal",{relatedTarget:b});d?c.$element.find(".modal-dialog").one(a.support.transition.end,function(){c.$element.focus().trigger(e)}).emulateTransitionEnd(300):c.$element.focus().trigger(e)}))},b.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one(a.support.transition.end,a.proxy(this.hideModal,this)).emulateTransitionEnd(300):this.hideModal())},b.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.focus()},this))},b.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keyup.dismiss.bs.modal")},b.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.removeBackdrop(),a.$element.trigger("hidden.bs.modal")})},b.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},b.prototype.backdrop=function(b){var c=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var d=a.support.transition&&c;if(this.$backdrop=a('<div class="modal-backdrop '+c+'" />').appendTo(document.body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),d&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;d?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()):b&&b()};var c=a.fn.modal;a.fn.modal=function(c,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},b.DEFAULTS,e.data(),"object"==typeof c&&c);f||e.data("bs.modal",f=new b(this,g)),"string"==typeof c?f[c](d):g.show&&f.show(d)})},a.fn.modal.Constructor=b,a.fn.modal.noConflict=function(){return a.fn.modal=c,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(b){var c=a(this),d=c.attr("href"),e=a(c.attr("data-target")||d&&d.replace(/.*(?=#[^\s]+$)/,"")),f=e.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(d)&&d},e.data(),c.data());c.is("a")&&b.preventDefault(),e.modal(f,this).one("hide",function(){c.is(":visible")&&c.focus()})}),a(document).on("show.bs.modal",".modal",function(){a(document.body).addClass("modal-open")}).on("hidden.bs.modal",".modal",function(){a(document.body).removeClass("modal-open")})}(jQuery),+function(a){"use strict";var b=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};b.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},b.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},b.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},b.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show()},b.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},b.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){if(this.$element.trigger(b),b.isDefaultPrevented())return;var c=this,d=this.tip();this.setContent(),this.options.animation&&d.addClass("fade");var e="function"==typeof this.options.placement?this.options.placement.call(this,d[0],this.$element[0]):this.options.placement,f=/\s?auto?\s?/i,g=f.test(e);g&&(e=e.replace(f,"")||"top"),d.detach().css({top:0,left:0,display:"block"}).addClass(e),this.options.container?d.appendTo(this.options.container):d.insertAfter(this.$element);var h=this.getPosition(),i=d[0].offsetWidth,j=d[0].offsetHeight;if(g){var k=this.$element.parent(),l=e,m=document.documentElement.scrollTop||document.body.scrollTop,n="body"==this.options.container?window.innerWidth:k.outerWidth(),o="body"==this.options.container?window.innerHeight:k.outerHeight(),p="body"==this.options.container?0:k.offset().left;e="bottom"==e&&h.top+h.height+j-m>o?"top":"top"==e&&h.top-m-j<0?"bottom":"right"==e&&h.right+i>n?"left":"left"==e&&h.left-i<p?"right":e,d.removeClass(l).addClass(e)}var q=this.getCalculatedOffset(e,h,i,j);this.applyPlacement(q,e),this.hoverState=null;var r=function(){c.$element.trigger("shown.bs."+c.type)};a.support.transition&&this.$tip.hasClass("fade")?d.one(a.support.transition.end,r).emulateTransitionEnd(150):r()}},b.prototype.applyPlacement=function(b,c){var d,e=this.tip(),f=e[0].offsetWidth,g=e[0].offsetHeight,h=parseInt(e.css("margin-top"),10),i=parseInt(e.css("margin-left"),10);isNaN(h)&&(h=0),isNaN(i)&&(i=0),b.top=b.top+h,b.left=b.left+i,a.offset.setOffset(e[0],a.extend({using:function(a){e.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),e.addClass("in");var j=e[0].offsetWidth,k=e[0].offsetHeight;if("top"==c&&k!=g&&(d=!0,b.top=b.top+g-k),/bottom|top/.test(c)){var l=0;b.left<0&&(l=-2*b.left,b.left=0,e.offset(b),j=e[0].offsetWidth,k=e[0].offsetHeight),this.replaceArrow(l-f+j,j,"left")}else this.replaceArrow(k-g,k,"top");d&&e.offset(b)},b.prototype.replaceArrow=function(a,b,c){this.arrow().css(c,a?50*(1-a/b)+"%":"")},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},b.prototype.hide=function(){function b(){"in"!=c.hoverState&&d.detach(),c.$element.trigger("hidden.bs."+c.type)}var c=this,d=this.tip(),e=a.Event("hide.bs."+this.type);return this.$element.trigger(e),e.isDefaultPrevented()?void 0:(d.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?d.one(a.support.transition.end,b).emulateTransitionEnd(150):b(),this.hoverState=null,this)},b.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},b.prototype.hasContent=function(){return this.getTitle()},b.prototype.getPosition=function(){var b=this.$element[0];return a.extend({},"function"==typeof b.getBoundingClientRect?b.getBoundingClientRect():{width:b.offsetWidth,height:b.offsetHeight},this.$element.offset())},b.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},b.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},b.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},b.prototype.validate=function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},b.prototype.enable=function(){this.enabled=!0},b.prototype.disable=function(){this.enabled=!1},b.prototype.toggleEnabled=function(){this.enabled=!this.enabled},b.prototype.toggle=function(b){var c=b?a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type):this;c.tip().hasClass("in")?c.leave(c):c.enter(c)},b.prototype.destroy=function(){clearTimeout(this.timeout),this.hide().$element.off("."+this.type).removeData("bs."+this.type)};var c=a.fn.tooltip;a.fn.tooltip=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof c&&c;(e||"destroy"!=c)&&(e||d.data("bs.tooltip",e=new b(this,f)),"string"==typeof c&&e[c]())})},a.fn.tooltip.Constructor=b,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=c,this}}(jQuery),+function(a){"use strict";var b=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");b.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;(e||"destroy"!=c)&&(e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]())})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(a(c).is("body")?window:c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);{var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})}},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);if(g&&b<=e[0])return g!=(a=f[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parentsUntil(this.options.target,".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(b.RESET).addClass("affix");var a=this.$window.scrollTop(),c=this.$element.offset();return this.pinnedOffset=c.top-a},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"top"==this.affixed&&(e.top+=d),"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top(this.$element)),"function"==typeof h&&(h=f.bottom(this.$element));var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;if(this.affixed!==i){this.unpin&&this.$element.css("top","");var j="affix"+(i?"-"+i:""),k=a.Event(j+".bs.affix");this.$element.trigger(k),k.isDefaultPrevented()||(this.affixed=i,this.unpin="bottom"==i?this.getPinnedOffset():null,this.$element.removeClass(b.RESET).addClass(j).trigger(a.Event(j.replace("affix","affixed"))),"bottom"==i&&this.$element.offset({top:c-h-this.$element.height()}))}}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(jQuery);
;function be_supports_history_api() {
	return !!(window.history && history.pushState);
}

var defopacity = 0.70;
var contentSpinner = 'contentSpinner';
var useContentSpinners = 0;
//var useAjaxContainerSpinner = 0;
var doNotPost = 0;


var spinnerClassNormal = 'spinner';
var spinnerClassAjax = 'spinner';

var successBeforeCallBackFunction = null;

var successAfterCallBackFunction = null;

/*
if (be_supports_history_api())
{
	window.addEventListener('popstate', function(e) {
		// e.state is equal to the data-attribute of the last image we clicked
		//alert(e.state.formAction);

		if (e.state != null)
		{

			if (e.state.postType=='AJAX')
			{
				jQuery.each(e.state.data, function(key, val) {

						if (key == 'viewStateContainer') {
							jQuery("#" + key).html(val); //val
						}
						else
						{
							jQuery("#" + key).html(val);
						}
					}
				);
				bindAjaxComplete();
			}
		}
	});

}
*/
function setSpinners() {
	useContentSpinners = jQuery("#"+contentSpinner).length>0;
	//alert(useAjaxContainerSpinner);
}

jQuery(document).ready(function() { setSpinners(); });

jQuery(document).ajaxComplete(function() { setSpinners(); });

if (jsConfig!=undefined) {
	if (jsConfig.spinnerContentWrapper!=undefined) 	contentSpinner = jsConfig.spinnerContentWrapper;
	if (jsConfig.spinnerDefopacity!=undefined) 		defopacity = jsConfig.spinnerDefopacity;
	if (jsConfig.spinnerClassNormal!=undefined) 	spinnerClassNormal = jsConfig.spinnerClassNormal;
	if (jsConfig.spinnerClassAjax!=undefined) 		spinnerClassAjax = jsConfig.spinnerClassAjax;
}

var app_signal_pre = new Array();
var app_signal_post = new Array();

function addSignalPre(sender,action) {

}

function getContentAnimationContainer() {
    var contentAnimation = jQuery('<div id="contentWaitAnimation" class="'+spinnerClassNormal+'"></div>');

    // if separate spinner container given
    if (jQuery('#appSpinnerContainer').length>0) {
        contentAnimation =  jQuery('#appSpinnerContainer');
    };
    return contentAnimation;
}

var prepended = false;
function setSpinner(target,opacity,contentAnimation)
{

	var contentAnimation = typeof(contentAnimation) != 'undefined' ? jQuery('#'+contentAnimation) : getContentAnimationContainer();

	var opacity = opacity || 0.85; // Default opacity

	var container = jQuery('#'+target);
	if (prepended)
	{
		contentAnimation.show();
	}
	else
	{
		container.css('position', 'relative').prepend(contentAnimation.show());
		prepended = true;
	}

	/*contentAnimation.innerHTML = contentAnimation.innerHTML;*/
}



function setSpinnerForClass(target,opacity)
{
	var opacity = opacity || 0.85; // Default opacity
	contentAnimation = getContentAnimationContainer();
	jQuery('.'+target).css('position', 'relative').prepend(contentAnimation.show());
}

function spinPage(contentAnimation,timeOut) {

	var timeOut = typeof(timeOut) != 'undefined' ? timeOut : 25000;
	setSpinner(contentSpinner, defopacity,contentAnimation);
	setTimeout(stopSpinPage, timeOut);
}

function stopSpinPage(contentAnimation) {


	var contentAnimation = typeof(contentAnimation) != 'undefined' ? jQuery('#'+contentAnimation) : getContentAnimationContainer();
	contentAnimation.hide();
}

var globaltargetid = null;
function setAjaxSpinner(target, opacity, spinnerClass) {

	    var opacity = typeof(opacity) != 'undefined' ? opacity : defopacity;
	    var animation = jQuery('<div class="'+spinnerClass+' spinningClass"></div>');
	    var container = jQuery("#"+target);
		var position = container.css('position');
		globaltargetid = target;

		if (container.hasClass('useSpinner')) {
		jQuery.ajaxSetup(
		    	{
		        beforeSend: function() {

		    		if (container.attr('id')==globaltargetid) {
		    			container.css('position', 'relative').prepend(animation.fadeTo(300, opacity));
		    		}
		        },
		        complete: function() {
		            animation.remove();
					globaltargetid = null;
		            container.css('position', position);
		        }
		    });
		}
}

/* If multiple App forms in the site */
var appFormToSubmit = null;

function app_check_fields() {
	var form = document.appForm;

	/* if page containsMultiple forms */
	if (appFormToSubmit!='')
	{
		var forms = document.getElementsByName(appFormToSubmit);

		if (forms.length==1)
		{
			form = forms[0];
		}
	}

	if (form == null)
	{
		alert('The main form "appForm" is missing!');
		return;
	}

    var actionControl = document.getElementById('appAction');
    var senderControl = document.getElementById('appSender');
    var actionParam = document.getElementById('appActionParam');
    var actionTarget = document.getElementById('appTarget');



	if (actionControl == null)
	{
        alert('The hidden input "appAction" (id) is missing!');
        return;
    }

    if (actionParam == null)
	{
        alert('The hidden input "appActionParam" (id) is missing!');
        return;
    }

    if (senderControl == null)
	{
        alert('The hidden input "appSender" (id) is missing!');
        return;
    }

    if (actionTarget == null)
	{
        alert('The hidden input "appTarget" (id) is missing!');
        return;
    }

	if (jQuery('#frScreenWidth').length>0)
	{
		jQuery('#frScreenWidth').val(screen.width);
	}

    return form;
}

function setParameters(target, control, action, param) {
    document.getElementById('appAction').value = action; // control (Button etc..)
    document.getElementById('appSender').value = control; // sender page or usercontrol
    document.getElementById('appActionParam').value = param; // action method
    document.getElementById('appTarget').value = target;  // param
}

var doNotClickTwice = ['notareal'];

function app_postback_ajax(target, control, action, param, spinners, spinnerClass) {

	var sourceOfCall = 'ajaxcall'+target+control+action+param;

    if (doNotClickTwice.indexOf(sourceOfCall)>0) {
		console.log('###### DOUBLECLICK ########');
		return;
    } else {
        doNotClickTwice.push(sourceOfCall);
	}

	console.log('**** CALL AJAX ****');

    form = app_check_fields();


    // remove the server-ajax:
    action = action.substring(12);

    // set the values to the form
    setParameters(target, control, action, param);

    var aDate = new Date();

    // get all select and input tags inside a div
    var selector = "select, input, textarea";

    // serialize the form
    var serialized = jQuery(selector).serializeArray();

    // tell to the frame that we are making ajax
    serialized.push({ name: 'appAjax', value: '1' });


    selectedSpinnerClass = spinnerClassAjax;
    if (spinnerClass!=undefined && spinnerClass.length>0) {
    	selectedSpinnerClass = spinnerClass;
    }


    // check if lang control is in place and Dont POST is attached
    if ( target=='appcontrol_ucLangAdminAppControl' || doNotPost==0) {
		if (spinners!=undefined && spinners.length>0) {
			if (spinners.indexOf(',')>0) {
				spinnerArr = spinners.split(',',spinners);
				//alert(spinnerArr);
				jQuery.each(spinnerArr, function(key, val){
					setAjaxSpinner(val, defopacity,selectedSpinnerClass);
				});
			}
			else {
				setAjaxSpinner(spinners, defopacity,selectedSpinnerClass);
			}
		} else {
			setAjaxSpinner(target, defopacity,selectedSpinnerClass);
		};


	    // post page & handle return
		jQuery.post(
	    	form.action,
	    	serialized,
	    	function(data) {

	    		var callIndex = doNotClickTwice.indexOf(sourceOfCall);
                if (callIndex>0) {
                   // console.log('**** CALL FINISHED ****');
                    doNotClickTwice = doNotClickTwice.splice(callIndex, 1);
                }

              //  console.log(doNotClickTwice);

				if (be_supports_history_api()) {
					history.pushState ( {
							postType : 'AJAX',
							formAction: form.action,
							data : data
						},
						"None"
						//"?"+action.trim().replace('_OnClick','').replace('_OnChange','')
					);
				}


				jQuery.each(data, function(key, val) {

					if (key == 'viewStateContainer') {
						jQuery("#"+key).html(val); //val
					} else {

						if(typeof successBeforeCallBackFunction == "function") {
							successBeforeCallBackFunction(data);
						}

						jQuery("#"+key).html(val);

						if(typeof successAfterCallBackFunction == "function") {
							successAfterCallBackFunction(data);
                            successAfterCallBackFunction = null;
						}

					}

				});
	    	},'json');
    }
}

function app_postback(target, control, action, param) {

	var form = app_check_fields();

	action = action.substring(7);
	setParameters(target, control, action, param);

	if (useContentSpinners) setSpinner(contentSpinner, defopacity);

      // check if lang control is in place and Dont POST is attached


	if (doNotPost==0)
	{
		//needs to wait for spinner to show before submitting -- safari bug
		setTimeout(function(){form.submit()}, 100);
	}
}

function app_postback_adyen(target, control, action, param) {
	var form = app_check_fields();

	action = action.substring(7);
	setParameters(target, control, action, param);

	if (useContentSpinners) {
		 setSpinner(contentSpinner, defopacity);
	}

	// check if lang control is in place and Dont POST is attached

	jQuery('#submitThisStupidButton').click();
}







;debugLevel = 0;
function debug(msg) {
	if (debugLevel>0)
	{

		if (jQuery('#debugView').length>0)
		{
			jQuery('.debugView').show();
			jQuery('#debugView').html(msg+"<br>"+jQuery('#debugView').html());

		}
	}
}

/* Check if value is defined or not */
function _isDef(val)
{
	return !(typeof val === 'undefined' || val === null || val === '')
}



function _GetHtml(element, def)
{
	var val = def;
	if (exists(element))
	{
		val = jQuery(element).html();
	}
	return val;
}

function _GetData(element, name, def)
{
	var val = def;
	if (exists(element))
	{
		var valnew = jQuery(element).data(name);
		if (_isDef(valnew))
		{
			return valnew;
		}
	}
	return val;
}




function SetCookie(cookieName,cookieValue,nDays) {
	var today = new Date();
	var expire = new Date();
	if (nDays==null || nDays==0) nDays=1;
	expire.setTime(today.getTime() + 3600000*24*nDays);
	document.cookie = cookieName+"=" + cookieValue + ";expires="+expire.toGMTString()+";samesite=lax";

	//Cookies.set(cookieName, value, { path:"/", domain: currentDomain, expires: 7, samesite: 'lax'});
}

function ReadCookie(cookieName) {
	var theCookie=" "+document.cookie;
	var ind=theCookie.indexOf(" "+cookieName+"=");
	if (ind==-1) ind=theCookie.indexOf(";"+cookieName+"=");
	if (ind==-1 || cookieName=="") return "";
	var ind1=theCookie.indexOf(";",ind+1);
	if (ind1==-1) ind1=theCookie.length;
	return theCookie.substring(ind+cookieName.length+2,ind1);
}


function postWidthToFrame()
{
	/*alert(screen.width);*/
	jQuery('#frScreenWidth').val(screen.width);
}

/**
 *
 * @param n original string
 * @param width Wiodth of padding
 * @param z Padding string
 * @returns {string}
 */
function strPadLeft(n, width, z) {
	z = z || '0';
	n = n + '';
	return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}


function loadAjaxProxyContent()
{
	jQuery('.ajaxContentProxy').each(function()
	{
		var datatype = jQuery(this).attr('data-type');
		jQuery(this).load(jsConfig.baseUrl+"/ajax/getContentProxy?type=" + datatype +"&client=" +jsConfig.clientId );
		/*jQuery(this).removeClass('ajaxContentProxy');*/
	});

	jQuery('.prCloseTerms').unbind('click').click(function(){
		jQuery('#TCContainer').modal('hide');
	});

    jQuery('.bindTermsClose').unbind('click').click(function(){
        jQuery('#TCContainer').modal('hide');
    });

    jQuery('.bindTermsPrint').unbind('click').click(function(){
        printArea(jQuery(this).data('printarea'));
    });
}


function printArea(id){
    var frameName = 'printIframe';
    var doc = window.frames[frameName];
    if (!doc) {
        jQuery('<iframe>').hide().attr('name', frameName).appendTo(document.body);
        doc = window.frames[frameName];
    }
    doc.document.body.innerHTML = jQuery("#"+id).html();
    doc.window.print();
}




function test(str) {
	if (1==0) jQuery('#test').html(jQuery('#test').html()+'<br>'+str);
}

function exists(element) {
	return jQuery(element).length > 0;
}

function debugClear()
{

	jQuery('#debugView').html('');
}

function trans(langkey,defaultText) {
    return (typeof jsConfig.lang[langkey] == 'undefined') ? defaultText : jsConfig.lang[langkey];
}

function transAlert(langkey)
{
	alert(trans(langkey));
}


/**
 * Makes a clear search (used eg. in extras phase
 */
function makeClearSearch()
{
	app_postback('appcontrol_ucSearchMask','btnSearchAvailability', 'server:btnGetAvailabilityAndClear_Clicked', 'NA');
}
/**
 * call change phase function on Booking Page
 * @param phase
 */
function changePhase(phase)
{
	spinPage();
    app_postback('appcontrol','btnChangePhase', 'server:btnChangePhase_OnClick', phase);
}

/**
 * call change phase function on Booking Page
 * @param phase
 */
function redirectTo(url)
{
	spinPage();
	app_postback('appcontrol','btnChangePhase', 'server:redirectTo', url);
}

/**
 * call change phase function on Booking Page
 * @param phase
 */
function redirectToHome()
{
	spinPage();
	app_postback('appcontrol','btnChangePhase', 'server:redirectTo', jsConfig.baseUrl+'/reserve/'+jsConfig.language+'/home');
}


function documentLocation(url)
{
	document.location = url;
}

function documentLocationManage()
{
	spinPage();
	document.location = jsConfig.baseUrl+'/reserve/'+jsConfig.language+'/manage'
}

function documentLocationRegister()
{
	spinPage();
	document.location = jsConfig.baseUrl+'/reserve/'+jsConfig.language+'/register'
}

function documentLocationLogout()
{
	spinPage();
	document.location = jsConfig.baseUrl+'/reserve/'+jsConfig.language+'/logout'
}

function documentLocationAvailability() {
    spinPage();
    document.location = jsConfig.baseUrl+'/reserve/'+jsConfig.language+'/available';
};

function documentLocationProfile()
{
	spinPage();
	document.location = jsConfig.baseUrl+'/reserve/'+jsConfig.language+'/profile';
}

function documentLocationHome()
{
	spinPage();
	document.location = jsConfig.baseUrl+'/reserve/'+jsConfig.language+'/home'
}

function documentLocationForgotPassword()
{
	spinPage();
	document.location = jsConfig.baseUrl+'/reserve/'+jsConfig.language+'/forgot'
}

function isMobile() {
	if (jQuery(window).width() > 767) {
		return false;
	} else {
		return true;
	}
}


/**
 * call change phase function on Booking Page
 * @param phase
 */
function changePhaseAndClear(phase) {
	app_postback('appcontrol','btnChangePhase', 'server:btnChangePhaseAndClear_OnClick', phase);
}


/**
 * call change phase function on Booking Page
 * @param phase
 */
function changeLang(lang,keepPhase) {
	if (keepPhase==true) {
		app_postback('appcontrol','btnChangePhase', 'server:btnChangeLangKeepPhase_OnClick', lang);
	} else {
		app_postback('appcontrol','btnChangePhase', 'server:btnChangeLang_OnClick', lang);
	}
}

function changeCurrency(targetCurrency)
{
	app_postback('appcontrol','btnChangePhase', 'server:btnChangeCurrency', targetCurrency);
}

/**
 * Prepares the reservations
 * @param paymentRef
 */
function proceedPaymentToReservation(keyFound)
{
	spinPage();
	app_postback('appcontrol','btnProceedPayment', 'server: btnProceedPayment_OnClick', keyFound);
}

function proceedPaymentToProfile(keyFound)
{
	spinPage();
	var timeoutID = window.setTimeout(app_postback('appcontrol','btnToProfilePage', 'server:btnToProfilePage_OnClick', keyFound), 300)

}



function showAlert(key) {
    alert(trans(key));
}

function isLang(lang)
{
return jsConfig.language == lang;
}

function convertStrToIntArray(astring) {
	allowedArrivalWeekDays = astring.split(',');

	for (a in allowedArrivalWeekDays ) {
		allowedArrivalWeekDays[a] = parseInt(allowedArrivalWeekDays[a]);
		}
	return allowedArrivalWeekDays;
}

/**
 * Toggles given classes.
 */
function toggleClasses() {
	for( var i = 0; i < arguments.length; i++ )
	{
		 jQuery('.'+arguments[i]).toggle('blind');
	}
}

function toggleClassesAndClear() {
	for( var i = 0; i < arguments.length; i++ )
	{
		  jQuery('.'+arguments[i]).toggle('blind');
		  jQuery('.'+arguments[i]+' :text').val('');
	}
}

function closeClasses(){
	for( var i = 0; i < arguments.length; i++ ) {
		jQuery('.'+arguments[i]).hide('blind');
	}
}

function initAutoToggle(effect,clear) {
	if (effect == undefined) {
		effect = 'blind';
	}
	jQuery(".autoToggleClick").unbind().click(function(){
		jQuery(this).closest(".autoToggleContainer").find('.autoToggle').toggle(effect);

		// check if input to clear
		if (clear !=undefined) {
			jQuery(this).closest(".autoToggleContainer").find('.autoClear').val('');
		}
	});
}




function getConfigParam() {
	var setupValue = '';
	for( var i = 0; i < arguments.length; i++ ) {
		//if (jsConfig[arguments[i].length>0)
	}
	//if( "calAvElements" in jsConfig )
}


/**
 * validates email
 * @param str
 * @returns bool
 */
function validateEmail(str)
{
	//var filter2 = /^([\w]+)(.[\w]+)*@([\w]+)(.[\w]{2,3}){1,2}$/i;
	var filter=/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,7}(?:\.[a-z]{2})?)$/i;
	return filter.test(str.replace('+',''));
}

function addRequiredClass(element,notValidClassname,wrapperClass)
{
	if (typeof(wrapperClass)==undefined || wrapperClass=='')
	{
		jQuery(element).addClass(notValidClassname).addClass('requiredCaller'+element.id);
	}
	else
	{
		jQuery(element).closest('.'+wrapperClass).addClass(notValidClassname).addClass('requiredCaller'+element.id);
	}
}

function removeRequiredClass(element,requiredclassname,wrapperClass)
{
	if (typeof(wrapperClass)==undefined || wrapperClass=='')
	{
		jQuery(element).removeClass(requiredclassname);
	}
	else
	{
		var foundParent = jQuery(element).closest('.'+wrapperClass);
		if (foundParent.hasClass('requiredCaller'+element.id))
		{
			foundParent.removeClass(requiredclassname).removeClass('requiredCaller'+element.id);
		}
	}
}

function showErrorsNextToButton() {
	// Do not
}

/**
 * Function to validate any form
 *
 * @param requiredclassname the class name that is added to those inputs that are not valid
 * @param wrapperClass if we want to use wrapper class to which the required class is applied
 * @param requiredClassSelector if we want to narrow the selection with additional class name
 * @param id if we want to narrow down the validation to certain container
 * @returns {boolean}
 */
function validateFieldsWith(requiredclassname,wrapperClass,requiredClassSelector,id)  {

	var isValid = true;
	debug('-c1-');
	jQuery(id+'.isRequired'+requiredClassSelector).each(function()
	{
		var value = jQuery(this).val();
		debug('-c1 val-'  +value);
		if (!value)
		{
			debug('-c1 value empty');
			isValid = false;
			addRequiredClass(this,requiredclassname,wrapperClass);
		}
		else
		{
			debug('-c1 has val');
			removeRequiredClass(this,requiredclassname,wrapperClass);
		}
	});

	debug('-c2-');
	/* Check required emails and Format*/
	jQuery(id+'.isRequiredEmail'+requiredClassSelector).each(function()
	{
		if (!validateEmail(jQuery(this).val()))
		{
			isValid = false;
			addRequiredClass(this,requiredclassname,wrapperClass);
		}
		else
		{
			removeRequiredClass(this,requiredclassname,wrapperClass);
		}
	});

	debug('-c3-');
	jQuery(id+'.isRequiredSelect'+requiredClassSelector).each(function()
	{
		var val = jQuery.trim(jQuery(this).val());
		if (val=='N/C' || val=='' || val=='CHOOSE')
		{
			isValid = false;
			addRequiredClass(this,requiredclassname,wrapperClass);
		}
		else
		{
			removeRequiredClass(this,requiredclassname,wrapperClass);
		}
	});

	debug('-c4-');
	jQuery(id+'.isRequiredCheck'+requiredClassSelector).each(function()
	{
		if (jQuery(this).prop('checked')==false)
		{
			isValid = false;
			addRequiredClass(this,requiredclassname,wrapperClass);
		}
		else
		{
			removeRequiredClass(this,requiredclassname,wrapperClass);
		}

	});
	return isValid;
}

function validateFields()
{
	return validateFieldsWith('required','requireWrap','','');
}

function validateFieldsWithoutWrapper()
{
	return validateFieldsWith('required','','','');
}



function validateFieldsWithClassSelector(classSelector)
{
	return validateFieldsWith('required','requireWrap',classSelector,'');
}

function validateFieldsWithClassSelectorAndId(classSelector,id)
{
	return validateFieldsWith('required','requireWrap',classSelector,'#'+id+' ');
}

/**
 * Binds the default enter key click to certain button ID=defaultActionButton
 */
function bindDefaultSubmit() {
	jQuery("input").bind("keydown", function(event) {
		// track enter key
		var keycode = (event.keyCode ? event.keyCode : (event.which ? event.which : event.charCode));
		if (keycode == 13) { // keycode for enter key
			// force the 'Enter Key' to implicitly click the Update button
			jQuery('#defaultActionButton').click();
			return false;
		} else  {
			return true;
		}
	}); // end of function
}



function centerItem(theItem){
    var winWidth=jQuery(window).width();
    var winHeight=jQuery(window).height();
    var windowCenter=winWidth/2;
    var itemCenter=jQuery(theItem).width()/2;
    var theCenter=windowCenter-itemCenter;
    var windowMiddle=winHeight/2;
    var itemMiddle=jQuery(theItem).height()/2;
    var theMiddle=windowMiddle-itemMiddle;

    if(winWidth>jQuery(theItem).width()){ //horizontal
        jQuery(theItem).css('left',theCenter + 'px');
    } else {
        jQuery(theItem).css('left','0');
    }
    if(winHeight>jQuery(theItem).height()){ //vertical
        jQuery(theItem).css('top', (theMiddle + jQuery(window).scrollTop() - 50) + 'px');
    } else {
        jQuery(theItem).css('top','0');
    }
}



;/**
 * Verkkotaito jQuery calendar library
 * Use at your own risk!
 */



function isDate (value)
{
return (!isNaN (new Date (value).getYear () ) ) ;
}




function CalendarSetup()
{
	this.moveDate = function(aDate,days)
	{
		if (days<1) return aDate;
		aDate.setDate(aDate.getDate()+parseInt(days));
		return aDate;
	};

	this.getDatePlus = function(aDate,days) {
		return this.moveDate(new Date(aDate.valueOf()),days);
	};

	this.getDateMinus = function(aDate,days) {
		var a = new Date(aDate.valueOf());
		a.setDate(a.getDate()-parseInt(days));
		return a;
	};

	this.diff = function(d1, d2, secondsToDivide)
	{
		var ndays;
		var tv1 = d1.valueOf();  // msec since 1970
		var tv2 = d2.valueOf();

		ndays = (tv2 - tv1) / 1000 / secondsToDivide;
		ndays = Math.round(ndays - 0.5);

		return ndays;
	};

	/**
	 * Print a date in 2011-10-01 Format. Internal usage
	 */
	this.printDate = function(aDate)
	{
		month = (aDate.getMonth()+1);
		if (month<10) month = "0"+month;

		day = aDate.getDate();
		if (day<10) day = "0"+day;
		return aDate.getFullYear()+"-"+month+"-"+day;
	};

	/**
	 * Simple date formatting
	 */
	this.printDateFormat = function(aDate,format)
	{

		var month = (aDate.getMonth()+1);
		if (month<10) month = "0"+month;

		var day = aDate.getDate();
		if (day<10) day = "0"+day;

		var year = aDate.getFullYear();


		var res = format.replace('mm',month);
		res = res.replace('dd',day);
		res = res.replace('yy',year);

		return res;
	};
	/**
	 * Parse date string to Date oject in 2011-10-01 Format. Internal usage
	 */
	this.parseDate = function (str)
	{
		 if (str=="") return new Date();

		if (typeof str === 'string' || str instanceof String)
		{
			var newDateStr = str.split('-');
			return new Date(Date.UTC(newDateStr[0], newDateStr[1] - 1, newDateStr[2]));
		}
		else
		{
			return new Date();
		}

	};

	/**
	 * Parse date string to Date oject in 2011-10-01 Format. Internal usage
	 */
	this.parseDateLocal = function (str)
	{
		 if (str=="") return new Date();

		if (typeof str === 'string' || str instanceof String)
		{
			var newDateStr = str.split('-');
			return new Date(newDateStr[0], newDateStr[1] - 1, newDateStr[2]);
		}
		else
		{
			return new Date();
		}

	};

	this.getDateFrom = function(yyyy,mm,dd)
	{
		return new Date(Date.UTC(yyyy, mm - 1, dd));
	};


	/* Add new period to be checked */
	this.addPeriod = function(calendarPeriod)
	{
		this.calPeriods.push(calendarPeriod);
	};

	this.isValidForArrival = function(aDate)
	{
		if (CalendarSetup.calPeriods.length==0) return [true];

		var isValid = false;

		for (i=0;i<CalendarSetup.calPeriods.length;i++)
		{
			if (CalendarSetup.calPeriods[i].isValidForArrival(aDate))
			{
				isValid = true;
			}
		}
		return isValid;
	};

	this.isValidForArrivalArray = function(aDate) {


		/*Must call the instance for some reason, this does not work*/
		var isValidDate = CalendarSetup.isValidForArrival(aDate);

		var toolTips = [];
		var avPrice = '';
		var data = CalendarSetup.getData(aDate,isValidDate);

        var avDefaultToolTip = CalendarSetup.getTip('default');


		var css = '';
		if (data) {
			css = CalendarSetup.getCSS(data);
			var avToolTip = CalendarSetup.getTip(css);
			if (avToolTip!='') {
				toolTips.push(avToolTip);
			}

			var avPrice = CalendarSetup.getPrice(data);
			if (avPrice!='') {
				toolTips.push(avPrice);
			}

			var occupancy = data.totalOccupancy;
			if (occupancy<=jsConfig.calAvSoldOutLimit) {
				isValidDate = false;
			}
		}


        var holidayToolTip = CalendarSetup.getHoliday(aDate);
        if (holidayToolTip!='') {
            toolTips.push(holidayToolTip);
            if (css=='') {css = 'avCalHoliday'};
        }

        // if availability tells somethin else


		var toolTip = avDefaultToolTip;
        if (toolTips.length>0) {
            var toolTip = toolTips.join(' - ');
		}

		if (avPrice!='') {
			avPrice = '<div class="avCalPrice">' + avPrice + '</div>';
		}

		if (typeof calendarPickUpArrival !== 'undefined' && calendarPickUpArrival!=null) {
			//debugLevel = 10;
			//debug(aDate+' '+calendarPickUpArrival);

			if (CalendarSetup.isSameDate(aDate,calendarPickUpArrival)) {
				css ="avCalShowPrice avCalSelectedStart";
			}

			if (aDate>calendarPickUpArrival && calendarPickUpDeparture>=aDate) {
				css = "avCalShowPrice avCalSelected";
			}

			if (CalendarSetup.isSameDate(aDate,calendarPickUpDeparture)) {
				css = "avCalShowPrice avCalSelectedEnd";
			}

			if (CalendarSetup.isSameDate(calendarPickUpDeparture,calendarPickUpArrival) && CalendarSetup.isSameDate(aDate,calendarPickUpArrival)) {
				css = "avCalShowPrice avCalSelectedStart";
			}
		}

		return [isValidDate,css,toolTip,avPrice];
	};

	this.isValidForArrivalObject = function(aDate) {


		/*Must call the instance for some reason, this does not work*/
		var isValidDate = CalendarSetup.isValidForArrival(aDate);

		var toolTips = [];
		var avPrice = '';
		var data = CalendarSetup.getData(aDate,isValidDate);

        var avDefaultToolTip = CalendarSetup.getTip('default');


		var css = '';
		if (data) {
			css = CalendarSetup.getCSS(data);
			var avToolTip = CalendarSetup.getTip(css);
			if (avToolTip!='') {
				toolTips.push(avToolTip);
			}

			var avPrice = CalendarSetup.getPrice(data);
			if (avPrice!='') {
				toolTips.push(avPrice);
			}

			var occupancy = data.totalOccupancy;
			if (occupancy<=jsConfig.calAvSoldOutLimit) {
				isValidDate = false;
			}
		}


        var holidayToolTip = CalendarSetup.getHoliday(aDate);
        if (holidayToolTip!='') {
            toolTips.push(holidayToolTip);
            if (css=='') {css = 'avCalHoliday'};
        }

        // if availability tells somethin else


		var toolTip = avDefaultToolTip;
        if (toolTips.length>0) {
            var toolTip = toolTips.join(' - ');
		}

		if (avPrice!='') {
			avPrice = '<div class="avCalPrice">' + avPrice + '</div>';
		}

		if (typeof calendarPickUpArrival !== 'undefined' && calendarPickUpArrival!=null) {
			//debugLevel = 10;
			//debug(aDate+' '+calendarPickUpArrival);

			if (CalendarSetup.isSameDate(aDate,calendarPickUpArrival)) {
				css ="avCalShowPrice avCalSelectedStart";
			}

			if (aDate>calendarPickUpArrival && calendarPickUpDeparture>=aDate) {
				css = "avCalShowPrice avCalSelected";
			}

			if (CalendarSetup.isSameDate(aDate,calendarPickUpDeparture)) {
				css = "avCalShowPrice avCalSelectedEnd";
			}

			if (CalendarSetup.isSameDate(calendarPickUpDeparture,calendarPickUpArrival) && CalendarSetup.isSameDate(aDate,calendarPickUpArrival)) {
				css = "avCalShowPrice avCalSelectedStart";
			}
		}

		return {
			'enabled': isValidDate,
			'classes': css,
			'tooltip': toolTip,
			'content': avPrice
		};
	};

	this.isSameDate = function(a,b) {
		return a.getFullYear() === b.getFullYear()
		&& a.getDate() === b.getDate()
		&& a.getMonth() === b.getMonth();
	};


	this.getTip = function(name) {

		if( "calAvTips" in jsConfig ) {
			if( name in jsConfig.calAvTips ) {
				return jsConfig.calAvTips[name]; // tips.indexOf(name); //jsConfig.calAvTips[jsConfig.calAvTips.indexOf(name)];
			}
		}
		return '';
	};

    this.getHoliday = function(aDate) {

        // check if there is holdays
        if( "calHolidays" in jsConfig ) {
            var dt = CalendarSetup.printDate(aDate);

            if( dt in jsConfig.calHolidays ) {
                return jsConfig.calHolidays[dt];
            }
        }
        return '';
    };

	this.getData = function(aDate,isValidDate)
	{
		if (CalendarSetup.calendarCalled>0) // miksi oli && aDate>=(CalendarSetup.today()-2)
		{
			key = CalendarSetup.printDate(aDate);
			if (CalendarSetup.elementExists(CalendarSetup.calendarDays[key]))
			{
				return CalendarSetup.calendarDays[key];
			}
		}
		return null;
	};

	this.getPrice = function(data)
	{
		var price = parseFloat(data.minPrice);
		if (price>0)
		{
			return price;
		}
		return jsConfig.calAvSoldOutText;
	};

	this.getCSS = function(data)
	{
		var css = '';
		occupancy = data.totalOccupancy;
		clientStatus = data.clientStatus;

		css = 'avCalShowPrice avCalAvailable';

		// order: if sold out, show that always, then client status if applicable

		if (occupancy<jsConfig.calAvFewLeftLimit)
		{
			css = 'avCalShowPrice avCalFewLeft';
		}
		if (clientStatus!='NA')
		{
			css = 'avCalShowPrice avCalStatus'+clientStatus;
		}
		if (occupancy<=jsConfig.calAvSoldOutLimit)
		{
			css = 'avCalSoldOut';
		}
        return css;
	};

	this.today = function() {
		return new Date();
	};

	this.isValidForDeparture = function(aDate) {
		if (CalendarSetup.calPeriods.length==0) return [true];

		var isValid = false;

		for (i=0;i<CalendarSetup.calPeriods.length;i++)
		{
			if (CalendarSetup.calPeriods[i].isValidForDeparture(aDate))
			{
				isValid = true;
			}
		}
		return isValid;
	};

	this.isValidForDepartureArray = function(aDate) {
		/*Must call the instance for some reason, this does not work*/

		var isValidDate = CalendarSetup.isValidForDeparture(aDate);

		var css = CalendarSetup.getCSS(aDate,isValidDate);

        var toolTips = [];
        var holidayToolTip = CalendarSetup.getHoliday(aDate);
        var avToolTip = CalendarSetup.getTip(css);

        if (holidayToolTip!='')
		{
            toolTips.push(holidayToolTip);
            if (css=='') {css = 'avCalHoliday'};
        }
        if (avToolTip!='') toolTips.push(avToolTip);

        // if availability tells somethin else
        var toolTip = toolTips.join(' - ');


        return [isValidDate,css,toolTip];

	};

	/**
	 * Return a next valid Arrival Day to be shown
	 */
	this.getNextValidArrivalDay = function(aDay) {
		if (aDay==undefined)
			var aDay = new Date();

		var isValid = false;
		var safeCnt = 0;
		while (!isValid && safeCnt<50)
		  {
			isValid = this.isValidForArrival(aDay);
			if (!isValid) { aDay = this.moveDate(aDay,1);}
			safeCnt++;
		  }
		return aDay;
	};

	this.getNextValidDepartureDay = function(aDay) {
		if (aDay==undefined)
			var aDay = new Date();

		var isValid = false;
		var safeCnt = 0;
		while (!isValid && safeCnt<50)
		  {
			isValid = this.isValidForDeparture(aDay);
			if (!isValid) { aDay = this.moveDate(aDay,1); }
			safeCnt++;
		  }
		return aDay;
	};

	/**
	 * Retunr the minimun nro Of nights for the arrival date
	 */
	this.getMinimumNumberOfNights = function(arrivalDate) {
		var min = 1;
		for (i=0;i<CalendarSetup.calPeriods.length;i++)
		{
			if (CalendarSetup.calPeriods[i].isInPeriod(arrivalDate)) {
				var periodmin = parseInt(CalendarSetup.calPeriods[i].getMinimumNights());
				if (periodmin>1)
					min = periodmin;
			}
		}
		return min;
	};

	this.getArrivalElement = function() {
		return jQuery(this.arrivalCalContainer);
	};

	this.getDepartureElement = function() {
		return jQuery(this.departureCalContainer);
	};

	this.getStayNightsElement = function() {

		return jQuery(this.stayNightsContainer);
	};

	this.elementExists = function(elementId) {
		return jQuery(elementId).length > 0;
	};

	this.hasArrivalElement = function() {
		return this.elementExists(CalendarSetup.getArrivalElement());
	};

	this.hasDepartureElement = function() {
		return this.elementExists(CalendarSetup.getDepartureElement());
	};

	this.hasStayNightsElement = function() {
		return this.elementExists(CalendarSetup.getStayNightsElement());
	};

	this.getDefaultArrivalDateFromAlt = function() {
		this.arrivalAlt = jQuery(jsConfig.arrivalElementAlt).val();
		if (this.arrivalAlt.length>0) {
			return this.arrivalAlt;
		} else return new Date();
	};

	this.getDefaultDepartureDateFromAlt = function() {
		this.departureAlt = jQuery(jsConfig.departureElementAlt).val();
		if (this.departureAlt.length>0) {
			return this.departureAlt;
		} else return new Date();
	};

	this.hasAvCalendars = function() {
		if( "calAvElements" in jsConfig ) {
			return (jsConfig.calAvLegendSelector.length>0 && (typeof CalendarSetup.searchMask != "undefined"))
        } else {
			return false;
        }
	};



	this.beforeShow = function (input, inst) {
		setTimeout(function()
			{
				CalendarSetup.initLegend('wait');

				var searchObject1 	= CalendarSetup.getSearchObject(1,31);

				CalendarSetup.populateAvCalendar(searchObject1,inst);

				var searchObjectStartOfMonth 	= CalendarSetup.getSearchObject(1,31,'next');
				CalendarSetup.populateAvCalendar(searchObjectStartOfMonth,inst);
			},
			20);

	};


	this.updateCalendarForSelectedDate = function(inst,aDate)
	{
		setTimeout(function()
			{
				CalendarSetup.clearCalendarDays();

				CalendarSetup.initLegend('wait');

				var searchObject1 	= CalendarSetup.getSearchObjectForDate(aDate);

				CalendarSetup.populateAvCalendar(searchObject1,inst);

				var searchObjectStart2 	= CalendarSetup.getSearchObjectForDate(aDate,'next');
				CalendarSetup.populateAvCalendar(searchObjectStart2,inst);

				inst.datepicker("setDate",aDate);
			},
			20);
	};


	this.getSearchObjectForDate = function(aDate,next)
	{
		var copy = getSearchMaskJSON();

		var dayStart 	= '01';
		var dayEnd 		= '31';
		var arrival 	= CalendarSetup.parseDate(copy.arrivalDate);

		// use month from the search
		if (typeof calendarStartDate !== "undefined")
		{
			if (aDate instanceof Date)
			{
				arrival = aDate;
			}
			else
			{
				arrival = CalendarSetup.parseDate(aDate);
			}
		}

		var year 	= arrival.getFullYear();
		var month	= arrival.getMonth()+1;
		if (next=='next')
		{
			month = month + 1;
		}

		if (month>12)
		{
			month = 1;
			year = year +1;
		}

		month = strPadLeft(month,2);

		//var departure = CalendarSetup.getDatePlus(CalendarSetup.getDateFrom(year,month,dayEnd),1);

		copy.arrivalDate = year+"-"+month+"-"+dayStart;

		//alert(copy.arrivalDate);

		var refreshCalendarData = 0;
		if (exists('#avCalRefreshCalendarData'))
		{
			if (jQuery('#avCalRefreshCalendarData').prop('checked'))
			{
				refreshCalendarData = 1;
			}
		}

		var searchObject =
		{
			searchMask: copy,
			nroOfNights: calendarNroOfNights,
			refreshCalendarData: refreshCalendarData
		};
		return searchObject;
	};



	this.moveAvCalendarDays = function(year, month, inst)
	{

		setTimeout(function()
		{
			var searchObject;

			var monthStr = parseInt(month)+1;
			if (monthStr < 10) { monthStr = "0" + monthStr;	}

			calendarStartDate = year + "-" + monthStr + "-01"; // causing if a month was selected but caledar refresh done, not the earlier moths come visible no more???*/

			var searchObjectStartOfMonth = CalendarSetup.getSearchObject(1, 31, year, month);
			CalendarSetup.populateAvCalendar(searchObjectStartOfMonth, inst);

			setTimeout(function() {
				var searchObjectStartOfMonth = CalendarSetup.getSearchObject(1, 31, year, month + 1);
				CalendarSetup.populateAvCalendar(searchObjectStartOfMonth, inst);
			},300);

		},20);
	};



	this.initLegend = function(type)
	{
		/* Spin the spinner when start and stop ehnwn done */
		if (CalendarSetup.elementExists(jsConfig.calAvSpinner))
		{
			if (type=='wait')
				jQuery(jsConfig.calAvSpinner).show();
			else
				jQuery(jsConfig.calAvSpinner).hide();
		}

		if (CalendarSetup.elementExists(jsConfig.calAvLegendElementId)) {

			if (type=='wait')
			{
				var data = jQuery(jsConfig.calAvWaitLegendElementId).html();
			}
			else
			{
				var data = jQuery(jsConfig.calAvLegendElementId).html();
			}


			setTimeout(function(){
                jQuery(jsConfig.calAvLegendSelector).each(function() {
                    jQuery(this).find(".dpLegend").remove();
                    jQuery(jsConfig.calAvLegendSelector).append('<div class="dpLegend">'+data+'</div>');

                    //.appendTo(jsConfig.calAvLegendSelector);
                });
			},50);


		}

		return;
	};

	this.getSearchObject = function(dayStart,dayEnd,year,month)
	{
		var copy = getSearchMaskJSON();
		if (typeof dayStart == "undefined")
		{
			dayStart = 1;
		}


		// If year + month NOT given
		if ( !(parseInt(year)>0 && parseInt(month)>0))
		{

			// use month from the search
			if (typeof calendarStartDate !== "undefined")
			{
				if (calendarStartDate instanceof Date)
				{
					var arrival = calendarStartDate;
				}
				else
				{
					var arrival = CalendarSetup.parseDate(calendarStartDate);
				}
			}
			else
			{
				var arrival = CalendarSetup.parseDate(copy.arrivalDate);
			}
			month = arrival.getMonth()+1;
			if (year=='next')
			{
				month = month + 1;
			}
			year = arrival.getFullYear();
		}

		month 		= strPadLeft(month,2);
		dayStart 	= strPadLeft(dayStart,2);
		dayEnd 		= strPadLeft(dayEnd,2);

		if (month>12)
		{
			month = '01';
			year = year +1;
		}

		var departure = CalendarSetup.getDatePlus(CalendarSetup.getDateFrom(year,month,dayEnd),1);

		// we need to add one day to departure
		var dYear = year;
		var dMonth = month;
		var dDay = dayEnd;

		copy.arrivalDate = year+"-"+month+"-"+dayStart;
		copy.departureDate = CalendarSetup.printDate(departure);

		//alert(copy.arrivalDate);

		var refreshCalendarData = 0;
		if (exists('#avCalRefreshCalendarData'))
		{
			if (jQuery('#avCalRefreshCalendarData').prop('checked'))
			{
				refreshCalendarData = 1;
			}
		}

		var searchObject =
		{
			searchMask: copy,
			nroOfNights: calendarNroOfNights,
			refreshCalendarData: refreshCalendarData
		};
		return searchObject;
	};

	this.getAvCalMinPrice = function(arrival,departure,elementSelectorToUpdate)
	{
		var copy = getSearchMaskJSON();

		copy.arrivalDate 	= CalendarSetup.printDate(arrival);
		copy.departureDate 	= CalendarSetup.printDate(departure);
		//copy.hotelCode 		= jsConfig.hotelCode; MIKSI NÄÄ OLI?
		//copy.chainCode 		= jsConfig.chainCode;

		var searchObject =
		{
			searchMask: copy,
			nroOfNights: calendarNroOfNights
		};

		var time = new Date().getTime();

		var URI = jsConfig.baseUrl+'/calendar/getAvCalMinPrice?client=' + jsConfig.clientId;
		jQuery.post(URI,
			searchObject,
			function(data)
			{
				jQuery(elementSelectorToUpdate).html('-');
				if (data.success)
				{
					if (data.resultObj)
					{
						jQuery(elementSelectorToUpdate).html(getFormattedPrice(data.resultObj));
					}

				}
			}
		);

	};



	this.merge = function (ob) {
		for (var z in ob)
		{
			if (!(z in CalendarSetup.calendarDays))
			{
				CalendarSetup.calendarDays[z] = ob[z];
			}
		}
	};

	this.populateAvCalendar = function (searchObject,instance)
	{
		CalendarSetup.calendarCalled++; // we need to follow how many cals has been called
		var time = new Date().getTime();

		var URI = jsConfig.baseUrl+'/calendar/getAvCalendar?client=' + jsConfig.clientId;
		if ('calAvURL' in jsConfig)
		{
			URI = jsConfig.calProxyURL;
		}

		jQuery.get(URI,
			searchObject,
			function(data)
			{
				if (data.success)
				{
					CalendarSetup.merge(data.resultObj);




					if (jQuery.type(instance)=='object')
					{
						if (instance.id)
						{
							jQuery("#"+instance.id).datepicker("refresh");
						}
						else
						{
							jQuery(instance).datepicker("refresh");
						}
					}
					else
					{
						jQuery(instance).datepicker("refresh");
					}

					CalendarSetup.initLegend();
				}
			}
		);
	};

    this.getArrivalDate = function() {
        if (CalendarSetup.hasArrivalElement())
				{

					if (jsConfig.datePickerInUse == 'bootstrap') {
						return CalendarSetup.getArrivalElement().bootstrapDP('getDate');

					} else {
						return CalendarSetup.getArrivalElement().datepicker("getDate");
					}

        }
        return new Date();
    };

	this.setArrivalDate = function(date) {

			//if (configExists(jsConfig.datePickerInUse)) {
				if (jsConfig.datePickerInUse == 'bootstrap') {
					CalendarSetup.getArrivalElement().bootstrapDP('setDate', date);
		//		}
			} else {
				  CalendarSetup.getArrivalElement().datepicker('setDate', date);
			}

	};

	this.getArrivalDateFormat = function(format) {
		if (CalendarSetup.hasArrivalElement())
		{
			return CalendarSetup.printDateFormat(CalendarSetup.getArrivalDate(),format);
		}
		return new Date();
	};


    this.getDepartureDate = function() {
        if (CalendarSetup.hasDepartureElement()) {
					if (jsConfig.datePickerInUse == 'bootstrap') {
						return CalendarSetup.getDepartureElement().bootstrapDP("getDate");
					}
					else {
						return CalendarSetup.getDepartureElement().datepicker("getDate");
					}
        }
        return new Date();
    };

	this.setDepartureDate = function(date) {


		if (jsConfig.datePickerInUse == 'bootstrap') {
				CalendarSetup.getDepartureElement().bootstrapDP('setDate', date);
		}
			else {
			CalendarSetup.getDepartureElement().datepicker('setDate', date);
		}

	};

    this.inBetween = function(aDate) {
        if (aDate<=CalendarSetup().getDepartureDate() && aDate>=CalendarSetup().getArrivalDate())
        {return true;}
        else
        {return false;}
    };

	this.clearCalendarDays = function()
	{

		this.calendarDays = [];
	};
	/** Constructor **/
	this.calPeriods = [];

	this.arrivalCalContainer 	= 	jsConfig.arrivalElement;
	this.departureCalContainer 	=	jsConfig.departureElement;
	this.stayNightsContainer 	= 	jsConfig.nightsElement;
	this.arrivalAlt = '';
	this.departureAlt = '';

	this.calendarDays =[];
	this.calendarCalled = 0;
	this.legendElementId = '';
	this.searchMask = null;
	this.rateCode = null;
}
CalendarSetup = new CalendarSetup();




/***
 * CalendarPeriod defines rules if the arrival is valid
***/
function CalendarPeriod(startDateStr,endDateStr) {



	this.setStartDate = function(aDateStr) {

		if (aDateStr=='now') {
			this.startDate = new Date();
		} else if (aDateStr=='yesterday') {
			this.startDate = new Date();
			var d = new Date();
			this.startDate.setDate(d.getDate()-1);
		} else if (isDate(aDateStr)){
			this.startDate = aDateStr; // date Object ?
		} else {
			this.startDate = CalendarSetup.parseDate(aDateStr); // string
		}
	};

	this.setEndDate = function(aDateStr) {
		if (isDate(aDateStr)){
			this.endDate = aDateStr; // date Object ?
		} else {
			this.endDate = CalendarSetup.parseDate(aDateStr); // string
		}
	};

	this.setMinimumDaysInAdvance = function(minDaysInAdvance) {
		this.minimumDaysInAdvance = minDaysInAdvance;
		this.minDate = CalendarSetup.moveDate(new Date(),this.minimumDaysInAdvance);
	};

	this.setMinimumNights = function(minNigths) {
		this.minNigths = minNigths;
	};

	this.getMinimumNights = function(aDate) {
		return this.minNigths;
	};


	this.setMaximumNights = function(maxNights) {
		this.maxNights = maxNights;
	};

	this.setAllowedArrivalWeekDays = function(allowed) {
		if (typeof(allowed)=='string') {
			this.allowedArrivalWeekDays = convertStrToIntArray(allowed);
		} else {
			this.allowedArrivalWeekDays = allowed;
		}
	};

	this.setAllowedDepartureWeekDays = function(allowed) {
		if (typeof(allowed)=='string') {
			this.allowedDepartureWeekDays = convertStrToIntArray(allowed);
		} else {
			this.allowedDepartureWeekDays = allowed;
		}
	};
	/**
	 * Check if given date is inseide this period
	 * @param Date
	 */
	this.isInPeriod = function(aDate) {
		return (this.startDate<=aDate && aDate<=this.endDate);
	};

	/**
	 * Check if the give day is a valid weekday for arrival
	 */
	this.isValidArrivalWeekDay = function(aDate) {
		if (this.allowedArrivalWeekDays.length==0) return true;
		return jQuery.inArray(aDate.getDay(),this.allowedArrivalWeekDays)>-1 ? true : false;
	};
		/**
	 * Check if the give day is a valid weekday for departure
	 */
	this.isValidDepartureWeekDay = function(aDate) {
		if (this.allowedDepartureWeekDays.length==0) return true;
		return jQuery.inArray(aDate.getDay(),this.allowedDepartureWeekDays)>-1 ? true : false;
	};

	this.isValidForArrival = function(aDate) {
		if (!this.isInPeriod(aDate)) return false;

		if (this.minimumDaysInAdvance>1) {
			if (aDate<this.minDate) return false;
			}
		if (!this.isValidArrivalWeekDay(aDate)) return false;

		return true;
	};

	this.isValidForDeparture = function(aDate) {
		if (this.allowedDepartureWeekDays.length==0) return true;
		if (!this.isValidDepartureWeekDay(aDate)) return false;

		return true;
	};

	this.print = function() {
		return this.startDate+" to "+this.endDate;
	};




	/* Constructor */
	this.setStartDate(startDateStr);

    this.setEndDate(endDateStr);

	this.minNigths = 0;
	this.maxNights = 0;

    if (this.endDate<this.startDate) alert('CalendarPeriod error: End is before start date');

	this.allowedArrivalWeekDays = []; // All weeksdays allowed
	this.allowedDepartureWeekDays =  []; // All weekdays allowed
	this.setMaximumNights(31); // How many maximum nights
	this.setMinimumNights(0); // How many minimum nights
	this.setMinimumDaysInAdvance(0);

}



var DefaultDatePickedArrival = function(date,picker)
{
	//var jQuery(picker).attr('data-departure');

	var departureId = jQuery(this).attr('data-departure');
	if (exists(departureId)) {
		var hasArrivalElement 	= true;
		var hasDepartureElement = true;
		var arrivalElement		= jQuery(this);
		var departureElement	= jQuery(departureId);
		var arrivalDate 		= jQuery(this).datepicker("getDate");
	}
	else
	{
		var hasArrivalElement 	= CalendarSetup.hasArrivalElement();
		var hasDepartureElement = CalendarSetup.hasDepartureElement();
		var arrivalElement		= CalendarSetup.getArrivalElement();
		var departureElement	= CalendarSetup.getDepartureElement();
		var arrivalDate 		= CalendarSetup.getArrivalDate();
	}

	var hasNightsElement = CalendarSetup.hasStayNightsElement();

	var stayNights = minStayNights = CalendarSetup.getMinimumNumberOfNights(arrivalDate);

	if (hasNightsElement && hasArrivalElement)
	{
		var stayNights = parseInt(CalendarSetup.getStayNightsElement().val());

		// arrival selected, set the departure as minimum requirements
		if (stayNights<minStayNights)
		{
			CalendarSetup.getStayNightsElement().val(minStayNights);
			stayNights = minStayNights;
		}

		departureDate = CalendarSetup.getNextValidDepartureDay(CalendarSetup.getDatePlus(arrivalDate,stayNights));
		CalendarSetup.getDepartureElement().datepicker("setDate",departureDate);

	};

	if (hasDepartureElement)  //Miksi ei sais olla nigths ?
	{
		departureElement.datepicker('option', 'minDate', CalendarSetup.getDatePlus(arrivalDate,minStayNights));

	  	var departureDate 	= departureElement.datepicker("getDate");

	  	var dateToCheck 	= CalendarSetup.getDatePlus(arrivalDate,stayNights); // tarkistetaan että mikäli deprture on jo kaukakan tulevaisuudesta, niin ei automaattisesti

		  if (departureDate<dateToCheck || departureDate==dateToCheck)
		  {
			  departureDate = CalendarSetup.getNextValidDepartureDay(CalendarSetup.getDatePlus(arrivalDate,stayNights));
			  departureElement.datepicker("setDate",departureDate);
		  }
			/*
			if (jsConfig.openDeparture)
			{
				setTimeout(function()
				{
					CalendarSetup.getDepartureElement().datepicker('show');
				}, 200);
			}
			*/

	}
};

var DefaultDatePickedDeparture= function()
{
	if (CalendarSetup.hasStayNightsElement())
	{
		var arrivalDate = CalendarSetup.getArrivalDate();
		var departureDate 	= CalendarSetup.getDepartureDate();
		var stayNights = CalendarSetup.diff(arrivalDate,departureDate,86400);

		CalendarSetup.getStayNightsElement().val(stayNights);

	}
};


var getSearchMaskJSON = function() {
	if (Array.isArray(searchMaskJSON)) {
		return JSON.parse(JSON.stringify(searchMaskJSON[0]));
	} else {
		return JSON.parse(JSON.stringify(searchMaskJSON));
	}
};





/*!
 * JavaScript Cookie v2.1.4
 * https://github.com/js-cookie/js-cookie
 *
 * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
 * Released under the MIT license
 */
;(function (factory) {
	var registeredInModuleLoader = false;
	if (typeof define === 'function' && define.amd) {
		define(factory);
		registeredInModuleLoader = true;
	}
	if (typeof exports === 'object') {
		module.exports = factory();
		registeredInModuleLoader = true;
	}
	if (!registeredInModuleLoader) {
		var OldCookies = window.Cookies;
		var api = window.Cookies = factory();
		api.noConflict = function () {
			window.Cookies = OldCookies;
			return api;
		};
	}
}(function () {
	function extend () {
		var i = 0;
		var result = {};
		for (; i < arguments.length; i++) {
			var attributes = arguments[ i ];
			for (var key in attributes) {
				result[key] = attributes[key];
			}
		}
		return result;
	};

	function init (converter) {
		function api (key, value, attributes) {
			var result;
			if (typeof document === 'undefined') {
				return;
			}

			// Write

			if (arguments.length > 1) {
				attributes = extend({
					path: '/'
				}, api.defaults, attributes);

				if (typeof attributes.expires === 'number') {
					var expires = new Date();
					expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
					attributes.expires = expires;
				}

				// We're using "expires" because "max-age" is not supported by IE
				attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';

				try {
					result = JSON.stringify(value);
					if (/^[\{\[]/.test(result)) {
						value = result;
					}
				} catch (e) {}

				if (!converter.write) {
					value = encodeURIComponent(String(value))
						.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
				} else {
					value = converter.write(value, key);
				}

				key = encodeURIComponent(String(key));
				key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
				key = key.replace(/[\(\)]/g, escape);

				var stringifiedAttributes = '';

				for (var attributeName in attributes) {
					if (!attributes[attributeName]) {
						continue;
					}
					stringifiedAttributes += '; ' + attributeName;
					if (attributes[attributeName] === true) {
						continue;
					}
					stringifiedAttributes += '=' + attributes[attributeName];
				}
				//alert(stringifiedAttributes);
				return (document.cookie = key + '=' + value + stringifiedAttributes);
			}

			// Read

			if (!key) {
				result = {};
			};

			// To prevent the for loop in the first place assign an empty array
			// in case there are no cookies at all. Also prevents odd result when
			// calling "get()"
			var cookies = document.cookie ? document.cookie.split('; ') : [];
			var rdecode = /(%[0-9A-Z]{2})+/g;
			var i = 0;


			for (; i < cookies.length; i++) {
				var parts = cookies[i].split('=');
				var cookie = parts.slice(1).join('=');

				if (cookie.charAt(0) === '"') {
					cookie = cookie.slice(1, -1);
				}

				try {
					var name = parts[0].replace(rdecode, decodeURIComponent);
					cookie = converter.read ?
						converter.read(cookie, name) : converter(cookie, name) ||
						cookie.replace(rdecode, decodeURIComponent);

					if (this.json) {
						try {
							cookie = JSON.parse(cookie);
						} catch (e) {}
					}

					if (key === name) {
						result = cookie;
						break;
					}

					if (!key) {
						result[name] = cookie;
					}
				} catch (e) {}
			}

			return result;
		};

		api.set = api;
		api.get = function (key) {
			return api.call(api, key);
		};
		api.getJSON = function () {
			return api.apply({
				json: true
			}, [].slice.call(arguments));
		};
		api.defaults = {};

		api.remove = function (key, attributes) {
			api(key, '', extend(attributes, {
				expires: -1
			}));
		};

		api.withConverter = init;

		return api;
	}

	return init(function () {});
}));
/* instructions
 *
  * All searchmask values are taken from inputs, for example #SMJSON-arrivalDate
  *
  * If the searchmask template needs to be fancy, eg the elements are not inputs or selects:
  * Add the inputs and selects to the DOM as hidden elements and update their values on change in client-specific js.
  * When iterating room detail data, the room specific info will be searched under .SMJSON-roomDetails
  *
  * */



//searchMaskContainerIndex is for identifying multiple rooms in same destination as every room is it's own searchmask
var searchMaskJSON  =
    [
        {
            "chainCode":"",
            "hotelCode":"",
            "isBusinessTraveller": "false",
            "searchMaskContainerIndex": "", //searchMaskContainerIndex is for identifying multiple rooms in same destination as every room is it's own searchmask
            "arrivalDate":"",
            "departureDate":"",
            "rooms":1,
            "adultsPerRoom":1,
            "childrenPerRoom":0,
            "childrenAges": "",
            "childrenBeds": "",
            "selectedChildrenBedOption": "",
            "combinedCode": "",
            "promotionCode":"",
            "blockCode":"",
            "corporateId":"",
            "iataId":"",
            "groupId":"",
            "clubMember": false,
            "selectedRoom": {
                'encodedSearchMask': "",
                'encodedRoomRate': "",
                'roomName': "",
                'roomTypeCode': "",
                'rateCode': "",
                'rateName': "",
                'price': "",
            },
            "lastPhase": "",
            "classification": "",
        }
    ];


function loadSMJSONfromCookie() {
    // get searchmask values stored in cookie and apply them to the visible searchmask


    var SMJSON = getSmCookie();

    if (SMJSON != false) {

        searchMaskJSON = SMJSON;

        console.log(searchMaskJSON);

        if (checkIfSMJSONdatesArePast(searchMaskJSON)) {
            clearSMJSON();
            return;
        }


        var roomNumberInSearchMask = 1;

        var smContainerIndex = 0;

        // loop quikly through searchmask to see how many searchmaskcontainers there are.
        var lastSearchmask;
        for (var i=0; i<searchMaskJSON.length; i++ ){
            lastSearchmask = searchMaskJSON[i].searchMaskContainerIndex;
        }

        jQuery('#SMJSON-numberOfRooms').val(searchMaskJSON.length);


        // loop through SMJSON searchmasks and add values
        for (var i=0; i<searchMaskJSON.length; i++ ){

            //get the container where to add values
            var smContainer = jQuery('.newSearchMaskContainer[data-smindex="'+searchMaskJSON[i].searchMaskContainerIndex+'"]');

            if (smContainerIndex == searchMaskJSON[i].searchMaskContainerIndex) {
                // if first room in searchmaskcontainer


                // businessTraveller
                var isBusinessTraveller = searchMaskJSON[i].isBusinessTraveller;
                if (isBusinessTraveller) {

                    jQuery('.reasonForStayContainer').find('.reasonHoliday').removeClass('active');
                    jQuery('.reasonForStayContainer').find('.reasonWork').addClass('active');
                    jQuery('.hideIfBusiness').hide();
                }

                // hotelCode
                var hotelCode = searchMaskJSON[i].hotelCode;

                if (typeof hotelCode != 'undefined')
                {
                    if (hotelCode!='' && hotelCode!='NA')
                    {
                        smContainer.find('.smSelectedHotel').data('hotelcode', hotelCode);
                        var hotelName = smContainer.find('.smHotelOption[data-hotelcode="'+hotelCode+'"], .smHotelListCity[data-hotelcode="'+hotelCode+'"]').first().text();
                        smContainer.find('.smSelectedHotel').text(hotelName);
                        smContainer.find('.smHotels').addClass('selected');
                    }
                }
                // arrivalDate
                var arrDate = searchMaskJSON[i].arrivalDate;
                if (typeof arrDate != 'undefined') {
                    smContainer.find('#SMJSON-arrivalDate').val(arrDate);
                }
                // departureDate
                var depDate = searchMaskJSON[i].departureDate;
                if (typeof depDate != 'undefined') {
                    smContainer.find('#SMJSON-departureDate').val(depDate);
                }

                var datesDelta = 1;
                if (typeof arrDate != 'undefined' && typeof depDate != 'undefined') {
                    var arrivalAsDate = parseSMJSONDate(arrDate);
                    var departureAsDate = parseSMJSONDate(depDate);

                    datesDelta = CalendarSetup.diff(arrivalAsDate,departureAsDate,86400);
                }
                smContainer.find('#SMJSON-numberOfNights').val(datesDelta);



                // adults
                var adults = searchMaskJSON[i].adultsPerRoom;
                if (typeof adults != 'undefined') {
                    smContainer.find('.smRoomDetails[occnro="1"] .SMJSON-adultsAmount').val(adults);
                }
                // children
                var children = searchMaskJSON[i].childrenPerRoom;
                if (typeof children != 'undefined') {
                    smContainer.find('.smRoomDetails[occnro="1"] .SMJSON-childrenAmount').val(children);
                }
                // child ages
                var childages = searchMaskJSON[i].childrenAges;
                var childbeds = searchMaskJSON[i].childrenBedTexts;
                if (typeof childages != 'undefined') {
                    for (var arrIndx=0; arrIndx<childages.length; arrIndx++) {
                        var cb = arrIndx + 1;
                        smContainer.find('.smRoomDetails[occnro="1"] .SMJSON-childAge[data-cb="'+cb+'"]').val(childages[arrIndx]);
                    }
                }


                // combinedCode
                var combinedCode = searchMaskJSON[i].combinedCode;
                if (typeof combinedCode != 'undefined') {
                    smContainer.find('#SMJSON-combinedCode').val(combinedCode);
                }
                // clubMember
                var clubMember = searchMaskJSON[i].clubMember;
                if (typeof clubMember != 'undefined') {
                    smContainer.find('.bindCopyLaplandClub').prop('checked', clubMember);
                }

                //classification
                var classes = searchMaskJSON[i].classification;
                if (typeof classes != 'undefined' && Array.isArray(classes)) {
                    smContainer.find('.bindClassFilterBtn').each(function(){
                        if (classes.indexOf(jQuery(this).data('classification')) > -1) {
                            jQuery(this).addClass('active');
                        }
                    });
                }
                else {
                    smContainer.find('.bindClassFilterBtn[data-classification="all"]').addClass('active');
                }

                smContainerIndex++;
                // reset roomNumber to 1;
                roomNumberInSearchMask = 1;

                // if this is not the last searchmask, add a new one.
                if (searchMaskJSON[i].searchMaskContainerIndex != lastSearchmask) {
                    addSearchMask();
                }

            }
            else {
                // if many rooms in searchmaskContainer



                var realRoomNro = roomNumberInSearchMask+1;

                // adults
                var adults = searchMaskJSON[i].adultsPerRoom;
                if (typeof adults != 'undefined') {


                    smContainer.find('.smRoomDetails[occnro="'+realRoomNro+'"] .SMJSON-adultsAmount').val(adults);
                }
                // children
                var children = searchMaskJSON[i].childrenPerRoom;
                if (typeof children != 'undefined') {
                    smContainer.find('.smRoomDetails[occnro="'+realRoomNro+'"] .SMJSON-childrenAmount').val(children);
                }

                // child ages
                var childages = searchMaskJSON[i].childrenAges;
                if (typeof childages != 'undefined') {
                    for (var arrIndx=0; arrIndx<childages.length; arrIndx++) {
                        var cb = arrIndx + 1;
                        smContainer.find('.smRoomDetails[occnro="'+realRoomNro+'"] .SMJSON-childAge[data-cb="'+cb+'"]').val(childages[arrIndx]);
                    }
                }


                roomNumberInSearchMask ++;

            }
            // this should no be in the common js
            //countSelectedOccupants(smContainer);

        }


    }
    else {

        // if no cookie found, count the occupants of the first searchmask and fill dates with current date and next one

        // this should not be in the common js
        //countSelectedOccupants(jQuery('.newSearchMaskContainer[data-smindex="0"]'));

        var d = new Date;
        var curr_date = d.getDate();
        var curr_month = d.getMonth() + 1; // Months are zero based
        var curr_year = d.getFullYear();
        var arrDate = curr_date + "." + curr_month + "." + curr_year;

        var dep = CalendarSetup.moveDate(d,1);
        var dep_date = dep.getDate();
        var dep_month = dep.getMonth() + 1; // Months are zero based
        var dep_year = dep.getFullYear();

        depDate = dep_date + "." + dep_month + "." +dep_year;

        jQuery('.newSearchMaskContainer[data-smindex="0"] #SMJSON-arrivalDate').val(arrDate);
        jQuery('.newSearchMaskContainer[data-smindex="0"] #SMJSON-departureDate').val(depDate);

        //add All-class to classification filter.
        jQuery('.newSearchMaskContainer[data-smindex="0"]').find('.bindClassFilterBtn[data-classification="all"]').addClass('active');


    }

}

function buildSMJSON(triggerInFancybox) {

    // if addRoom parameter is true, add selected room data also.


    var searchMaskJSON = [];

    var jsoncounter = 0;

    jQuery('.newSearchMaskContainer').each(function(){

        // count visible searchmasks
        var container = jQuery(this);
        if (triggerInFancybox) {
            container = jQuery('.smFancybox');
        }



        // count rooms in searchmask, they are individual searchmasks in json

        var rooms = parseInt(jQuery(this).find('#SMJSON-numberOfRooms').val());

        for (var i=0; i<rooms; i++) {

            // get adults and children
            var adultsAmount, kidsAmount;
            var childrenAges = [];
            var childrenBedCodes = [];
            var childrenBedTexts = [];
            var selectedChildrenBedOption = null;

            container.find('.SMJSON-roomDetails.enabled').each(function(index){
                
                var roomDetails = jQuery(this);
                
                if (i == index) {
                    adultsAmount = parseInt(roomDetails.find('.SMJSON-adultsAmount').val());
                    kidsAmount = parseInt(roomDetails.find('.SMJSON-childrenAmount').val());
                    roomDetails.find('.SMJSON-childAge').each(function(indx){
                        if (indx < kidsAmount) {
                            childrenAges.push(jQuery(this).val());
                        }
                    });
                    roomDetails.find('.SMJSON-childBed').each(function(indx){
                        if (indx < kidsAmount) {
                            childrenBedCodes.push(jQuery(this).data('key'));
                            childrenBedTexts.push(jQuery(this).val());
                        }
                    });
                    console.log(roomDetails.find('.childBedChoiceOptionRadioSelected').length, roomDetails.find('.childBedChoiceOptionRadioSelected').parents('.childOptionRadioButton').data('index'));
                    if (roomDetails.find('.childBedChoiceOptionRadioSelected').length > 0) {
                        selectedChildrenBedOption = roomDetails.find('.childBedChoiceOptionRadioSelected').parents('.childOptionRadioButton').data('index');
                    }
                    
                }
           

            });


            searchMaskJSON[jsoncounter] = {
                "chainCode": jsConfig.chainCode,
                "hotelCode": jsConfig.hotelCode,
                "searchMaskContainerIndex": jQuery(this).data('smindex'), //searchMaskContainerIndex is for identifying multiple rooms in same destination as every room is it's own searchmask
                "isBusinessTraveller": jQuery('#SMJSON-isBusinessTraveller').val(), //true or false
                "rooms": 1, // this needs to be always 1, very confusing
                "arrivalDate": jQuery(this).find('#SMJSON-arrivalDate').val(),
                "departureDate": jQuery(this).find('#SMJSON-departureDate').val(),
                "adultsPerRoom": adultsAmount,
                "childrenPerRoom": kidsAmount,
                "childrenAges": childrenAges,
                "childrenBedTexts": childrenBedTexts,
                "childrenBedCodes": childrenBedCodes,
                'selectedChildrenBedOption': selectedChildrenBedOption,
                "combinedCode": jQuery(this).find('#SMJSON-combinedCode').val(),
                "promotionCode": jQuery(this).find('#SMJSON-promotionCode').val(),
                "blockCode": jQuery(this).find('#SMJSON-blockCode').val(),
                "corporateId": jQuery(this).find('#SMJSON-corporateId').val(),
                "iataId": jQuery(this).find('#SMJSON-iataId').val(),
                "groupId": jQuery(this).find('#SMJSON-groupId').val(),
                "clubMember": jQuery(this).find('#SMJSON-isClubMember').val(),
                "lastPhase": jsConfig.appPhase,
                "classification": getSelectedClassifications(),
            };





            jsoncounter++;
        }



    });


    // save the object to cookie
    //document.cookie = "SMJSON" + "=" +JSON.stringify(searchMaskJSON);
    setSmCookie(searchMaskJSON);

    console.log('json at search: ',searchMaskJSON);

    // add the json to hidden input to post

    var stringified = JSON.stringify(searchMaskJSON);
    var encoded = b64EncodeUnicode(stringified);

    jQuery('#heArrayOfSearchMasksAsJSON').val(stringified);


}

function getSelectedClassifications() {
    var selected = [];
    jQuery('.bindClassFilterBtn').each(function(){
        if(jQuery(this).hasClass('active')) {
            selected.push(jQuery(this).data('classification'));
        }
    });
    if (selected.length > 0) {
        return selected;
    }
    else {
        return "";
    }
}

function buildShoppingCartfromCookie() {
    // get searchmask values stored in cookie and apply them to the shopping cart

    var SMJSON = getSmCookie();

    if (SMJSON != false) {

        var searchMaskJSON = SMJSON;
        // clear the shopping cart
        jQuery('.Shopping-cart-single-hotel-data').empty();


        //console.log(searchMaskJSON);
        var roomNumberInSearchMask = 1;

        var smContainerIndex = 0;

        var totalPriceOfShopCart = 0;

        var allRoomsSelected = true;

        // loop quikly through searchmask to see how many searchmaskcontainers there are.
        var lastSearchmask;
        for (var i=0; i<searchMaskJSON.length; i++ ){
            lastSearchmask = searchMaskJSON[i].searchMaskContainerIndex;
        }

        // loop through SMJSON searchmasks and add values
        for (var i=0; i<searchMaskJSON.length; i++ ){

            //get the container where to add values
            var smContainer = jQuery('.newSearchMaskContainer[data-smindex="'+searchMaskJSON[i].searchMaskContainerIndex+'"]');

            if (smContainerIndex == searchMaskJSON[i].searchMaskContainerIndex) {
                // if first room in searchmaskcontainer


                var hotelCode = searchMaskJSON[i].hotelCode;
                var arrDate = searchMaskJSON[i].arrivalDate;
                var depDate = searchMaskJSON[i].departureDate;
                var adults = searchMaskJSON[i].adultsPerRoom;
                var children = searchMaskJSON[i].childrenPerRoom;
                if (typeof  children == 'undefined') {
                    children = 0;
                }


                smContainerIndex++;
                // reset roomNumber to 1;
                roomNumberInSearchMask = 1;

                // if this is not the last searchmask, add a new one.
                /*if (searchMaskJSON[i].searchMaskContainerIndex != lastSearchmask) {
                    addSearchMask();
                }*/

            }
            else {
                // if many rooms in searchmaskContainer


                var realRoomNro = roomNumberInSearchMask+1;

                var hotelCode = searchMaskJSON[i].hotelCode;
                var arrDate = searchMaskJSON[i].arrivalDate;
                var depDate = searchMaskJSON[i].departureDate;
                var adults = searchMaskJSON[i].adultsPerRoom;
                var children = searchMaskJSON[i].childrenPerRoom;
                if (typeof  children == 'undefined') {
                    children = 0;
                }


                roomNumberInSearchMask ++;

            }
            // finally place the total price and count the total nights
            if (allRoomsSelected) {

                jQuery('.bindTotalPriceOfShopCart').text(totalPriceOfShopCart +' €');
                if (jsConfig.language == 'fi') {
                    var totalNightsText = "Yhteensä viettäen "+getDayDifference(arrDate, depDate)+" yötä";
                } else {
                    var totalNightsText = "Total price spending "+getDayDifference(arrDate, depDate)+" nights";
                }

                jQuery('.bindTotalNightsOfShopCart').text(totalNightsText);
            }

        }


    }
    else {

        // if no cookie found:

    }

}

function getSmCookie() {

    // gets the base64 encoded searchmask from cookie, and returns it decoded
    var SMJSON = Cookies.get('SMJSON');

    // if last search mask is found use it instead.
    if (jQuery('#lastSearchMaskJSON').length > 0) {
        SMJSON = jQuery('#lastSearchMaskJSON').text();

        //also needs to save the data to cookie again
        var currentDomain = getDomain(window.location.hostname, false);
        Cookies.set('SMJSON', SMJSON, { path:"/", domain: currentDomain, expires: 7 });
    }




    if (typeof  SMJSON != 'undefined') {
        try {
            return JSON.parse(b64DecodeUnicode(SMJSON));
        }
        catch(err) {
            console.log(err);

            // jos cookie palauttaa errorin, niin poistetaan koko cookie.
            var currentDomain = getDomain(window.location.hostname, false);
            Cookies.remove('SMJSON', { path:"/", domain: currentDomain });
            return false;
        }


    }
    else {
        return false;
    }
}


function setSmCookie(value)
{
    //base64 encode
    value = JSON.stringify(value);
    value = b64EncodeUnicode(value);

    // get the current domain to set the cookie to
    var currentDomain = getDomain(window.location.hostname, false);
    Cookies.set('SMJSON', value, { path:"/", domain: currentDomain, expires: 7 });
}

// Encoding UTF8 ⇢ base64

function b64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode(parseInt(p1, 16))
    }))
}


function b64DecodeUnicode(str) {
    return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
    }).join(''))
}


function getHotelNameFromHotelCode(hotelcode) {
    var hotels = {
        'OWS': 'Arctic treehouse hotels',
    };

    return hotels[hotelcode];
}

function getSMJSONArrivalDate() {
    var SMJSON = getSmCookie();

    if (SMJSON != false) {

        var searchMaskJSON = SMJSON;

        return parseSMJSONDate(searchMaskJSON[0].arrivalDate);

    }
}

function getSMJSONProperty(propertyName, index) {
    if (typeof index == 'undefined'){
        index = 0;
    }
    var SMJSON = getSmCookie();

    if (SMJSON != false) {

        var searchMaskJSON = SMJSON;

        return searchMaskJSON[index][propertyName];

    }
}

function parseSMJSONDate(dateStr) {
    if (dateStr=="") return new Date();

    if (typeof dateStr === 'string' || dateStr instanceof String)
    {
        var newDateStr = dateStr.split('.');
        return new Date(Date.UTC(newDateStr[2], newDateStr[1] - 1, newDateStr[0]));
    }
    else
    {
        return new Date();
    }
}


function getDayDifference(first, second) {


    var _first = first.split('.');
    first = new Date(_first[2], _first[1], _first[0]-1);
    var _second = second.split('.');
    second = new Date(_second[2], _second[1], _second[0]-1);


    return Math.round((second-first)/(1000*60*60*24));
}

function updateSMJSONphase (){

    // just updates the last phase on every load

    var SMJSON = getSmCookie();

    if (SMJSON != 'false') {

        var searchMaskJSON = SMJSON;

        for (var i=0; i<searchMaskJSON.length; i++ ){
            searchMaskJSON[i].lastPhase = jsConfig.appPhase;
        }

        setSmCookie(searchMaskJSON);
    }
}


function getDomain(url, subdomain) {
    subdomain = subdomain || false;

    url = url.replace(/(https?:\/\/)?(www.)?/i, '');

    if (!subdomain) {
        url = url.split('.');

        url = url.slice(url.length - 2).join('.');
    }

    if (url.indexOf('/') !== -1) {
        return url.split('/')[0];
    }

    return "."+url;
}

function clearSMJSON() {
    //console.log('clearing SMJSON');
    var currentDomain = getDomain(window.location.hostname, false);
    Cookies.remove('SMJSON', { path:"/", domain: currentDomain });
}

function SMJSONexists() {

    // function to check if SMJSON exists

    var SMJSON = getSmCookie();

    if (SMJSON != false) {

        return true;
    }
    else {
        return false;
    }
}

function removeRoomFromSMJSON(index) {

    // removes a room from the SMJSON cookie and sets the new object to the cookie

    var SMJSON = getSmCookie();
    var updatedSMJSON = SMJSON.splice(index,1);
    console.log(updatedSMJSON);
    setSmCookie(updatedSMJSON);

}

function SMJSONhasAllRoomsSelected() {

    // function to check if all rooms have been selected in SMJSON

    var SMJSON = getSmCookie();

    var allSelected = false;

    if (SMJSON != 'false') {

        var searchMaskJSON = SMJSON;

        allSelected = true;

        for (var i = 0; i < searchMaskJSON.length; i++) {
            if (typeof searchMaskJSON[i].selectedRoom.roomName == 'undefined') {
                allSelected = false;
            }
        }
    }

    return allSelected;
}

function checkIfSMJSONdatesArePast(searchMaskJSON) {
    for (var i=0; i<searchMaskJSON.length; i++ ) {
        var arrDate = searchMaskJSON[i].arrivalDate;
        var nowTimeStamp = new Date();
        nowTimeStamp.setHours(0,0,0,0);
        nowTimeStamp = nowTimeStamp.getTime();
        if (typeof arrDate != 'undefined') {
            var newDateStr = arrDate.split('.');
            var arrivalTimeStamp =  new Date(newDateStr[2], newDateStr[1] - 1, newDateStr[0]).getTime();

            if (nowTimeStamp > arrivalTimeStamp) {
                return true;
            } else {
                return false;
            }
        }
    }
}
/*!
 * Datepicker for Bootstrap v1.6.4 (https://github.com/eternicode/bootstrap-datepicker)
 *
 * Copyright 2012 Stefan Petre
 * Improvements by Andrew Rowls
 * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
 */(function(factory){
    if (typeof define === "function" && define.amd) {
        define(["jquery"], factory);
    } else if (typeof exports === 'object') {
        factory(require('jquery'));
    } else {
        factory(jQuery);
    }
}(function($, undefined){

	function UTCDate(){
		return new Date(Date.UTC.apply(Date, arguments));
	}
	function UTCToday(){
		var today = new Date();
		return UTCDate(today.getFullYear(), today.getMonth(), today.getDate());
	}
	function isUTCEquals(date1, date2) {
		return (
			date1.getUTCFullYear() === date2.getUTCFullYear() &&
			date1.getUTCMonth() === date2.getUTCMonth() &&
			date1.getUTCDate() === date2.getUTCDate()
		);
	}
	function alias(method){
		return function(){
			return this[method].apply(this, arguments);
		};
	}
	function isValidDate(d) {
		return d && !isNaN(d.getTime());
	}

	var DateArray = (function(){
		var extras = {
			get: function(i){
				return this.slice(i)[0];
			},
			contains: function(d){
				// Array.indexOf is not cross-browser;
				// $.inArray doesn't work with Dates
				var val = d && d.valueOf();
				for (var i=0, l=this.length; i < l; i++)
					if (this[i].valueOf() === val)
						return i;
				return -1;
			},
			remove: function(i){
				this.splice(i,1);
			},
			replace: function(new_array){
				if (!new_array)
					return;
				if (!$.isArray(new_array))
					new_array = [new_array];
				this.clear();
				this.push.apply(this, new_array);
			},
			clear: function(){
				this.length = 0;
			},
			copy: function(){
				var a = new DateArray();
				a.replace(this);
				return a;
			}
		};

		return function(){
			var a = [];
			a.push.apply(a, arguments);
			$.extend(a, extras);
			return a;
		};
	})();


	// Picker object

	var Datepicker = function(element, options){
		$(element).data('datepicker', this);
		this._process_options(options);

		this.dates = new DateArray();
		this.viewDate = this.o.defaultViewDate;
		this.focusDate = null;

		this.element = $(element);
		this.isInput = this.element.is('input');
		this.inputField = this.isInput ? this.element : this.element.find('input');
		this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;
		this.hasInput = this.component && this.inputField.length;
		if (this.component && this.component.length === 0)
			this.component = false;
		this.isInline = !this.component && this.element.is('div');

		this.picker = $(DPGlobal.template);

		// Checking templates and inserting
		if (this._check_template(this.o.templates.leftArrow)) {
			this.picker.find('.prev').html(this.o.templates.leftArrow);
		}
		if (this._check_template(this.o.templates.rightArrow)) {
			this.picker.find('.next').html(this.o.templates.rightArrow);
		}

		this._buildEvents();
		this._attachEvents();

		if (this.isInline){
			this.picker.addClass('datepicker-inline').appendTo(this.element);
		}
		else {
			this.picker.addClass('datepicker-dropdown dropdown-menu');
		}

		if (this.o.rtl){
			this.picker.addClass('datepicker-rtl');
		}

		this.viewMode = this.o.startView;

		if (this.o.calendarWeeks)
			this.picker.find('thead .datepicker-title, tfoot .today, tfoot .clear')
						.attr('colspan', function(i, val){
							return parseInt(val) + 1;
						});

		this._allow_update = false;

		this.setStartDate(this._o.startDate);
		this.setEndDate(this._o.endDate);
		this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
		this.setDaysOfWeekHighlighted(this.o.daysOfWeekHighlighted);
		this.setDatesDisabled(this.o.datesDisabled);

		this.fillDow();
		this.fillMonths();

		this._allow_update = true;

		this.update();
		this.showMode();

		if (this.isInline){
			this.show();
		}
	};

	Datepicker.prototype = {
		constructor: Datepicker,

		_resolveViewName: function(view, default_value){
			if (view === 0 || view === 'days' || view === 'month') {
				return 0;
			}
			if (view === 1 || view === 'months' || view === 'year') {
				return 1;
			}
			if (view === 2 || view === 'years' || view === 'decade') {
				return 2;
			}
			if (view === 3 || view === 'decades' || view === 'century') {
				return 3;
			}
			if (view === 4 || view === 'centuries' || view === 'millennium') {
				return 4;
			}
			return default_value === undefined ? false : default_value;
		},

		_check_template: function(tmp){
			try {
				// If empty
				if (tmp === undefined || tmp === "") {
					return false;
				}
				// If no html, everything ok
				if ((tmp.match(/[<>]/g) || []).length <= 0) {
					return true;
				}
				// Checking if html is fine
				var jDom = $(tmp);
				return jDom.length > 0;
			}
			catch (ex) {
				return false;
			}
		},

		_process_options: function(opts){
			// Store raw options for reference
			this._o = $.extend({}, this._o, opts);
			// Processed options
			var o = this.o = $.extend({}, this._o);

			// Check if "de-DE" style date is available, if not language should
			// fallback to 2 letter code eg "de"
			var lang = o.language;
			if (!dates[lang]){
				lang = lang.split('-')[0];
				if (!dates[lang])
					lang = defaults.language;
			}
			o.language = lang;

			// Retrieve view index from any aliases
			o.startView = this._resolveViewName(o.startView, 0);
			o.minViewMode = this._resolveViewName(o.minViewMode, 0);
			o.maxViewMode = this._resolveViewName(o.maxViewMode, 4);

			// Check that the start view is between min and max
			o.startView = Math.min(o.startView, o.maxViewMode);
			o.startView = Math.max(o.startView, o.minViewMode);

			// true, false, or Number > 0
			if (o.multidate !== true){
				o.multidate = Number(o.multidate) || false;
				if (o.multidate !== false)
					o.multidate = Math.max(0, o.multidate);
			}
			o.multidateSeparator = String(o.multidateSeparator);

			o.weekStart %= 7;
			o.weekEnd = (o.weekStart + 6) % 7;

			var format = DPGlobal.parseFormat(o.format);
			if (o.startDate !== -Infinity){
				if (!!o.startDate){
					if (o.startDate instanceof Date)
						o.startDate = this._local_to_utc(this._zero_time(o.startDate));
					else
						o.startDate = DPGlobal.parseDate(o.startDate, format, o.language, o.assumeNearbyYear);
				}
				else {
					o.startDate = -Infinity;
				}
			}
			if (o.endDate !== Infinity){
				if (!!o.endDate){
					if (o.endDate instanceof Date)
						o.endDate = this._local_to_utc(this._zero_time(o.endDate));
					else
						o.endDate = DPGlobal.parseDate(o.endDate, format, o.language, o.assumeNearbyYear);
				}
				else {
					o.endDate = Infinity;
				}
			}

			o.daysOfWeekDisabled = o.daysOfWeekDisabled||[];
			if (!$.isArray(o.daysOfWeekDisabled))
				o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
			o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){
				return parseInt(d, 10);
			});

			o.daysOfWeekHighlighted = o.daysOfWeekHighlighted||[];
			if (!$.isArray(o.daysOfWeekHighlighted))
				o.daysOfWeekHighlighted = o.daysOfWeekHighlighted.split(/[,\s]*/);
			o.daysOfWeekHighlighted = $.map(o.daysOfWeekHighlighted, function(d){
				return parseInt(d, 10);
			});

			o.datesDisabled = o.datesDisabled||[];
			if (!$.isArray(o.datesDisabled)) {
				o.datesDisabled = [
					o.datesDisabled
				];
			}
			o.datesDisabled = $.map(o.datesDisabled,function(d){
				return DPGlobal.parseDate(d, format, o.language, o.assumeNearbyYear);
			});

			var plc = String(o.orientation).toLowerCase().split(/\s+/g),
				_plc = o.orientation.toLowerCase();
			plc = $.grep(plc, function(word){
				return /^auto|left|right|top|bottom$/.test(word);
			});
			o.orientation = {x: 'auto', y: 'auto'};
			if (!_plc || _plc === 'auto')
				; // no action
			else if (plc.length === 1){
				switch (plc[0]){
					case 'top':
					case 'bottom':
						o.orientation.y = plc[0];
						break;
					case 'left':
					case 'right':
						o.orientation.x = plc[0];
						break;
				}
			}
			else {
				_plc = $.grep(plc, function(word){
					return /^left|right$/.test(word);
				});
				o.orientation.x = _plc[0] || 'auto';

				_plc = $.grep(plc, function(word){
					return /^top|bottom$/.test(word);
				});
				o.orientation.y = _plc[0] || 'auto';
			}
			if (o.defaultViewDate) {
				var year = o.defaultViewDate.year || new Date().getFullYear();
				var month = o.defaultViewDate.month || 0;
				var day = o.defaultViewDate.day || 1;
				o.defaultViewDate = UTCDate(year, month, day);
			} else {
				o.defaultViewDate = UTCToday();
			}
		},
		_events: [],
		_secondaryEvents: [],
		_applyEvents: function(evs){
			for (var i=0, el, ch, ev; i < evs.length; i++){
				el = evs[i][0];
				if (evs[i].length === 2){
					ch = undefined;
					ev = evs[i][1];
				}
				else if (evs[i].length === 3){
					ch = evs[i][1];
					ev = evs[i][2];
				}
				el.on(ev, ch);
			}
		},
		_unapplyEvents: function(evs){
			for (var i=0, el, ev, ch; i < evs.length; i++){
				el = evs[i][0];
				if (evs[i].length === 2){
					ch = undefined;
					ev = evs[i][1];
				}
				else if (evs[i].length === 3){
					ch = evs[i][1];
					ev = evs[i][2];
				}
				el.off(ev, ch);
			}
		},
		_buildEvents: function(){
            var events = {
                keyup: $.proxy(function(e){
                    if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1)
                        this.update();
                }, this),
                keydown: $.proxy(this.keydown, this),
                paste: $.proxy(this.paste, this)
            };

            if (this.o.showOnFocus === true) {
                events.focus = $.proxy(this.show, this);
            }

            if (this.isInput) { // single input
                this._events = [
                    [this.element, events]
                ];
            }
            else if (this.component && this.hasInput) { // component: input + button
                this._events = [
                    // For components that are not readonly, allow keyboard nav
                    [this.inputField, events],
                    [this.component, {
                        click: $.proxy(this.show, this)
                    }]
                ];
            }
			else {
				this._events = [
					[this.element, {
						click: $.proxy(this.show, this),
						keydown: $.proxy(this.keydown, this)
					}]
				];
			}
			this._events.push(
				// Component: listen for blur on element descendants
				[this.element, '*', {
					blur: $.proxy(function(e){
						this._focused_from = e.target;
					}, this)
				}],
				// Input: listen for blur on element
				[this.element, {
					blur: $.proxy(function(e){
						this._focused_from = e.target;
					}, this)
				}]
			);

			if (this.o.immediateUpdates) {
				// Trigger input updates immediately on changed year/month
				this._events.push([this.element, {
					'changeYear changeMonth': $.proxy(function(e){
						this.update(e.date);
					}, this)
				}]);
			}

			this._secondaryEvents = [
				[this.picker, {
					click: $.proxy(this.click, this)
				}],
				[$(window), {
					resize: $.proxy(this.place, this)
				}],
				[$(document), {
					mousedown: $.proxy(function(e){
						// Clicked outside the datepicker, hide it
						if (!(
							this.element.is(e.target) ||
							this.element.find(e.target).length ||
							this.picker.is(e.target) ||
							this.picker.find(e.target).length ||
							this.isInline
						)){
							this.hide();
						}
					}, this)
				}]
			];
		},
		_attachEvents: function(){
			this._detachEvents();
			this._applyEvents(this._events);
		},
		_detachEvents: function(){
			this._unapplyEvents(this._events);
		},
		_attachSecondaryEvents: function(){
			this._detachSecondaryEvents();
			this._applyEvents(this._secondaryEvents);
		},
		_detachSecondaryEvents: function(){
			this._unapplyEvents(this._secondaryEvents);
		},
		_trigger: function(event, altdate){
			var date = altdate || this.dates.get(-1),
				local_date = this._utc_to_local(date);

			this.element.trigger({
				type: event,
				date: local_date,
				dates: $.map(this.dates, this._utc_to_local),
				format: $.proxy(function(ix, format){
					if (arguments.length === 0){
						ix = this.dates.length - 1;
						format = this.o.format;
					}
					else if (typeof ix === 'string'){
						format = ix;
						ix = this.dates.length - 1;
					}
					format = format || this.o.format;
					var date = this.dates.get(ix);
					return DPGlobal.formatDate(date, format, this.o.language);
				}, this)
			});
		},

		show: function(){
			if (this.inputField.prop('disabled') || (this.inputField.prop('readonly') && this.o.enableOnReadonly === false))
				return;
			if (!this.isInline)
				this.picker.appendTo(this.o.container);
			this.place();
			this.picker.show();
			this._attachSecondaryEvents();
			this._trigger('show');
			if ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && this.o.disableTouchKeyboard) {
				$(this.element).blur();
			}
			return this;
		},

		hide: function(){
			if (this.isInline || !this.picker.is(':visible'))
				return this;
			this.focusDate = null;
			this.picker.hide().detach();
			this._detachSecondaryEvents();
			this.viewMode = this.o.startView;
			this.showMode();

			if (this.o.forceParse && this.inputField.val())
				this.setValue();
			this._trigger('hide');
			return this;
		},

		destroy: function(){
			this.hide();
			this._detachEvents();
			this._detachSecondaryEvents();
			this.picker.remove();
			delete this.element.data().datepicker;
			if (!this.isInput){
				delete this.element.data().date;
			}
			return this;
		},

		paste: function(evt){
			var dateString;
			if (evt.originalEvent.clipboardData && evt.originalEvent.clipboardData.types
				&& $.inArray('text/plain', evt.originalEvent.clipboardData.types) !== -1) {
				dateString = evt.originalEvent.clipboardData.getData('text/plain');
			}
			else if (window.clipboardData) {
				dateString = window.clipboardData.getData('Text');
			}
			else {
				return;
			}
			this.setDate(dateString);
			this.update();
			evt.preventDefault();
		},

		_utc_to_local: function(utc){
			return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000));
		},
		_local_to_utc: function(local){
			return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));
		},
		_zero_time: function(local){
			return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
		},
		_zero_utc_time: function(utc){
			return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));
		},

		getDates: function(){
			return $.map(this.dates, this._utc_to_local);
		},

		getUTCDates: function(){
			return $.map(this.dates, function(d){
				return new Date(d);
			});
		},

		getDate: function(){
			return this._utc_to_local(this.getUTCDate());
		},

		getUTCDate: function(){
			var selected_date = this.dates.get(-1);
			if (typeof selected_date !== 'undefined') {
				return new Date(selected_date);
			} else {
				return null;
			}
		},

		clearDates: function(){
			if (this.inputField) {
				this.inputField.val('');
			}

			this.update();
			this._trigger('changeDate');

			if (this.o.autoclose) {
				this.hide();
			}
		},
		setDates: function(){
			var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
			this.update.apply(this, args);
			this._trigger('changeDate');
			this.setValue();
			return this;
		},

		setUTCDates: function(){
			var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
			this.update.apply(this, $.map(args, this._utc_to_local));
			this._trigger('changeDate');
			this.setValue();
			return this;
		},

		setDate: alias('setDates'),
		setUTCDate: alias('setUTCDates'),
		remove: alias('destroy'),

		setValue: function(){
			var formatted = this.getFormattedDate();
			this.inputField.val(formatted);
			return this;
		},

		getFormattedDate: function(format){
			if (format === undefined)
				format = this.o.format;

			var lang = this.o.language;
			return $.map(this.dates, function(d){
				return DPGlobal.formatDate(d, format, lang);
			}).join(this.o.multidateSeparator);
		},

		getStartDate: function(){
			return this.o.startDate;
		},

		setStartDate: function(startDate){
			this._process_options({startDate: startDate});
			this.update();
			this.updateNavArrows();
			return this;
		},

		getEndDate: function(){
			return this.o.endDate;
		},

		setEndDate: function(endDate){
			this._process_options({endDate: endDate});
			this.update();
			this.updateNavArrows();
			return this;
		},

		setDaysOfWeekDisabled: function(daysOfWeekDisabled){
			this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
			this.update();
			this.updateNavArrows();
			return this;
		},

		setDaysOfWeekHighlighted: function(daysOfWeekHighlighted){
			this._process_options({daysOfWeekHighlighted: daysOfWeekHighlighted});
			this.update();
			return this;
		},

		setDatesDisabled: function(datesDisabled){
			this._process_options({datesDisabled: datesDisabled});
			this.update();
			this.updateNavArrows();
		},

		place: function(){
			if (this.isInline)
				return this;
			var calendarWidth = this.picker.outerWidth(),
				calendarHeight = this.picker.outerHeight(),
				visualPadding = 10,
				container = $(this.o.container),
				windowWidth = container.width(),
				scrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(),
				appendOffset = container.offset();

			var parentsZindex = [];
			this.element.parents().each(function(){
				var itemZIndex = $(this).css('z-index');
				if (itemZIndex !== 'auto' && itemZIndex !== 0) parentsZindex.push(parseInt(itemZIndex));
			});
			var zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset;
			var offset = this.component ? this.component.parent().offset() : this.element.offset();
			var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
			var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
			var left = offset.left - appendOffset.left,
				top = offset.top - appendOffset.top;

			if (this.o.container !== 'body') {
				top += scrollTop;
			}

			this.picker.removeClass(
				'datepicker-orient-top datepicker-orient-bottom '+
				'datepicker-orient-right datepicker-orient-left'
			);

			if (this.o.orientation.x !== 'auto'){
				this.picker.addClass('datepicker-orient-' + this.o.orientation.x);
				if (this.o.orientation.x === 'right')
					left -= calendarWidth - width;
			}
			// auto x orientation is best-placement: if it crosses a window
			// edge, fudge it sideways
			else {
				if (offset.left < 0) {
					// component is outside the window on the left side. Move it into visible range
					this.picker.addClass('datepicker-orient-left');
					left -= offset.left - visualPadding;
				} else if (left + calendarWidth > windowWidth) {
					// the calendar passes the widow right edge. Align it to component right side
					this.picker.addClass('datepicker-orient-right');
					left += width - calendarWidth;
				} else {
					// Default to left
					this.picker.addClass('datepicker-orient-left');
				}
			}

			// auto y orientation is best-situation: top or bottom, no fudging,
			// decision based on which shows more of the calendar
			var yorient = this.o.orientation.y,
				top_overflow;
			if (yorient === 'auto'){
				top_overflow = -scrollTop + top - calendarHeight;
				yorient = top_overflow < 0 ? 'bottom' : 'top';
			}

			this.picker.addClass('datepicker-orient-' + yorient);
			if (yorient === 'top')
				top -= calendarHeight + parseInt(this.picker.css('padding-top'));
			else
				top += height;

			if (this.o.rtl) {
				var right = windowWidth - (left + width);
				this.picker.css({
					top: top,
					right: right,
					zIndex: zIndex
				});
			} else {
				this.picker.css({
					top: top,
					left: left,
					zIndex: zIndex
				});
			}
			return this;
		},

		_allow_update: true,
		update: function(){
			if (!this._allow_update)
				return this;

			var oldDates = this.dates.copy(),
				dates = [],
				fromArgs = false;
			if (arguments.length){
				$.each(arguments, $.proxy(function(i, date){
					if (date instanceof Date)
						date = this._local_to_utc(date);
					dates.push(date);
				}, this));
				fromArgs = true;
			}
			else {
				dates = this.isInput
						? this.element.val()
						: this.element.data('date') || this.inputField.val();
				if (dates && this.o.multidate)
					dates = dates.split(this.o.multidateSeparator);
				else
					dates = [dates];
				delete this.element.data().date;
			}

			dates = $.map(dates, $.proxy(function(date){
				return DPGlobal.parseDate(date, this.o.format, this.o.language, this.o.assumeNearbyYear);
			}, this));
			dates = $.grep(dates, $.proxy(function(date){
				return (
					!this.dateWithinRange(date) ||
					!date
				);
			}, this), true);
			this.dates.replace(dates);

			if (this.dates.length)
				this.viewDate = new Date(this.dates.get(-1));
			else if (this.viewDate < this.o.startDate)
				this.viewDate = new Date(this.o.startDate);
			else if (this.viewDate > this.o.endDate)
				this.viewDate = new Date(this.o.endDate);
			else
				this.viewDate = this.o.defaultViewDate;

			if (fromArgs){
				// setting date by clicking
				this.setValue();
			}
			else if (dates.length){
				// setting date by typing
				if (String(oldDates) !== String(this.dates))
					this._trigger('changeDate');
			}
			if (!this.dates.length && oldDates.length)
				this._trigger('clearDate');

			this.fill();
			this.element.change();
			return this;
		},

		fillDow: function(){
			var dowCnt = this.o.weekStart,
				html = '<tr>';
			if (this.o.calendarWeeks){
				this.picker.find('.datepicker-days .datepicker-switch')
					.attr('colspan', function(i, val){
						return parseInt(val) + 1;
					});
				html += '<th class="cw">&#160;</th>';
			}
			while (dowCnt < this.o.weekStart + 7){
				html += '<th class="dow';
        if ($.inArray(dowCnt, this.o.daysOfWeekDisabled) > -1)
          html += ' disabled';
        html += '">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
			}
			html += '</tr>';
			this.picker.find('.datepicker-days thead').append(html);
		},

		fillMonths: function(){
      var localDate = this._utc_to_local(this.viewDate);
			var html = '',
			i = 0;
			while (i < 12){
        var focused = localDate && localDate.getMonth() === i ? ' focused' : '';
				html += '<span class="month' + focused + '">' + dates[this.o.language].monthsShort[i++]+'</span>';
			}
			this.picker.find('.datepicker-months td').html(html);
		},

		setRange: function(range){
			if (!range || !range.length)
				delete this.range;
			else
				this.range = $.map(range, function(d){
					return d.valueOf();
				});
			this.fill();
		},

		getClassNames: function(date){
			var cls = [],
				year = this.viewDate.getUTCFullYear(),
				month = this.viewDate.getUTCMonth(),
				today = new Date();
			if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){
				cls.push('old');
			}
			else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
				cls.push('new');
			}
			if (this.focusDate && date.valueOf() === this.focusDate.valueOf())
				cls.push('focused');
			// Compare internal UTC date with local today, not UTC today
			if (this.o.todayHighlight &&
				date.getUTCFullYear() === today.getFullYear() &&
				date.getUTCMonth() === today.getMonth() &&
				date.getUTCDate() === today.getDate()){
				cls.push('today');
			}
			if (this.dates.contains(date) !== -1)
				cls.push('active');
			if (!this.dateWithinRange(date)){
				cls.push('disabled');
			}
			if (this.dateIsDisabled(date)){
				cls.push('disabled', 'disabled-date');
			}
			if ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){
				cls.push('highlighted');
			}

			if (this.range){
				if (date > this.range[0] && date < this.range[this.range.length-1]){
					cls.push('range');
				}
				if ($.inArray(date.valueOf(), this.range) !== -1){
					cls.push('selected');
				}
				if (date.valueOf() === this.range[0]){
          cls.push('range-start');
        }
        if (date.valueOf() === this.range[this.range.length-1]){
          cls.push('range-end');
        }
			}
			return cls;
		},

		_fill_yearsView: function(selector, cssClass, factor, step, currentYear, startYear, endYear, callback){
			var html, view, year, steps, startStep, endStep, thisYear, i, classes, tooltip, before;

			html      = '';
			view      = this.picker.find(selector);
			year      = parseInt(currentYear / factor, 10) * factor;
			startStep = parseInt(startYear / step, 10) * step;
			endStep   = parseInt(endYear / step, 10) * step;
			steps     = $.map(this.dates, function(d){
				return parseInt(d.getUTCFullYear() / step, 10) * step;
			});

			view.find('.datepicker-switch').text(year + '-' + (year + step * 9));

			thisYear = year - step;
			for (i = -1; i < 11; i += 1) {
				classes = [cssClass];
				tooltip = null;

				if (i === -1) {
					classes.push('old');
				} else if (i === 10) {
					classes.push('new');
				}
				if ($.inArray(thisYear, steps) !== -1) {
					classes.push('active');
				}
				if (thisYear < startStep || thisYear > endStep) {
					classes.push('disabled');
				}
        if (thisYear === this.viewDate.getFullYear()) {
				  classes.push('focused');
        }

				if (callback !== $.noop) {
					before = callback(new Date(thisYear, 0, 1));
					if (before === undefined) {
						before = {};
					} else if (typeof(before) === 'boolean') {
						before = {enabled: before};
					} else if (typeof(before) === 'string') {
						before = {classes: before};
					}
					if (before.enabled === false) {
						classes.push('disabled');
					}
					if (before.classes) {
						classes = classes.concat(before.classes.split(/\s+/));
					}
					if (before.tooltip) {
						tooltip = before.tooltip;
					}
				}

				html += '<span class="' + classes.join(' ') + '"' + (tooltip ? ' title="' + tooltip + '"' : '') + '>' + thisYear + '</span>';
				thisYear += step;
			}
			view.find('td').html(html);
		},

		fill: function(){
			var d = new Date(this.viewDate),
				year = d.getUTCFullYear(),
				month = d.getUTCMonth(),
				startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
				startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
				endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
				endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
				todaytxt = dates[this.o.language].today || dates['en'].today || '',
				cleartxt = '<div class="beButton blueBtn clear">OK</div>',
				titleFormat = dates[this.o.language].titleFormat || dates['en'].titleFormat,
				tooltip,
				before;
			if (isNaN(year) || isNaN(month))
				return;
			this.picker.find('.datepicker-days .datepicker-switch')
						.text(DPGlobal.formatDate(d, titleFormat, this.o.language));
			this.picker.find('tfoot .today')
						.text(todaytxt)
						.toggle(this.o.todayBtn !== false);
			this.picker.find('tfoot .clear')
						.html(cleartxt)
						.toggle(this.o.clearBtn !== false);
			this.picker.find('thead .datepicker-title')
						.text(this.o.title)
						.toggle(this.o.title !== '');
			this.updateNavArrows();
			this.fillMonths();
			var prevMonth = UTCDate(year, month-1, 28),
				day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
			prevMonth.setUTCDate(day);
			prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
			var nextMonth = new Date(prevMonth);
			if (prevMonth.getUTCFullYear() < 100){
        nextMonth.setUTCFullYear(prevMonth.getUTCFullYear());
      }
			nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
			nextMonth = nextMonth.valueOf();
			var html = [];
			var clsName;
			while (prevMonth.valueOf() < nextMonth){
				if (prevMonth.getUTCDay() === this.o.weekStart){
					html.push('<tr>');
					if (this.o.calendarWeeks){
						// ISO 8601: First week contains first thursday.
						// ISO also states week starts on Monday, but we can be more abstract here.
						var
							// Start of current week: based on weekstart/current date
							ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
							// Thursday of this week
							th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
							// First Thursday of year, year from thursday
							yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
							// Calendar week: ms between thursdays, div ms per day, div 7 days
							calWeek =  (th - yth) / 864e5 / 7 + 1;
						html.push('<td class="cw">'+ calWeek +'</td>');
					}
				}
				clsName = this.getClassNames(prevMonth);
				clsName.push('day');

				if (this.o.beforeShowDay !== $.noop){
					before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
					if (before === undefined)
						before = {};
					else if (typeof(before) === 'boolean')
						before = {enabled: before};
					else if (typeof(before) === 'string')
						before = {classes: before};
					if (before.enabled === false)
						clsName.push('disabled');
					if (before.classes)
						clsName = clsName.concat(before.classes.split(/\s+/));
					if (before.tooltip)
						tooltip = before.tooltip;
				}

				//Check if uniqueSort exists (supported by jquery >=1.12 and >=2.2)
				//Fallback to unique function for older jquery versions
				if ($.isFunction($.uniqueSort)) {
					clsName = $.uniqueSort(clsName);
				} else {
					clsName = $.unique(clsName);
				}

				html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '><span>'+prevMonth.getUTCDate() + '</span></td>');
				tooltip = null;
				if (prevMonth.getUTCDay() === this.o.weekEnd){
					html.push('</tr>');
				}
				prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
			}
			this.picker.find('.datepicker-days tbody').empty().append(html.join(''));

			var monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months';
			var months = this.picker.find('.datepicker-months')
						.find('.datepicker-switch')
							.text(this.o.maxViewMode < 2 ? monthsTitle : year)
							.end()
						.find('span').removeClass('active');

			$.each(this.dates, function(i, d){
				if (d.getUTCFullYear() === year)
					months.eq(d.getUTCMonth()).addClass('active');
			});

			if (year < startYear || year > endYear){
				months.addClass('disabled');
			}
			if (year === startYear){
				months.slice(0, startMonth).addClass('disabled');
			}
			if (year === endYear){
				months.slice(endMonth+1).addClass('disabled');
			}

			if (this.o.beforeShowMonth !== $.noop){
				var that = this;
				$.each(months, function(i, month){
          var moDate = new Date(year, i, 1);
          var before = that.o.beforeShowMonth(moDate);
					if (before === undefined)
						before = {};
					else if (typeof(before) === 'boolean')
						before = {enabled: before};
					else if (typeof(before) === 'string')
						before = {classes: before};
					if (before.enabled === false && !$(month).hasClass('disabled'))
					    $(month).addClass('disabled');
					if (before.classes)
					    $(month).addClass(before.classes);
					if (before.tooltip)
					    $(month).prop('title', before.tooltip);
				});
			}

			// Generating decade/years picker
			this._fill_yearsView(
				'.datepicker-years',
				'year',
				10,
				1,
				year,
				startYear,
				endYear,
				this.o.beforeShowYear
			);

			// Generating century/decades picker
			this._fill_yearsView(
				'.datepicker-decades',
				'decade',
				100,
				10,
				year,
				startYear,
				endYear,
				this.o.beforeShowDecade
			);

			// Generating millennium/centuries picker
			this._fill_yearsView(
				'.datepicker-centuries',
				'century',
				1000,
				100,
				year,
				startYear,
				endYear,
				this.o.beforeShowCentury
			);
		},

		updateNavArrows: function(){
			if (!this._allow_update)
				return;

			var d = new Date(this.viewDate),
				year = d.getUTCFullYear(),
				month = d.getUTCMonth();
			switch (this.viewMode){
				case 0:
					if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){
						this.picker.find('.prev').css({visibility: 'hidden'});
					}
					else {
						this.picker.find('.prev').css({visibility: 'visible'});
					}
					if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){
						this.picker.find('.next').css({visibility: 'hidden'});
					}
					else {
						this.picker.find('.next').css({visibility: 'visible'});
					}
					break;
				case 1:
				case 2:
				case 3:
				case 4:
					if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() || this.o.maxViewMode < 2){
						this.picker.find('.prev').css({visibility: 'hidden'});
					}
					else {
						this.picker.find('.prev').css({visibility: 'visible'});
					}
					if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() || this.o.maxViewMode < 2){
						this.picker.find('.next').css({visibility: 'hidden'});
					}
					else {
						this.picker.find('.next').css({visibility: 'visible'});
					}
					break;
			}
		},

		click: function(e){
			e.preventDefault();
			e.stopPropagation();

			var target, dir, day, year, month, monthChanged, yearChanged;
			target = $(e.target);

			// Clicked on the switch
			if (target.hasClass('datepicker-switch')){
				this.showMode(1);
			}

			// Clicked on prev or next
			var navArrow = target.closest('.prev, .next');
			if (navArrow.length > 0) {
				dir = DPGlobal.modes[this.viewMode].navStep * (navArrow.hasClass('prev') ? -1 : 1);
				if (this.viewMode === 0){
					this.viewDate = this.moveMonth(this.viewDate, dir);
					this._trigger('changeMonth', this.viewDate);
				} else {
					this.viewDate = this.moveYear(this.viewDate, dir);
					if (this.viewMode === 1){
						this._trigger('changeYear', this.viewDate);
					}
				}
				this.fill();
			}

			// Clicked on today button
			if (target.hasClass('today') && !target.hasClass('day')){
				this.showMode(-2);
				this._setDate(UTCToday(), this.o.todayBtn === 'linked' ? null : 'view');
			}

			// Clicked on clear button
			if (target.hasClass('clear')){
				//this.clearDates();
				this.hide();
			}

			if (!target.hasClass('disabled') && !target.parents('td').hasClass('disabled')){
				// Clicked on a day
				if (target.hasClass('day') || target.parents('td').hasClass('day')){
					day = parseInt(target.text(), 10) || 1;
					year = this.viewDate.getUTCFullYear();
					month = this.viewDate.getUTCMonth();

					// From last month
					if (target.hasClass('old') || target.parents('td').hasClass('old')){
						if (month === 0) {
							month = 11;
							year = year - 1;
							monthChanged = true;
							yearChanged = true;
						} else {
							month = month - 1;
							monthChanged = true;
 						}
 					}

					// From next month
					if (target.hasClass('new') || target.parents('td').hasClass('new')) {
						if (month === 11){
							month = 0;
							year = year + 1;
							monthChanged = true;
							yearChanged = true;
 						} else {
							month = month + 1;
							monthChanged = true;
 						}
					}
					this._setDate(UTCDate(year, month, day));
					if (yearChanged) {
						this._trigger('changeYear', this.viewDate);
					}
					if (monthChanged) {
						this._trigger('changeMonth', this.viewDate);
					}
				}

				// Clicked on a month
				if (target.hasClass('month')) {
					this.viewDate.setUTCDate(1);
					day = 1;
					month = target.parent().find('span').index(target);
					year = this.viewDate.getUTCFullYear();
					this.viewDate.setUTCMonth(month);
					this._trigger('changeMonth', this.viewDate);
					if (this.o.minViewMode === 1){
						this._setDate(UTCDate(year, month, day));
						this.showMode();
					} else {
						this.showMode(-1);
					}
					this.fill();
				}

				// Clicked on a year
				if (target.hasClass('year')
						|| target.hasClass('decade')
						|| target.hasClass('century')) {
					this.viewDate.setUTCDate(1);

					day = 1;
					month = 0;
					year = parseInt(target.text(), 10)||0;
					this.viewDate.setUTCFullYear(year);

					if (target.hasClass('year')){
						this._trigger('changeYear', this.viewDate);
						if (this.o.minViewMode === 2){
							this._setDate(UTCDate(year, month, day));
						}
					}
					if (target.hasClass('decade')){
						this._trigger('changeDecade', this.viewDate);
						if (this.o.minViewMode === 3){
							this._setDate(UTCDate(year, month, day));
						}
					}
					if (target.hasClass('century')){
						this._trigger('changeCentury', this.viewDate);
						if (this.o.minViewMode === 4){
							this._setDate(UTCDate(year, month, day));
						}
					}

					this.showMode(-1);
					this.fill();
				}
			}

			if (this.picker.is(':visible') && this._focused_from){
				$(this._focused_from).focus();
			}
			delete this._focused_from;
		},

		_toggle_multidate: function(date){
			var ix = this.dates.contains(date);
			if (!date){
				this.dates.clear();
			}

			if (ix !== -1){
				if (this.o.multidate === true || this.o.multidate > 1 || this.o.toggleActive){
					this.dates.remove(ix);
				}
			} else if (this.o.multidate === false) {
				this.dates.clear();
				this.dates.push(date);
			}
			else {
				this.dates.push(date);
			}

			if (typeof this.o.multidate === 'number')
				while (this.dates.length > this.o.multidate)
					this.dates.remove(0);
		},

		_setDate: function(date, which){
			if (!which || which === 'date')
				this._toggle_multidate(date && new Date(date));
			if (!which || which === 'view')
				this.viewDate = date && new Date(date);

			this.fill();
			this.setValue();
			if (!which || which !== 'view') {
				this._trigger('changeDate');
			}
			if (this.inputField){
				this.inputField.change();
			}
			if (this.o.autoclose && (!which || which === 'date')){
				this.hide();
			}
		},

		moveDay: function(date, dir){
			var newDate = new Date(date);
			newDate.setUTCDate(date.getUTCDate() + dir);

			return newDate;
		},

		moveWeek: function(date, dir){
			return this.moveDay(date, dir * 7);
		},

		moveMonth: function(date, dir){
			if (!isValidDate(date))
				return this.o.defaultViewDate;
			if (!dir)
				return date;
			var new_date = new Date(date.valueOf()),
				day = new_date.getUTCDate(),
				month = new_date.getUTCMonth(),
				mag = Math.abs(dir),
				new_month, test;
			dir = dir > 0 ? 1 : -1;
			if (mag === 1){
				test = dir === -1
					// If going back one month, make sure month is not current month
					// (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
					? function(){
						return new_date.getUTCMonth() === month;
					}
					// If going forward one month, make sure month is as expected
					// (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
					: function(){
						return new_date.getUTCMonth() !== new_month;
					};
				new_month = month + dir;
				new_date.setUTCMonth(new_month);
				// Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
				if (new_month < 0 || new_month > 11)
					new_month = (new_month + 12) % 12;
			}
			else {
				// For magnitudes >1, move one month at a time...
				for (var i=0; i < mag; i++)
					// ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
					new_date = this.moveMonth(new_date, dir);
				// ...then reset the day, keeping it in the new month
				new_month = new_date.getUTCMonth();
				new_date.setUTCDate(day);
				test = function(){
					return new_month !== new_date.getUTCMonth();
				};
			}
			// Common date-resetting loop -- if date is beyond end of month, make it
			// end of month
			while (test()){
				new_date.setUTCDate(--day);
				new_date.setUTCMonth(new_month);
			}
			return new_date;
		},

		moveYear: function(date, dir){
			return this.moveMonth(date, dir*12);
		},

		moveAvailableDate: function(date, dir, fn){
			do {
				date = this[fn](date, dir);

				if (!this.dateWithinRange(date))
					return false;

				fn = 'moveDay';
			}
			while (this.dateIsDisabled(date));

			return date;
		},

		weekOfDateIsDisabled: function(date){
			return $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1;
		},

		dateIsDisabled: function(date){
			return (
				this.weekOfDateIsDisabled(date) ||
				$.grep(this.o.datesDisabled, function(d){
					return isUTCEquals(date, d);
				}).length > 0
			);
		},

		dateWithinRange: function(date){
			return date >= this.o.startDate && date <= this.o.endDate;
		},

		keydown: function(e){
			if (!this.picker.is(':visible')){
				if (e.keyCode === 40 || e.keyCode === 27) { // allow down to re-show picker
					this.show();
					e.stopPropagation();
        }
				return;
			}
			var dateChanged = false,
				dir, newViewDate,
				focusDate = this.focusDate || this.viewDate;
			switch (e.keyCode){
				case 27: // escape
					if (this.focusDate){
						this.focusDate = null;
						this.viewDate = this.dates.get(-1) || this.viewDate;
						this.fill();
					}
					else
						this.hide();
					e.preventDefault();
					e.stopPropagation();
					break;
				case 37: // left
				case 38: // up
				case 39: // right
				case 40: // down
					if (!this.o.keyboardNavigation || this.o.daysOfWeekDisabled.length === 7)
						break;
					dir = e.keyCode === 37 || e.keyCode === 38 ? -1 : 1;
          if (this.viewMode === 0) {
  					if (e.ctrlKey){
  						newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');

  						if (newViewDate)
  							this._trigger('changeYear', this.viewDate);
  					}
  					else if (e.shiftKey){
  						newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');

  						if (newViewDate)
  							this._trigger('changeMonth', this.viewDate);
  					}
  					else if (e.keyCode === 37 || e.keyCode === 39){
  						newViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay');
  					}
  					else if (!this.weekOfDateIsDisabled(focusDate)){
  						newViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek');
  					}
          } else if (this.viewMode === 1) {
            if (e.keyCode === 38 || e.keyCode === 40) {
              dir = dir * 4;
            }
            newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');
          } else if (this.viewMode === 2) {
            if (e.keyCode === 38 || e.keyCode === 40) {
              dir = dir * 4;
            }
            newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');
          }
					if (newViewDate){
						this.focusDate = this.viewDate = newViewDate;
						this.setValue();
						this.fill();
						e.preventDefault();
					}
					break;
				case 13: // enter
					if (!this.o.forceParse)
						break;
					focusDate = this.focusDate || this.dates.get(-1) || this.viewDate;
					if (this.o.keyboardNavigation) {
						this._toggle_multidate(focusDate);
						dateChanged = true;
					}
					this.focusDate = null;
					this.viewDate = this.dates.get(-1) || this.viewDate;
					this.setValue();
					this.fill();
					if (this.picker.is(':visible')){
						e.preventDefault();
						e.stopPropagation();
						if (this.o.autoclose)
							this.hide();
					}
					break;
				case 9: // tab
					this.focusDate = null;
					this.viewDate = this.dates.get(-1) || this.viewDate;
					this.fill();
					this.hide();
					break;
			}
			if (dateChanged){
				if (this.dates.length)
					this._trigger('changeDate');
				else
					this._trigger('clearDate');
				if (this.inputField){
					this.inputField.change();
				}
			}
		},

		showMode: function(dir){
			if (dir){
				this.viewMode = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, this.viewMode + dir));
			}
			this.picker
				.children('div')
				.hide()
				.filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName)
					.show();
			this.updateNavArrows();
		}
	};

	var DateRangePicker = function(element, options){
		$(element).data('datepicker', this);
		this.element = $(element);
		this.inputs = $.map(options.inputs, function(i){
			return i.jquery ? i[0] : i;
		});
		delete options.inputs;

		datepickerPlugin.call($(this.inputs), options)
			.on('changeDate', $.proxy(this.dateUpdated, this));

		this.pickers = $.map(this.inputs, function(i){
			return $(i).data('datepicker');
		});
		this.updateDates();
	};
	DateRangePicker.prototype = {
		updateDates: function(){
			this.dates = $.map(this.pickers, function(i){
				return i.getUTCDate();
			});
			this.updateRanges();
		},
		updateRanges: function(){
			var range = $.map(this.dates, function(d){
				return d.valueOf();
			});
			$.each(this.pickers, function(i, p){
				p.setRange(range);
			});
		},
		dateUpdated: function(e){
			// `this.updating` is a workaround for preventing infinite recursion
			// between `changeDate` triggering and `setUTCDate` calling.  Until
			// there is a better mechanism.
			if (this.updating)
				return;
			this.updating = true;

			var dp = $(e.target).data('datepicker');

			if (typeof(dp) === "undefined") {
				return;
			}

			var new_date = dp.getUTCDate(),
				i = $.inArray(e.target, this.inputs),
				j = i - 1,
				k = i + 1,
				l = this.inputs.length;
			if (i === -1)
				return;

			$.each(this.pickers, function(i, p){
				if (!p.getUTCDate())
					p.setUTCDate(new_date);
			});

			if (new_date < this.dates[j]){
				// Date being moved earlier/left
				while (j >= 0 && new_date < this.dates[j]){
					this.pickers[j--].setUTCDate(new_date);
				}
			}
			else if (new_date > this.dates[k]){
				// Date being moved later/right
				while (k < l && new_date > this.dates[k]){
					this.pickers[k++].setUTCDate(new_date);
				}
			}
			this.updateDates();

			delete this.updating;
		},
		remove: function(){
			$.map(this.pickers, function(p){ p.remove(); });
			delete this.element.data().datepicker;
		}
	};

	function opts_from_el(el, prefix){
		// Derive options from element data-attrs
		var data = $(el).data(),
			out = {}, inkey,
			replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])');
		prefix = new RegExp('^' + prefix.toLowerCase());
		function re_lower(_,a){
			return a.toLowerCase();
		}
		for (var key in data)
			if (prefix.test(key)){
				inkey = key.replace(replace, re_lower);
				out[inkey] = data[key];
			}
		return out;
	}

	function opts_from_locale(lang){
		// Derive options from locale plugins
		var out = {};
		// Check if "de-DE" style date is available, if not language should
		// fallback to 2 letter code eg "de"
		if (!dates[lang]){
			lang = lang.split('-')[0];
			if (!dates[lang])
				return;
		}
		var d = dates[lang];
		$.each(locale_opts, function(i,k){
			if (k in d)
				out[k] = d[k];
		});
		return out;
	}

	var old = $.fn.datepicker;
	var datepickerPlugin = function(option){
		var args = Array.apply(null, arguments);
		args.shift();
		var internal_return;
		this.each(function(){
			var $this = $(this),
				data = $this.data('datepicker'),
				options = typeof option === 'object' && option;
			if (!data){
				var elopts = opts_from_el(this, 'date'),
					// Preliminary otions
					xopts = $.extend({}, defaults, elopts, options),
					locopts = opts_from_locale(xopts.language),
					// Options priority: js args, data-attrs, locales, defaults
					opts = $.extend({}, defaults, locopts, elopts, options);
				if ($this.hasClass('input-daterange') || opts.inputs){
					$.extend(opts, {
						inputs: opts.inputs || $this.find('input').toArray()
					});
					data = new DateRangePicker(this, opts);
				}
				else {
					data = new Datepicker(this, opts);
				}
				$this.data('datepicker', data);
			}
			if (typeof option === 'string' && typeof data[option] === 'function'){
				internal_return = data[option].apply(data, args);
			}
		});

		if (
			internal_return === undefined ||
			internal_return instanceof Datepicker ||
			internal_return instanceof DateRangePicker
		)
			return this;

		if (this.length > 1)
			throw new Error('Using only allowed for the collection of a single element (' + option + ' function)');
		else
			return internal_return;
	};
	$.fn.datepicker = datepickerPlugin;

	var defaults = $.fn.datepicker.defaults = {
		assumeNearbyYear: false,
		autoclose: false,
		beforeShowDay: $.noop,
		beforeShowMonth: $.noop,
		beforeShowYear: $.noop,
		beforeShowDecade: $.noop,
		beforeShowCentury: $.noop,
		calendarWeeks: false,
		clearBtn: false,
		toggleActive: false,
		daysOfWeekDisabled: [],
		daysOfWeekHighlighted: [],
		datesDisabled: [],
		endDate: Infinity,
		forceParse: true,
		format: 'd.m.yyyy',
		keyboardNavigation: true,
		language: 'en',
		minViewMode: 0,
		maxViewMode: 4,
		multidate: false,
		multidateSeparator: ',',
		orientation: "auto",
		rtl: false,
		startDate: -Infinity,
		startView: 0,
		todayBtn: false,
		todayHighlight: false,
		weekStart: 0,
		disableTouchKeyboard: false,
		enableOnReadonly: true,
		showOnFocus: true,
		zIndexOffset: 10,
		container: 'body',
		immediateUpdates: false,
		title: '',
		templates: {
			leftArrow: '&laquo;',
			rightArrow: '&raquo;'
		}
	};
	var locale_opts = $.fn.datepicker.locale_opts = [
		'format',
		'rtl',
		'weekStart'
	];
	$.fn.datepicker.Constructor = Datepicker;
	var dates = $.fn.datepicker.dates = {
		en: {
			days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
			daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
			daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
			months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
			monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
			today: "Today",
			clear: "Clear",
			titleFormat: "MM yyyy"
		}
	};

	var DPGlobal = {
		modes: [
			{
				clsName: 'days',
				navFnc: 'Month',
				navStep: 1
			},
			{
				clsName: 'months',
				navFnc: 'FullYear',
				navStep: 1
			},
			{
				clsName: 'years',
				navFnc: 'FullYear',
				navStep: 10
			},
			{
				clsName: 'decades',
				navFnc: 'FullDecade',
				navStep: 100
			},
			{
				clsName: 'centuries',
				navFnc: 'FullCentury',
				navStep: 1000
		}],
		isLeapYear: function(year){
			return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
		},
		getDaysInMonth: function(year, month){
			return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
		},
		validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
		nonpunctuation: /[^ -\/:-@\u5e74\u6708\u65e5\[-`{-~\t\n\r]+/g,
		parseFormat: function(format){
			if (typeof format.toValue === 'function' && typeof format.toDisplay === 'function')
                return format;
            // IE treats \0 as a string end in inputs (truncating the value),
			// so it's a bad format delimiter, anyway
			var separators = format.replace(this.validParts, '\0').split('\0'),
				parts = format.match(this.validParts);
			if (!separators || !separators.length || !parts || parts.length === 0){
				throw new Error("Invalid date format.");
			}
			return {separators: separators, parts: parts};
		},
		parseDate: function(date, format, language, assumeNearby){
			if (!date)
				return undefined;
			if (date instanceof Date)
				return date;
			if (typeof format === 'string')
				format = DPGlobal.parseFormat(format);
			if (format.toValue)
                return format.toValue(date, format, language);
            var part_re = /([\-+]\d+)([dmwy])/,
				parts = date.match(/([\-+]\d+)([dmwy])/g),
				fn_map = {
					d: 'moveDay',
					m: 'moveMonth',
					w: 'moveWeek',
					y: 'moveYear'
				},
				dateAliases = {
					yesterday: '-1d',
					today: '+0d',
					tomorrow: '+1d'
				},
				part, dir, i, fn;
			if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
				date = new Date();
				for (i=0; i < parts.length; i++){
					part = part_re.exec(parts[i]);
					dir = parseInt(part[1]);
					fn = fn_map[part[2]];
					date = Datepicker.prototype[fn](date, dir);
				}
				return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
			}

			if (typeof dateAliases[date] !== 'undefined') {
				date = dateAliases[date];
				parts = date.match(/([\-+]\d+)([dmwy])/g);

				if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
					date = new Date();
				  	for (i=0; i < parts.length; i++){
						part = part_re.exec(parts[i]);
						dir = parseInt(part[1]);
						fn = fn_map[part[2]];
						date = Datepicker.prototype[fn](date, dir);
				  	}

			  		return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
				}
			}

			parts = date && date.match(this.nonpunctuation) || [];
			date = new Date();

			function applyNearbyYear(year, threshold){
				if (threshold === true)
					threshold = 10;

				// if year is 2 digits or less, than the user most likely is trying to get a recent century
				if (year < 100){
					year += 2000;
					// if the new year is more than threshold years in advance, use last century
					if (year > ((new Date()).getFullYear()+threshold)){
						year -= 100;
					}
				}

				return year;
			}

			var parsed = {},
				setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
				setters_map = {
					yyyy: function(d,v){
						return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
					},
					yy: function(d,v){
						return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
					},
					m: function(d,v){
						if (isNaN(d))
							return d;
						v -= 1;
						while (v < 0) v += 12;
						v %= 12;
						d.setUTCMonth(v);
						while (d.getUTCMonth() !== v)
							d.setUTCDate(d.getUTCDate()-1);
						return d;
					},
					d: function(d,v){
						return d.setUTCDate(v);
					}
				},
				val, filtered;
			setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
			setters_map['dd'] = setters_map['d'];
			date = UTCToday();
			var fparts = format.parts.slice();
			// Remove noop parts
			if (parts.length !== fparts.length){
				fparts = $(fparts).filter(function(i,p){
					return $.inArray(p, setters_order) !== -1;
				}).toArray();
			}
			// Process remainder
			function match_part(){
				var m = this.slice(0, parts[i].length),
					p = parts[i].slice(0, m.length);
				return m.toLowerCase() === p.toLowerCase();
			}
			if (parts.length === fparts.length){
				var cnt;
				for (i=0, cnt = fparts.length; i < cnt; i++){
					val = parseInt(parts[i], 10);
					part = fparts[i];
					if (isNaN(val)){
						switch (part){
							case 'MM':
								filtered = $(dates[language].months).filter(match_part);
								val = $.inArray(filtered[0], dates[language].months) + 1;
								break;
							case 'M':
								filtered = $(dates[language].monthsShort).filter(match_part);
								val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
								break;
						}
					}
					parsed[part] = val;
				}
				var _date, s;
				for (i=0; i < setters_order.length; i++){
					s = setters_order[i];
					if (s in parsed && !isNaN(parsed[s])){
						_date = new Date(date);
						setters_map[s](_date, parsed[s]);
						if (!isNaN(_date))
							date = _date;
					}
				}
			}
			return date;
		},
		formatDate: function(date, format, language){
			if (!date)
				return '';
			if (typeof format === 'string')
				format = DPGlobal.parseFormat(format);
			if (format.toDisplay)
                return format.toDisplay(date, format, language);
            var val = {
				d: date.getUTCDate(),
				D: dates[language].daysShort[date.getUTCDay()],
				DD: dates[language].days[date.getUTCDay()],
				m: date.getUTCMonth() + 1,
				M: dates[language].monthsShort[date.getUTCMonth()],
				MM: dates[language].months[date.getUTCMonth()],
				yy: date.getUTCFullYear().toString().substring(2),
				yyyy: date.getUTCFullYear()
			};
			val.dd = (val.d < 10 ? '0' : '') + val.d;
			val.mm = (val.m < 10 ? '0' : '') + val.m;
			date = [];
			var seps = $.extend([], format.separators);
			for (var i=0, cnt = format.parts.length; i <= cnt; i++){
				if (seps.length)
					date.push(seps.shift());
				date.push(val[format.parts[i]]);
			}
			return date.join('');
		},
		headTemplate: '<thead>'+
			              '<tr>'+
			                '<th colspan="7" class="datepicker-title"></th>'+
			              '</tr>'+
							'<tr>'+
								'<th class="prev" colspan="1">&laquo;</th>'+
								'<th colspan="5" style="position:relative;"><span class="datepicker-switch"></span</th>'+
								'<th class="next" colspan="1">&raquo;</th>'+
							'</tr>'+
						'</thead>',
		contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
		footTemplate: '<tfoot>'+
							'<tr>'+
								'<th colspan="7" class="today"></th>'+
							'</tr>'+
							'<tr>'+
								'<th colspan="7" class="clear"></th>'+
							'</tr>'+
						'</tfoot>'
	};

	if (isMobile()) {
		DPGlobal.headTemplate = '<thead>'+
		'<tr>'+
		'<th colspan="7" class="datepicker-title"></th>'+
		'</tr>'+
		'<tr>'+
		'<th class="prev" colspan="1">&laquo;</th>'+
		'<th colspan="5" class="datepicker-switch"></th>'+
		'<th class="next" colspan="1">&raquo;</th>'+
		'</tr>'+
		'</thead>'
	}

	DPGlobal.template = '<div class="datepicker">'+
							'<div class="datepicker-days">'+
								'<table class="table-condensed">'+
									DPGlobal.headTemplate+
									'<tbody></tbody>'+
									DPGlobal.footTemplate+
								'</table>'+
							'</div>'+
							'<div class="datepicker-months">'+
								'<table class="table-condensed">'+
									DPGlobal.headTemplate+
									DPGlobal.contTemplate+
									DPGlobal.footTemplate+
								'</table>'+
							'</div>'+
							'<div class="datepicker-years">'+
								'<table class="table-condensed">'+
									DPGlobal.headTemplate+
									DPGlobal.contTemplate+
									DPGlobal.footTemplate+
								'</table>'+
							'</div>'+
							'<div class="datepicker-decades">'+
								'<table class="table-condensed">'+
									DPGlobal.headTemplate+
									DPGlobal.contTemplate+
									DPGlobal.footTemplate+
								'</table>'+
							'</div>'+
							'<div class="datepicker-centuries">'+
								'<table class="table-condensed">'+
									DPGlobal.headTemplate+
									DPGlobal.contTemplate+
									DPGlobal.footTemplate+
								'</table>'+
							'</div>'+
						'</div>';

	$.fn.datepicker.DPGlobal = DPGlobal;


	/* DATEPICKER NO CONFLICT
	* =================== */

	$.fn.datepicker.noConflict = function(){
		$.fn.datepicker = old;
		return this;
	};

	/* DATEPICKER VERSION
	 * =================== */
	$.fn.datepicker.version = '1.6.4';

	/* DATEPICKER DATA-API
	* ================== */

	$(document).on(
		'focus.datepicker.data-api click.datepicker.data-api',
		'[data-provide="datepicker"]',
		function(e){
			var $this = $(this);
			if ($this.data('datepicker'))
				return;
			e.preventDefault();
			// component click requires us to explicitly show it
			datepickerPlugin.call($this, 'show');
		}
	);
	$(function(){
		datepickerPlugin.call($('[data-provide="datepicker-inline"]'));
	});

}));

// no conflict mode
if (!$.fn.bootstrapDP && $.fn.datepicker && $.fn.datepicker.noConflict) {
	var datepicker = $.fn.datepicker.noConflict();
	$.fn.bootstrapDP = datepicker;
}
!function(a){a.fn.bootstrapDP.dates.sv={days:["Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag"],daysShort:["Sön","Mån","Tis","Ons","Tor","Fre","Lör"],daysMin:["Sö","Må","Ti","On","To","Fr","Lö"],months:["Januari","Februari","Mars","April","Maj","Juni","Juli","Augusti","September","Oktober","November","December"],monthsShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],today:"Idag",format:"yyyy-mm-dd",weekStart:1,clear:"Rensa"}}(jQuery);

function initBootstrapCals() {

    var bsDatePickerLoaded = false;
    var hasCals = (CalendarSetup.hasArrivalElement() && CalendarSetup.hasDepartureElement());

    if (hasCals)
    {
        
        if (CalendarSetup.getArrivalElement().val() == '') {
            var today = CalendarSetup.printDateFormat(CalendarSetup.today(), jsConfig.calDateFormat);
            CalendarSetup.getArrivalElement().val(today);
        }

        CalendarSetup.getArrivalElement().bootstrapDP({
            weekStart: 1,
            maxViewMode: 0,
            language: transformLanguageCode(jsConfig.language),
            todayHighlight: true,
            autoclose: true,
            startDate: CalendarSetup.printDateFormat(new Date(), jsConfig.calDateFormat),
            format: jsConfig.calDateFormat,
        }).unbind('changeDate').on('changeDate', function (e) {
            JSONDatePickedArrival();
            if (bsDatePickerLoaded) {
                CalendarSetup.getDepartureElement().bootstrapDP("show");
            } else {
                bsDatePickerLoaded = true;
            }
        }).on('show', function (e) {
            hideDatepickerTooltip();
            showDatepickerTooltip('arrival');
        }).on('hide', function(e) {
            hideDatepickerTooltip();
        });

        CalendarSetup.getDepartureElement().bootstrapDP({
            weekStart: 1,
            maxViewMode: 0,
            language: transformLanguageCode(jsConfig.language),
            todayHighlight: true,
            autoclose: true,
            startDate: CalendarSetup.printDateFormat(CalendarSetup.getDatePlus(new Date(), 1), jsConfig.calDateFormat),
            format: jsConfig.calDateFormat,
            clearBtn: true,
        }).on('changeDate', function (e) {
            JSONDatePickedDeparture();
        }).on('show', function (e) {
            hideDatepickerTooltip();
            setTimeout(function() {showDatepickerTooltip('departure')}, 200);
        }).on('hide', function(e) {
            hideDatepickerTooltip();
        });

        // Sets Defaults, also used onSelect
        //JSONDatePickedArrival();

        // ensimäisellä kerralla pitää asettaa saapumispäivä objektille.
        if (typeof getSMJSONArrivalDate() != 'undefined' && !isDateInThePast(getSMJSONArrivalDate())) {
            CalendarSetup.getArrivalElement().bootstrapDP('setDate', getSMJSONArrivalDate());
        } else {
            CalendarSetup.getArrivalElement().bootstrapDP('setDate', new Date());
            JSONDatePickedArrival();
        }
        

        CalendarSetup.getStayNightsElement().change(function(){
            JSONDatePickedArrival();

        });

    }
}

function showDatepickerTooltip(target) {
    if (target == 'arrival') {
        jQuery('.bindDatePickerTooltip.arrival').show();
    }
    else if (target == 'departure') {
        jQuery('.bindDatePickerTooltip.departure').show();
    }
    else  {
        console.log("showDatepickerTooltip(), target is missing" );
    }
}

function hideDatepickerTooltip() {
    jQuery('.bindDatePickerTooltip').hide();
}

function transformLanguageCode(gothiaLangCode) {
    if (gothiaLangCode == 's') {
        return 'sv';
    }
    else if (gothiaLangCode == 'e') {
        return 'en';
    }
    else {
        console.error('weird langCode: '+ gothiaLangCode);
        return false;
    }
}

function isDateInThePast(date){
    if (typeof date != 'undefined') {
        var arrDate = date.getTime();
        var nowTimeStamp = new Date();
        nowTimeStamp.setHours(0,0,0,0);
        nowTimeStamp = nowTimeStamp.getTime();

        if (nowTimeStamp > arrDate) {
            return true;
        } else {
            return false;
        }
    }
}



var JSONDatePickedArrival = function(date,picker)
{
    console.log('datepickedArrival');
    hideDatepickerTooltip();
    var departureId = jQuery(this).attr('data-departure');
    if (exists(departureId))
    {
        var hasArrivalElement 	= true;
        var hasDepartureElement = true;
        var arrivalElement		= jQuery(this);
        var departureElement	= jQuery(departureId);
        var arrivalDate 		= jQuery(this).bootstrapDP("getDate");
    }
    else
    {

        var hasArrivalElement 	= CalendarSetup.hasArrivalElement();
        var hasDepartureElement = CalendarSetup.hasDepartureElement();
        var arrivalElement		= CalendarSetup.getArrivalElement();
        var departureElement	= CalendarSetup.getDepartureElement();
        var arrivalDate 		= CalendarSetup.getArrivalDate();

    }

    var minStayNights = jsConfig.minStayNights;


    var hasNightsElement = CalendarSetup.hasStayNightsElement();


    // Jos on nights elementti, niin testaa toimiiko tämä. ei ole testattu bootstrapdatepickerin kanssa.
    if (hasNightsElement && hasArrivalElement)
    {
        var stayNights = parseInt(CalendarSetup.getStayNightsElement().val());
        if (typeof CalendarSetup.getStayNightsElement().val() == 'undefined' || CalendarSetup.getStayNightsElement().val() == "") {
            stayNights = minStayNights;
        }
        // arrival selected, set the departure as minimum requirements
        if (stayNights<minStayNights)
        {
            CalendarSetup.getStayNightsElement().val(minStayNights);

            stayNights = minStayNights;
        }
        

        departureDate = CalendarSetup.getNextValidDepartureDay(CalendarSetup.getDatePlus(arrivalDate,stayNights));
        newStartDate = CalendarSetup.getNextValidDepartureDay(CalendarSetup.getDatePlus(arrivalDate,1));
        departureElement.bootstrapDP("setStartDate",newStartDate);
        departureElement.bootstrapDP("setDate",departureDate);


    }


    if (hasDepartureElement && !hasNightsElement)
    {
        stayNights = minStayNights;

        departureElement.bootstrapDP("setStartDate", CalendarSetup.getDatePlus(arrivalDate,minStayNights));
        var departureDate 	= departureElement.bootstrapDP("getDate");
        var dateToCheck 	= CalendarSetup.getDatePlus(arrivalDate,stayNights); // tarkistetaan että mikäli deprture on jo kaukakan tulevaisuudesta, niin ei automaattisesti

        if (departureDate<dateToCheck || departureDate==dateToCheck)
        {
            departureDate = CalendarSetup.getNextValidDepartureDay(CalendarSetup.getDatePlus(arrivalDate,stayNights));
            departureElement.bootstrapDP("setDate",departureDate);

        }


    }
};

var JSONDatePickedDeparture= function()
{
    hideDatepickerTooltip();
    if (CalendarSetup.hasStayNightsElement())
    {
        var arrivalDate = CalendarSetup.getArrivalDate();
        var departureDate 	= CalendarSetup.getDepartureDate();
        if (arrivalDate != null && departureDate != null) {
            var stayNights = CalendarSetup.diff(arrivalDate,departureDate,86400);
        }

        CalendarSetup.getStayNightsElement().val(stayNights);

    }
};








// clean below
/*
var hasCals = (CalendarSetup.hasArrivalElement() && CalendarSetup.hasDepartureElement());


if (CalendarSetup.calendarCalled==0) {
    if (hasCals)
    {
        if (CalendarSetup.getArrivalElement().val()=='')
        {
            var today = CalendarSetup.printDateFormat(CalendarSetup.today(),jsConfig.calDateFormat);
            CalendarSetup.getArrivalElement().val(today);
        }

        if (typeof avCalSearchMask != "undefined") {
            jsConfig.calAvSearchMask = avCalSearchMask;
        }
        var nroOfMonths = 2;
        if (jQuery(window).width()<768)
        {
            nroOfMonths = 1;
        }

        jQuery(CalendarSetup.getArrivalElement()).bootstrapDP({
            onSelect: DefaultDatePickedArrival,
            dateFormat: jsConfig.calDateFormat,
            numberOfMonths: nroOfMonths,
            changeMonth: false,
            changeYear: false,
            yearRange: '-0:+2',
            minDate: new Date(),
            firstDay: 1
        });

        jQuery(CalendarSetup.getDepartureElement()).bootstrapDP({
            onSelect: DefaultDatePickedDeparture,
            dateFormat: jsConfig.calDateFormat,
            numberOfMonths: 1,
            changeMonth: false,
            changeYear: false,
            yearRange: '-0:+2',
            firstDay: 1
        });

        jQuery(CalendarSetup.getStayNightsElement()).change(function() {
            DefaultDatePickedArrival();
        });

        // Sets Defaults, also used onSelect
        DefaultDatePickedArrival();
    }
}
*/

function bindSearchMaskButtons()
{
	jQuery('#smMakeNewSearch').unbind('click').click(function()
	{
		jQuery(this).hide();
		jQuery('#smSearchMask').show('slide');
		jQuery('#ssContainer').hide('slide');
		//jQuery('#ssStartOver').hide();

	});

	jQuery('#ssStartOver').unbind('click').click(function()
	{
		if (confirm(jsConfig.lang.confirmStartOver))
		{
			goHome();
		}
	});

	jQuery('.smSavedCompanyId').unbind('click').click(function(){

		//jQuery('#combined').val(jQuery(this).html());
		app_postback_ajax('appcontrol_ucSearchMask','btnToggleCode', 'server-ajax: btnToggleCode_OnClick', '','')
	});



	jQuery('.bindShowSmInputs').unbind('click').click(function(){
		jQuery('.smSummary').hide();
		jQuery('.smInputs').show();
	});

	jQuery('.bindAddChild').unbind('click').click(function(){
		var room = jQuery(this).parents('.SMJSON-roomDetails');
		room.find('.kidAgeWrap').not('.enabled').first().addClass('enabled');
		countKids(room);
		countOccupants();
	});

	jQuery('.bindRemoveChild').unbind('click').click(function(){
		var room = jQuery(this).parents('.SMJSON-roomDetails');
		var childRow = jQuery(this).parents('.kidAgeWrap');
		childRow.removeClass('enabled');
		countKids(room);
		countOccupants();
	});
}

function countKids (room) {
	var childCountInput = room.find('.SMJSON-childrenAmount');
	var childCount = 0;
	room.find('.kidAgeWrap').each(function(){
		if (jQuery(this).hasClass('enabled')) {
			childCount ++;
		}
	});
	childCountInput.val(childCount);

	//get beds if all ages selected
	var allAgesSelected = true;
	room.find('.SMJSON-childAge').each(function(){

		if (jQuery(this).data('cb') <= childCount) {
			if (jQuery(this).val() == -1 || jQuery(this).val() == null) {
				allAgesSelected = false;
			}
		}
	});

}

function bindSmChangeFunctionsLast() {
	setTimeout(function(){
		jQuery('.smCalendar').change(function () {
			showAvOverlay();
		});
	}, 5000);

}

function goHome()
{
	document.location = jsConfig.baseUrl+'/reserve/home';
}

function goWebSite()
{
	document.location = 'http://www.gothiatowers.com/';
}

function showAvOverlay()
{
	jQuery('.bindAvOverlay').show();
	jQuery('.bindBookButtonTextBook').hide();
	jQuery('.bindBookButtonTextUpdate').show();
}




function jsonSearchmaskFunctions() {

	countRooms();
	countOccupants(true);
	populateSmSummary();
	bindToggleRoomPolicy();



	if (findGetParameter('showOccupancy') == 1) {

		showOccupancyPopup();
	}
	if (findGetParameter('showCodeInput') == 1) {

		showCodeInput();
	}

	jQuery('#SMJSON-combinedCode').val(getSMJSONProperty('combinedCode', 0));
	setCode(false);

	jQuery('#SMJSON-numberOfRooms').unbind('change').change(function(){
		showAvOverlay();
		countRooms();
	});
	jQuery('.SMJSON-childrenAmount').unbind('change').change(function(){
		showAvOverlay();
		countOccupants();
	});
	jQuery('.SMJSON-adultsAmount').unbind('change').change(function(){
		showAvOverlay();
		countOccupants();
	});
	if (isMobile()) {
		jQuery('.bindShowOccupancyPopup').fancybox({
			'padding': 0,
			'width': '100%',
			'height': '100%',
			'topRatio': 0,
			'leftRatio': 0,
			'margin': 0,
			'autoSize': false,
			'fitToView': true,
			'wrapCSS': 'smFancybox',


		});
		jQuery('.bindOpenSmCodePopup').fancybox({
			'padding': 0,
			'width': '100%',
			'height': '100%',
			'topRatio': 0,
			'leftRatio': 0,
			'margin': 0,
			'autoSize': false,
			'fitToView': true,
			'wrapCSS': 'smFancybox',

		});
	}
	else {
		jQuery('.bindShowOccupancyPopup').fancybox({
			'padding': 0,
			'minWidth': 500,
			'maxWidth': 500,
			'fitToView': true,
			'wrapCSS': 'smFancybox',

		});
		jQuery('.bindOpenSmCodePopup').fancybox({
			'padding': 0,
			'minWidth': 500,
			'maxWidth': 500,
			'wrapCSS': 'smFancybox'
		});
	}


	jQuery('.bindToggleOccupancy').unbind('click').click(function(){
		jQuery('.bindToggleOccupancyQuickSelect').toggleClass('active');
	});

	jQuery('.bindSmAddRoom').unbind('click').click(function(){
		var maxRooms = parseInt(jQuery(this).data('max'));
		addRoom(maxRooms);
	});
	jQuery('.bindRemoveRoom').unbind().click(function(){
		removeRoom(jQuery(this));
	});
	jQuery('.bindCloseFancybox').unbind('click').click(function(){
		jQuery.fancybox.close();
	});
	jQuery('.bindOccQuickSelect').unbind('click').click(function(){
		quickSelectOccupants(jQuery(this));
	});
	jQuery('.bindToggleRoomDetailsContent').unbind('click').click(function(){
		toggleRoomDetailsContent(jQuery(this));
	});
	jQuery('.bindSetCode').unbind('click').click(function(){
		setCode(true);
		jQuery.fancybox.close();
	});
	jQuery('.SMJSON-childAge').unbind('change').change(function(){
		countOccupants();
	});
	jQuery('.SMJSON-adultsAmount').unbind('change').change(function(){
		var roomContext = jQuery(this).parents('.SMJSON-roomDetails');
		getBedSelectionsAjax(0, roomContext);
	});
	jQuery('.bindCloseLoggedInAnnounce').click(function(){
		jQuery(this).parents('.smLoggedInAnnounce').fadeOut();
	});
	jQuery('.bindShowLoggedInSelections').click(function(e){
		e.preventDefault();
		jQuery(this).siblings('.bindLoggedInSelections').toggleClass('open');
	});
}

function jsonSearchmaskFunctionsAfterAjax() {

	populateSmSummary();
	bindToggleRoomPolicy();

	jQuery('#SMJSON-numberOfRooms').unbind('change').change(function(){
		showAvOverlay();
		countRooms();
	});
	jQuery('.SMJSON-childrenAmount').unbind('change').change(function(){
		showAvOverlay();
		countOccupants();
	});
	jQuery('.SMJSON-adultsAmount').unbind('change').change(function(){
		showAvOverlay();
		countOccupants();
	});
	/*if (isMobile()) {
		jQuery('.bindShowOccupancyPopup').fancybox({
			'padding': 0,
			'width': '100%',
			'height': '100%',
			'topRatio': 0,
			'leftRatio': 0,
			'margin': 0,
			'autoSize': false,
			'fitToView': true,
			'wrapCSS': 'smFancybox'
		});
		jQuery('.bindOpenSmCodePopup').fancybox({
			'padding': 0,
			'width': '100%',
			'height': '100%',
			'topRatio': 0,
			'leftRatio': 0,
			'margin': 0,
			'autoSize': false,
			'fitToView': true,
			'wrapCSS': 'smFancybox'
		});
	}
	else {
		jQuery('.bindShowOccupancyPopup').fancybox({
			'padding': 0,
			'minWidth': 500,
			'maxWidth': 500,
			'fitToView': true,
			'wrapCSS': 'smFancybox'
		});
		jQuery('.bindOpenSmCodePopup').fancybox({
			'padding': 0,
			'minWidth': 500,
			'maxWidth': 500,
			'wrapCSS': 'smFancybox'
		});
	}*/


	jQuery('.bindToggleOccupancy').unbind('click').click(function(){
		jQuery('.bindToggleOccupancyQuickSelect').toggleClass('active');
	});

	jQuery('.bindSmAddRoom').unbind('click').click(function(){
		var maxRooms = parseInt(jQuery(this).data('max'));
		addRoom(maxRooms);
	});
	jQuery('.bindRemoveRoom').unbind().click(function(){
		removeRoom(jQuery(this));
	});
	jQuery('.bindCloseFancybox').unbind('click').click(function(){
		jQuery.fancybox.close();
	});
	jQuery('.bindOccQuickSelect').unbind('click').click(function(){
		quickSelectOccupants(jQuery(this));
	});
	jQuery('.bindToggleRoomDetailsContent').unbind('click').click(function(){
		toggleRoomDetailsContent(jQuery(this));
	});
	jQuery('.bindSetCode').unbind('click').click(function(){
		setCode(true);
		jQuery.fancybox.close();
	});
	jQuery('.SMJSON-childAge').unbind('change').change(function(){
		countOccupants();
	});
	jQuery('.SMJSON-adultsAmount').unbind('change').change(function(){
		var roomContext = jQuery(this).parents('.SMJSON-roomDetails');
		getBedSelectionsAjax(0, roomContext);
	});

}

function bindToggleRoomPolicy() {
	jQuery('.bindToggleRoomPolicy').unbind('click').click(function(){
		jQuery('.fullRoomPolicy').toggle();
		jQuery('.smPopupFooter').toggle();
		jQuery('.occupancyPopupContent').toggle();
		jQuery(this).parents('.fancybox-wrap').find('.fancybox-close').toggle();
	});
}


function triggerBedSelectionsOnload() {
	var rooms = parseInt(jQuery('#SMJSON-numberOfRooms').val());
	for (var i=0; i<rooms; i++) {
		var beds=getSMJSONProperty('childrenBeds', i);
		var occnro = i+1;
		var room = jQuery('.smRoomDetails[occnro="'+occnro+'"]');
		getBedSelectionsAjax(0, room, true);
	}

}


var childBedOptionsData = [];

function selectChildBedOption(roomContext,index, isOnPageload) {

	//console.log(roomContext);
	//console.log(childBedOptionsData);
	//console.log('length: ', childBedOptionsData.bedoptions.length, 'index: ', index);

	if (childBedOptionsData.bedoptions.length>=index) {

        // take the first one as default
        var chosenOption = childBedOptionsData.bedoptions[index];
        var childIndex = 1;


        if (chosenOption) {


            jQuery.each(chosenOption, function(key, item){
                //console.log("Bed is " + key + "|" + item);
                roomContext.find('.SMJSON-childBed[data-cb="'+childIndex+'"]').val(item.text).data('key',item.code);
                childIndex = childIndex + 1;
            });
		}

	}

    roomContext.find('.childBedOptionContainer').empty();
    if (childBedOptionsData.choices.length>0) {

        jQuery.each(childBedOptionsData.choices, function(key,item){
			var newChoice = jQuery('#childBedChoiceOptionTemplate').clone();
			newChoice.prop('id',null);
            newChoice.data('index',key);
            newChoice.find('.childBedChoiceOptionText').html(item);

			if (isOnPageload) {
			//	console.log('selectedbedotion: ', getSMJSONProperty('selectedChildrenBedOption'), ' key, ' ,key);
				if (getSMJSONProperty('selectedChildrenBedOption') != null) {
					if (key == getSMJSONProperty('selectedChildrenBedOption')) {
						newChoice.find('.childBedChoiceOptionRadio').addClass('childBedChoiceOptionRadioSelected');
					}
				}
			}
            else if (index==key) {

                newChoice.find('.childBedChoiceOptionRadio').addClass('childBedChoiceOptionRadioSelected');
			}

            roomContext.find('.childBedOptionContainer').append(newChoice);

            newChoice.click(function (e) {
				var i = jQuery(this).data('index');
				//console.log(i);
                selectChildBedOption(roomContext,i,false);
            });
            newChoice.show();
        });


	}
	if (roomContext.find('.childBedOptionContainer').css('display') == 'none') {
		roomContext.find('.childBedSelectTooltip').hide();
	}
	else {
		roomContext.find('.childBedSelectTooltip').show();
	}

}

function getBedSelectionsAjax(trigger, roomContext, isOnPageload) {

	//console.log('getBedSelectionsAjax ', trigger, roomContext);

	// jos trigger ei ole lapsen ikä tai sänkyvalinta selecti, niin laita triggeriksi 0

	if (typeof roomContext != 'undefined') {
		jQuery('.smBookButton').removeClass('disabled')
		var adults = roomContext.find('.SMJSON-adultsAmount').val();
		var theme = jsConfig.theme == 'upper' ? jsConfig.theme : 'tower';
		var base = jsConfig.baseUrl;

		//base = "https://booking.gothiatowers.com";
		//base = "https://dev-gothia.hotelengine.eu";
		var kidsAmount = roomContext.find('.SMJSON-childrenAmount').val();
		var kidAges = [];
		var kidBeds = [];
		for (var i=1; i<=kidsAmount; i++) {
			kidAges.push(roomContext.find('.SMJSON-childAge[data-cb="'+i+'"]').val());
			var bedvalue = roomContext.find('.SMJSON-childBed[data-cb="'+i+'"]').data('key');
			if (bedvalue != 'NA') {
				kidBeds.push(bedvalue);
			}

		}
		kidAges = kidAges.join();

		/*
		kidBeds = kidBeds.join();
		if (jQuery.trim(kidBeds.length) > 0 ){
			// jos on sänkydataa
			kidBeds = '/'+kidBeds;
		}
		else {
			// jos ei ole sänkydataa niin triggeriä ei tarvita
			trigger = "";
		}

		if (trigger == 0) {
			trigger = "";
		}
		*/

		// Clear selections
        jQuery('#childBedChoiceOptionContainer').html();
		jQuery('.SMJSON-childBed').val('').data('key','');

		// empty the child bed selector
		roomContext.find('.childBedOptionContainer').empty();



		jQuery.ajax({
			url: base+'/services-custom/getChildSelections/'+theme+'/'+adults+'/'+kidAges,//+trigger,
			crossDomain: true
		}).done(function(data) {
			//console.log('data', data);
			if (data.error.length < 1) {

				roomContext.find('.bindChildBedError').hide().find('.childBedErrorText').html("");

				childBedOptionsData = data;

				if (isOnPageload) {
					getBedSelectionsFromJson();
				}
				else {
					selectChildBedOption(roomContext,0, false);
				}

			}
			else {
				roomContext.find('.bindChildBedError').show().find('.childBedErrorText').html(unescape(data.error)).show();
				//console.log('disableBookBtn');
				jQuery('.smBookButton').addClass('disabled');
			}
			// notes
			if (data.note.length > 0) {
				roomContext.find('.bindChildBedNote').show().find('.childBedNoteText').html(unescape(data.note)).show();
			}
			else {
				roomContext.find('.bindChildBedNote').hide().find('.childBedNoteText').html("");
			}

		});


	}

}

function validateChildAgeSelections() {
	//console.log('validateChildageSelections');
	var isValid = true;
	jQuery('.smBookButton').removeClass('disabled');

	jQuery('.SMJSON-roomDetails.enabled').each(function(){

		if (jQuery(this).find('.SMJSON-childrenAmount').val() > 0) {
			jQuery(this).find('.SMJSON-childAge:visible').each(function () {

				if (jQuery(this).val() == -1) {
					isValid = false;
				}
			});
			jQuery(this).find('.SMJSON-childBed:visible').each(function () {

				if (jQuery(this).val() == 'NA' || jQuery(this).val() == null) {
					isValid = false;
				}
			});
		}



	});

	return isValid;
}

function getBedSelectionsFromJson() {
	//console.log('getting beds from json');
	var rooms = parseInt(jQuery('#SMJSON-numberOfRooms').val());
	for (var i=0; i<rooms; i++) {
		var bedTexts=getSMJSONProperty('childrenBedTexts', i);
		var bedCodes=getSMJSONProperty('childrenBedCodes', i);
		if (typeof bedTexts != 'undefined') {
			var occnro = i+1;
			var room = jQuery('.smRoomDetails[occnro="'+occnro+'"]');
			for (var a=0; a<=bedTexts.length; a++) {
				var cb = a + 1;
				room.find('.SMJSON-childBed[data-cb="'+cb+'"]').val(bedTexts[a]).data('key', bedCodes[a]);
			}
			var roomContext = jQuery('.SMJSON-roomDetails[occnro="'+occnro+'"]');
		//	console.log('gotbedselectionsfromjson, getting selected options also');
			selectChildBedOption(roomContext,0, true);
		}
	}
}

function countRooms() {
	var rooms = parseInt(jQuery('#SMJSON-numberOfRooms').val());
	jQuery('.smRoomDetails').each(function(){
		if (parseInt(jQuery(this).attr('occnro')) <= rooms) {
			jQuery(this).addClass('enabled');
		}
		else {
			jQuery(this).removeClass('enabled');
		}
	});
}

function addRoom(maxRooms) {
	var rooms = parseInt(jQuery('#SMJSON-numberOfRooms').val());

	rooms++;
	if (rooms <= maxRooms) {
		jQuery('#SMJSON-numberOfRooms').val(rooms);
		jQuery('.smRoomDetails').each(function(){
			if (!jQuery(this).hasClass("enabled")) {
				jQuery(this).addClass('enabled');
				toggleRoomDetailsContent(jQuery(this).find('.bindToggleRoomDetailsContent'));
				return false;
			}
		});
		// show close -button in first room
		jQuery('.smRoomDetails[occnro="1"]').find('.bindRemoveRoom').show();
	}
	if (rooms == maxRooms) {
		jQuery('.bindSmAddRoom').hide();
	}
	countRooms();
	countOccupants();
	refreshRoomIndexesInOccupacy();
	jQuery.fancybox.reposition();

}

function checkIfChildAgesAreSelected (room, getBeds, isOnPageload) {

	if (typeof getBeds == 'undefined') {
		getBeds = false;
	}

	//console.log('check kid ages');

	let allSelected = true;
	room.find('.kidAgeWrap.enabled').each(function(){
		let kidAgeWrap = jQuery(this);
		let ageSelect = jQuery(this).find('.SMJSON-childAge');
		if (parseInt(ageSelect.val()) > -1) {
			// age selected
			kidAgeWrap.find('.smSpecifyAge').hide();
			kidAgeWrap.find('.smChildBedWrapper').show();
		}
		else {
			// age not selected
			allSelected = false;
			kidAgeWrap.find('.smSpecifyAge').show();
			kidAgeWrap.find('.smChildBedWrapper').hide();
		}
	});
	if (getBeds && allSelected) {
		getBedSelectionsAjax('', room, isOnPageload);
	}
}

function countOccupants (isOnPageload) {

	//console.log('countOccupants');
	var totalRooms = 0;
	var totalAdults = 0;
	var totalKids = 0;

	jQuery('.smRoomDetails.enabled').each(function (index) {

		totalRooms ++;

		var context = jQuery(this);
		var adults = parseInt(context.find('.SMJSON-adultsAmount').val());
		var kids = parseInt(context.find('.SMJSON-childrenAmount').val());

		totalAdults += adults;
		totalKids += kids;

		if (kids > 0) {
			context.find('.childAgesLabel').show();

			context.find('.kidAgeWrap').each(function(index){
				index = index+1;
				if (index <= kids) {
					jQuery(this).addClass('enabled');
				}
				else {
					jQuery(this).removeClass('enabled');
				}
			});
		}
		else {
			context.find('.childAgesLabel').hide();
			context.find('.kidAgeWrap').removeClass('enabled');
		}



		/* context.find('.SMJSON-childAge').each(function(){
			if (jQuery(this).data('cb') <= kids) {
				jQuery(this).parents('.kidAgeWrap').addClass('enabled');

				if (jQuery(this).val() == -1 || jQuery(this).val() == 'NA') {
					jQuery(this).parents('.ChildAgesIncludingLabel').find('.SMJSON-childBed[data-cb="'+jQuery(this).data('cb')+'"]').parents('.smChildBedWrapper').siblings('.smSpecifyAge').show();
				}
				else {
					jQuery(this).parents('.ChildAgesIncludingLabel').find('.SMJSON-childBed[data-cb="'+jQuery(this).data('cb')+'"]').parents('.smChildBedWrapper').hide();
				}
			}
			else {
				jQuery(this).parents('.kidAgeWrap').removeClass('enabled');
				var childBed = jQuery(this).parents('.ChildAgesIncludingLabel').find('.SMJSON-childBed[data-cb="'+jQuery(this).data('cb')+'"]');
				childBed.parents('.smChildBedWrapper').hide();
				childBed.parents('.smChildBedWrapper').siblings('.smSpecifyAge').show();

			}
		}); */


		// second parameter makes bed ajax.
		checkIfChildAgesAreSelected (context, true, isOnPageload);



		var header = context.find('.occRoomHeader');
		header.find('.smRoomOccupantsAdults').text(adults);
		header.find('.smRoomOccupantsChildren').text(kids);

		// set labels
		if (totalRooms > 1) {
			header.find('.smOccLabelRoom').hide();
			header.find('.smOccLabelRooms').show();
		}
		else {
			header.find('.smOccLabelRoom').show();
			header.find('.smOccLabelRooms').hide();
		}

		if (adults > 1) {
			header.find('.smOccLabelAdult').hide();
			header.find('.smOccLabelAdults').show();
		}
		else {
			header.find('.smOccLabelAdult').show();
			header.find('.smOccLabelAdults').hide();
		}

		if (kids != 1) {
			header.find('.smOccLabelChild').hide();
			header.find('.smOccLabelChildren').show();
		}
		else {
			header.find('.smOccLabelChild').show();
			header.find('.smOccLabelChildren').hide();
		}


	});

	jQuery('.smOccupancyTotalRooms').text(totalRooms);
	jQuery('.smOccupancyTotalAdults').text(totalAdults);
	jQuery('.smOccupancyTotalChildren').text(totalKids);

}

function removeRoom(context){

	var roomDetailsCount = 0;
	jQuery('.smRoomDetails').each(function(){
		if (jQuery(this).hasClass("enabled")) {
			roomDetailsCount ++;
		}
	});
	//console.log('rooms enabled:' +roomDetailsCount);

	jQuery('#SMJSON-numberOfRooms').val(roomDetailsCount-1);

	if (roomDetailsCount > 1) {
		context.parents('.smRoomDetails').removeClass('enabled');
	}
	jQuery('.bindSmAddRoom').show();

	refreshRoomIndexesInOccupacy();
	// hide close -button if only one room
	if (jQuery('#SMJSON-numberOfRooms').val() == 1) {
		jQuery('.smRoomDetails[occnro="1"]').find('.bindRemoveRoom').hide();
	}
	else {
		jQuery('.smRoomDetails[occnro="1"]').find('.bindRemoveRoom').show();
	}

	countOccupants();


};

function refreshRoomIndexesInOccupacy() {
	var indexLoop = 1;
	jQuery('.smRoomDetails').each(function(){
		if (jQuery(this).hasClass('enabled')) {
			jQuery(this).find('.room-index').text(indexLoop);
			indexLoop++;
		}
	});

}

function quickSelectOccupants(element) {
	var rooms = element.data('rooms');
	var adults = element.data('adults');
	var kids = element.data('kids');

	jQuery('.smRoomDetails').each(function(){
		if (jQuery(this).attr('occnro') <= rooms) {
			jQuery(this).addClass('enabled');
			jQuery(this).find('.SMJSON-adultsAmount').val(adults);
			jQuery(this).find('.SMJSON-childrenAmount').val(kids);
		}
		else {
			jQuery(this).removeClass('enabled');
		}
	});
	jQuery('#SMJSON-numberOfRooms').val(rooms);

	countOccupants();
}

function toggleRoomDetailsContent(room) {
	room.parents('.smRoomDetails').toggleClass('open');
	jQuery.fancybox.reposition();
}

var clearCode = function() {
	jQuery('#SMJSON-combinedCode').val('');
	validateSearchMask(0, false);
}

function setCode(makeSearch) {
	var code = jQuery('#SMJSON-combinedCode').val();

	if (typeof code != 'undefined' && code.length > 0) {
		jQuery('.bindSmCodeIsSet').show();
		jQuery('.bindCodeIsNotSet').hide();
		jQuery('.bindSmCodeText').text(code);
		_gaSendSearchMaskCode(code);
		if (makeSearch) {
			setTimeout(function(){validateSearchMask(0, false);}, 300);
		}

	}
	else {
		jQuery('.bindSmCodeIsSet').hide();
		jQuery('.bindCodeIsNotSet').show();

	}
}


function slideSearchMaskInfos()
{
	jQuery('.smInputInfo').show('scale').delay(2000).hide('slow');

	jQuery('.smShowOnlyOnce').show('scale').delay(4500).hide('slow');

}




// When search mask is submitted, check that count from different child buckets
// mathches that of the main child count select.
function validateSearchMask(searchtype, triggerInFancybox) {


	var bedsettingsError = 'Vänligen välj sängtyper.';
	if (jsConfig.language == 'e') {
			bedsettingsError = 'Please select correct bed settings.';
	}

	if (jQuery('.smBookButton').hasClass('disabled')) {
		if (jQuery('.childBedErrorText').text().length < 1) {
			jQuery('.bindChildBedError').show().find('.childBedErrorText').html(bedsettingsError);
		}

		return false;
	}



	if (validateChildAgeSelections() == false) {
		jQuery('.bindChildBedError').show().find('.childBedErrorText').html(bedsettingsError);
		return false;
	}
	buildSMJSON(triggerInFancybox);


	/* let make a function to check if POST can be made*/
	if (1==1)
	{
		/* If clicking the avalability ribbon*/
		if (exists('#currentCurrency'))
		{
			if (jQuery('#currentCurrency').val()=='POINTS' && (searchtype!=0 && searchtype!=5))
			{
				searchtype = 5;
			};
		}


		var nroOfRooms = parseInt(jQuery("#lbNroOfRooms").val());
		var nroOfAdults = parseInt(jQuery("#lbNroOfAdults").val());

		var error = '';
		var isValid = true;

		/*if (nroOfRooms<1 || nroOfRooms=='NA' || isNaN(nroOfRooms))
		{
			alert(jsConfig.lang.numberOfRoomsInvalid);
			isValid = false;
			return false;
		}*/

		var shakeElements = [];

		// check the child ages and bed types
		var validKids = true;
		var hasKids = false;
		jQuery('.smChildAge').each(function()
		{
			hasKids = true;
			if (parseInt(jQuery(this).val())==-1)
			{
				validKids = false;
				debug('Age'+jQuery(this).val());
				shakeElements.push(this);
			}
		});

		if (hasKids && validKids)
		{
			// if the elements not loaded yet but kids selected
			if (!exists('.smChildBed'))
			{
				validKids = false;
			}
			jQuery('.smChildBed').each(function()
			{
				if (jQuery(this).val()=='NA')
				{
					validKids = false;
					debug('Bed'+jQuery(this).val());
					shakeElements.push(this);
				}
			});
		}


		jQuery('.smWaitingForChildselections').each(function()
		{
			debug('Wait'+jQuery(this).val());
			validKids = false;
			shakeElements.push(this);
		});

		jQuery('.smErrorid').each(function()
		{
			debug('Smerror'+jQuery(this).val());
			shakeElements.push(this);
		});


		if (!validKids)
		{
			isValid = false;
			smError(jsConfig.lang.JS_SM_CHECKCHILDREN);
		}

		if(isValid) {

			CalendarSetup.calendarCalled = 0; // so that next call will trigger the calendars
			createRibbon = true; // as we want to trig availability to make new ribbon
			selectedRoomIndex = 0;

			jQuery('#ssContainer').hide('slide');

			if (jQuery('body').hasClass('inBookingEngine'))
                app_postback('appcontrol_ucSearchMask','btnSearchAvailability', 'server:btnGetAvailabilitySetSearchTypeAndSearch_OnClick', searchtype,'appcontrol_ucAvailability');


			else {
				document.getElementById('appForm').submit();
			}

		}

		jQuery.each(shakeElements,function(index, value){
			jQuery(value).effect( "shake", {distance: 5});
		});
	}

}

function smError(error)
{
	jQuery('#smError').html(error);
}



function makeSearch(parameters)
{

	if (jQuery('body').hasClass('inBookingEngine')) {
		app_postback('appcontrol_ucSearchMask','btnSearchAvailability', 'server:btnGetAvailabilityAndClear_Clicked',parameters); //
	}
	else {
		document.getElementById('appForm').submit();
	}

}


function makeSearchAfterLogin(companyId) {

	if (companyId) {
        jQuery('#SMJSON-combinedCode').val(companyId);
	}


    setTimeout(validateSearchMask,500);
}

function logout() {
    jQuery('#SMJSON-combinedCode').val('');
    buildSMJSON();
	// documentLocationLogout();
	app_postback('appcontrol_ucLoginHome','btnLogout', 'server:logout_OnClick', '');
}

function showOccupancyPopup() {
	if (isMobile()) {

		jQuery.fancybox.open(jQuery('#occupancyPopup'),{
			'padding': 0,
			'width': '100%',
			'height': '100%',
			'topRatio': 0,
			'leftRatio': 0,
			'margin': 0,
			'autoSize': false,
			'fitToView': true,
			'wrapCSS': 'smFancybox'
		});

	}
	else {
		jQuery.fancybox.open(jQuery('#occupancyPopup'),{
			'padding': 0,
			'minWidth': 500,
			'maxWidth': 500,
			'fitToView': true,
			'wrapCSS': 'smFancybox'
		});
	}
}
function showCodeInput() {

	if (isMobile()) {
		jQuery.fancybox.open(jQuery('#smCodePopup'),{
			'padding': 0,
			'width': '100%',
			'height': '100%',
			'topRatio': 0,
			'leftRatio': 0,
			'margin': 0,
			'autoSize': false,
			'fitToView': true,
			'wrapCSS': 'smFancybox'
		});
	}

	else {

		jQuery.fancybox.open(jQuery('#smCodePopup'),{
			'padding': 0,
			'minWidth': 500,
			'maxWidth': 500,
			'wrapCSS': 'smFancybox'
		});
	}

}

function populateSmSummary () {

	// this is used to populate the searchmask summary box. Also same funcition populates the shopcartsummary quick details in profile page

	if (!SMJSONexists()) {
		jQuery('.smSummary').hide();
		jQuery('.smInputs').show();
		return false;
	}

	var totalRooms = getSmCookie().length;
	var totalAdults = 0;
	var totalKids = 0;
	var arrivalDate = getSMJSONProperty('arrivalDate', 0);
	var departureDate = getSMJSONProperty('departureDate', 0);
	var combinedCode = getSMJSONProperty('combinedCode', 0);

	if (typeof combinedCode == 'undefined') {
		combinedCode = "";
	}

	for (var i=0; i<totalRooms; i++) {
		totalAdults += parseInt(getSMJSONProperty('adultsPerRoom', i));
		totalKids += parseInt(getSMJSONProperty('childrenPerRoom', i));
	}

	jQuery('.bindSmSummaryDates').text(arrivalDate + " - " + departureDate);
	jQuery('.bindSmSummaryRooms').text(totalRooms);
	jQuery('.bindSmSummaryAdults').text(totalAdults);
	jQuery('.bindSmSummaryChildren').text(totalKids);
	jQuery('.bindSmSummaryCode').text(combinedCode);


	// set labels
	if (totalRooms > 1) {
		jQuery('.smSummaryLabelRoom').hide();
		jQuery('.smSummaryLabelRooms').show();
	}
	else {
		jQuery('.smSummaryLabelRoom').show();
		jQuery('.smSummaryLabelRooms').hide();
	}

	if (totalAdults > 1) {
		jQuery('.smSummaryLabelAdult').hide();
		jQuery('.smSummaryLabelAdults').show();
	}
	else {
		jQuery('.smSummaryLabelAdult').show();
		jQuery('.smSummaryLabelAdults').hide();
	}

	if (totalKids < 1) {
		jQuery('.smSummaryKidsComma').hide();
		jQuery('.smSummaryLabelChild').hide();
		jQuery('.bindSmSummaryChildren').hide();
	}
	else {
		if (totalKids != 1) {
			jQuery('.smSummaryLabelChild').hide();
			jQuery('.smSummaryLabelChildren').show();
		}
		else {
			jQuery('.smSummaryLabelChild').show();
			jQuery('.smSummaryLabelChildren').hide();
		}
	}
	if (combinedCode.length < 1) {
		jQuery('.smSummaryCodeComma').hide();
	}




}

function checkLoginAndEnrollFieldsOnOpen() {
    console.log('Login and enroll Opened');
    jQuery('.prLoginDetailsFieldsContainer').show();
    jQuery('.popupRegisterProfile').find('.isRequiredRegister').addClass('isRequired');
    jQuery('.prEnrollLabelOff').hide();
    jQuery('.prEnrollLabelOn').show();
}

function checkLoginAndEnrollFieldsOnClose() {
    console.log('Login and enroll closed');
    jQuery('.popupRegisterProfile').find('.isRequiredRegister').removeClass('isRequired');
    jQuery('.prLoginDetailsFieldsContainer').hide();
    jQuery('.prLoginCrediental').val('');
    jQuery('.prEnrollLabelOn').hide();
    jQuery('.prEnrollLabelOff').show();
}

function bindLoginButtons()
{
	//check on pageload


	/*
	if (jQuery('#becomemember').prop('checked') || jQuery('#memberlogin').prop('checked')) {

	} else {

	}
	*/

	// bind change action
	jQuery('.bindPrCreateProfile').unbind().click(function() {
			jQuery('.prLoginDetailsFieldsContainer').slideDown();
			jQuery('.prContainer').find('.isRequiredRegister').addClass('isRequired');
			jQuery('.prEnrollLabelOff').hide();
			jQuery('.prEnrollLabelOn').show();
	});

	jQuery('.bindPrDontCreateProfile').unbind().click(function(){
			jQuery('.prContainer').find('.isRequiredRegister').removeClass('isRequired');
			jQuery('.prLoginDetailsFieldsContainer').slideUp();
			jQuery('.prLoginCrediental').val('');
			jQuery('.prEnrollLabelOn').hide();
			jQuery('.prEnrollLabelOff').show();
	});

    /*
      jQuery('#userName').unbind().keyup(function(){
          jQuery('#email').val(jQuery(this).val());
      });

          jQuery('.bindPreFillFromBooker').unbind().click(function(){

              if (exists('.fieldNotEditable')) {
                  jQuery('#firstName').val(jQuery('#bookerfirstName').html());
                  jQuery('#lastName').val(jQuery('#bookerlastName').html());
                  jQuery('#email').val(jQuery('#bookeremail').html());
                  jQuery('#mobile').val(jQuery('#bookermobile').html());
              } else {
                  jQuery('#firstName').val(jQuery('#bookerfirstName').val());
                  jQuery('#lastName').val(jQuery('#bookerlastName').val());
                  jQuery('#email').val(jQuery('#bookeremail').val());
                  jQuery('#mobile').val(jQuery('#bookermobile').val());
              }
          });
      */

	/*
	jQuery('#openLoginDialog').unbind().click(function()
	{
		jQuery('#appcontrol_ucSearchMask_ucLogin').dialog({modal: true, width: 350,resizable: false});
	});
	*/

	jQuery('.bindLoginButton').unbind().click(function(){
		_gaSendLoginEvent();
		app_postback_ajax('appcontrol_ucLoginHome','btnLogin', 'server-ajax: login_OnClick', '','')
	});


	jQuery('#logoutButton').unbind().click(function()
	{
		app_postback('appcontrol_ucSearchMask_ucLogin','btnLogout', 'server:logout', '');

	});


	/* if the login fields ar already visible do not show the hiding option*/
	if (jQuery('.prLoginDetailsFieldsContainer').is(':visible'))
	{
		jQuery('.prCreateProfile').hide();
	}

	if (exists('.prLoginForceEnroll'))
	{
		//jQuery('.isRequiredLogin').addClass('isRequired');
	}


	/**
	 * handles create login radiobutton
	*/

	jQuery('.bindCreateLogin').unbind().click(function() {
		var value = jQuery(this).val();
		app_postback_ajax('appcontrol_ucRegisterProfile_ucGuestProfileManage','btnChooseAction', 'server-ajax: btnChooseAction_onClick', value);
	});


}

function saveProfile(fullId,classSelector)
{
	if (!isValidProfile(fullId,classSelector))
	{
		alert(jsConfig.lang.JS_PR_CHECKFIELDS);
	}
	else {

		app_postback_ajax(fullId, 'btnSaveChanges', 'server-ajax: btnSaveChanges_OnClick', '', '');
	}
}


function createAdditionalProfile(fullId)
{
	app_postback_ajax(fullId,'btnCreateAdditionalProfile', 'server-ajax: btnCreateAdditionalProfile_OnClick', '');
}

function saveAdditionalProfile(fullId)
{
	if (!isValidProfile(fullId))
	{
		alert(jsConfig.lang.JS_PR_CHECKFIELDS);
	}
	else
	{
		app_postback(fullId,'btnSaveAdditionalProfile', 'server: btnSaveAdditionalProfile_OnClick', '');
	}
}



function cancelEdit(fullId)
{
	app_postback_ajax(fullId,'btnCancelProfileValues', 'server-ajax: btnCancelProfileValues_OnClick', '','');
}

/**
 * Opens the edit dialog for
 *
 * @param profileId
 */
function editGuestProfile(fullId,profileId)
{
	app_postback_ajax(fullId,'btnEditProfileValues', 'server-ajax: btnEditProfileValues_OnClick', profileId,'');
}


/**
 * Removes the profile
 *
 * @param profileId
 */
function removeGuestProfile(fullId,profileId)
{
	if (confirm(trans('sureWantToRemoveProfile')))
	{
		app_postback(fullId,'btnEditProfileValues', 'server: btnEditProfileValues_Remove_OnClick', profileId,'');
	}
}



function registerUser(fullId) {
	// remove isRequiredProfile from profile
	jQuery('.notPopupRegister').find('.isRequiredRegister').removeClass('isRequiredRegister');


    var memberNewsLetterOptIn = jQuery('#memberNewsLetterOptIn').is(":checked");
/*
    if (memberNewsLetterOptIn) {
        alert('OptiIN'+memberNewsLetterOptIn);
	}

	!isValidProfile(fullId, '.isRequiredRegister')
*/
    var isValid = _validateFormFields('button','validationNotValid','validationIsValid','.isRequiredRegister');

    if (!isValid) {
		//alert(jsConfig.lang.JS_PR_CHECKFIELDS);
	} else {
		_gaSendRegisterEvent();


		app_postback_ajax('appcontrol_ucRegisterProfile_ucGuestProfileManage','btnRegisterProfile', 'server-ajax: btnRegisterProfile_OnClick', '','')
	}
}





jQuery(document).ready(function()
{
	/* SMJSON TRIGGERS*/
	loadSMJSONfromCookie();
	buildShoppingCartfromCookie();
	initBootstrapCals();
	triggerBedSelectionsOnload();
	jsonSearchmaskFunctions();


	bindMobileMenu();
	bindLoginPopup();

	bindSearchMaskButtons();
	bindLoginButtons();

	bindValidationEvents();
	loadAjaxProxyContent();


	/* on homepage lways show */
	jQuery('.smSummary').hide();
	jQuery('.smInputs').show();

	console.log('Open SM');

});

jQuery(document).ajaxComplete(function()
{
    jQuery('.smSummary').hide();
    jQuery('.smInputs').show();


});

/*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */
(function(r,G,f,v){var J=f("html"),n=f(r),p=f(G),b=f.fancybox=function(){b.open.apply(this,arguments)},I=navigator.userAgent.match(/msie/i),B=null,s=G.createTouch!==v,t=function(a){return a&&a.hasOwnProperty&&a instanceof f},q=function(a){return a&&"string"===f.type(a)},E=function(a){return q(a)&&0<a.indexOf("%")},l=function(a,d){var e=parseInt(a,10)||0;d&&E(a)&&(e*=b.getViewport()[d]/100);return Math.ceil(e)},w=function(a,b){return l(a,b)+"px"};f.extend(b,{version:"2.1.5",defaults:{padding:15,margin:20,
width:800,height:600,minWidth:100,minHeight:100,maxWidth:9999,maxHeight:9999,pixelRatio:1,autoSize:!0,autoHeight:!1,autoWidth:!1,autoResize:!0,autoCenter:!s,fitToView:!0,aspectRatio:!1,topRatio:0.5,leftRatio:0.5,scrolling:"auto",wrapCSS:"",arrows:!0,closeBtn:!0,closeClick:!1,nextClick:!1,mouseWheel:!0,autoPlay:!1,playSpeed:3E3,preload:3,modal:!1,loop:!0,ajax:{dataType:"html",headers:{"X-fancyBox":!0}},iframe:{scrolling:"auto",preload:!0},swf:{wmode:"transparent",allowfullscreen:"true",allowscriptaccess:"always"},
keys:{next:{13:"left",34:"up",39:"left",40:"up"},prev:{8:"right",33:"down",37:"right",38:"down"},close:[27],play:[32],toggle:[70]},direction:{next:"left",prev:"right"},scrollOutside:!0,index:0,type:null,href:null,content:null,title:null,tpl:{wrap:'<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',image:'<img class="fancybox-image" src="{href}" alt="" />',iframe:'<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen'+
(I?' allowtransparency="true"':"")+"></iframe>",error:'<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',closeBtn:'<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>',next:'<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',prev:'<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>'},openEffect:"fade",openSpeed:250,openEasing:"swing",openOpacity:!0,
openMethod:"zoomIn",closeEffect:"fade",closeSpeed:250,closeEasing:"swing",closeOpacity:!0,closeMethod:"zoomOut",nextEffect:"elastic",nextSpeed:250,nextEasing:"swing",nextMethod:"changeIn",prevEffect:"elastic",prevSpeed:250,prevEasing:"swing",prevMethod:"changeOut",helpers:{overlay:!0,title:!0},onCancel:f.noop,beforeLoad:f.noop,afterLoad:f.noop,beforeShow:f.noop,afterShow:f.noop,beforeChange:f.noop,beforeClose:f.noop,afterClose:f.noop},group:{},opts:{},previous:null,coming:null,current:null,isActive:!1,
isOpen:!1,isOpened:!1,wrap:null,skin:null,outer:null,inner:null,player:{timer:null,isActive:!1},ajaxLoad:null,imgPreload:null,transitions:{},helpers:{},open:function(a,d){if(a&&(f.isPlainObject(d)||(d={}),!1!==b.close(!0)))return f.isArray(a)||(a=t(a)?f(a).get():[a]),f.each(a,function(e,c){var k={},g,h,j,m,l;"object"===f.type(c)&&(c.nodeType&&(c=f(c)),t(c)?(k={href:c.data("fancybox-href")||c.attr("href"),title:c.data("fancybox-title")||c.attr("title"),isDom:!0,element:c},f.metadata&&f.extend(!0,k,
c.metadata())):k=c);g=d.href||k.href||(q(c)?c:null);h=d.title!==v?d.title:k.title||"";m=(j=d.content||k.content)?"html":d.type||k.type;!m&&k.isDom&&(m=c.data("fancybox-type"),m||(m=(m=c.prop("class").match(/fancybox\.(\w+)/))?m[1]:null));q(g)&&(m||(b.isImage(g)?m="image":b.isSWF(g)?m="swf":"#"===g.charAt(0)?m="inline":q(c)&&(m="html",j=c)),"ajax"===m&&(l=g.split(/\s+/,2),g=l.shift(),l=l.shift()));j||("inline"===m?g?j=f(q(g)?g.replace(/.*(?=#[^\s]+$)/,""):g):k.isDom&&(j=c):"html"===m?j=g:!m&&(!g&&
k.isDom)&&(m="inline",j=c));f.extend(k,{href:g,type:m,content:j,title:h,selector:l});a[e]=k}),b.opts=f.extend(!0,{},b.defaults,d),d.keys!==v&&(b.opts.keys=d.keys?f.extend({},b.defaults.keys,d.keys):!1),b.group=a,b._start(b.opts.index)},cancel:function(){var a=b.coming;a&&!1!==b.trigger("onCancel")&&(b.hideLoading(),b.ajaxLoad&&b.ajaxLoad.abort(),b.ajaxLoad=null,b.imgPreload&&(b.imgPreload.onload=b.imgPreload.onerror=null),a.wrap&&a.wrap.stop(!0,!0).trigger("onReset").remove(),b.coming=null,b.current||
b._afterZoomOut(a))},close:function(a){b.cancel();!1!==b.trigger("beforeClose")&&(b.unbindEvents(),b.isActive&&(!b.isOpen||!0===a?(f(".fancybox-wrap").stop(!0).trigger("onReset").remove(),b._afterZoomOut()):(b.isOpen=b.isOpened=!1,b.isClosing=!0,f(".fancybox-item, .fancybox-nav").remove(),b.wrap.stop(!0,!0).removeClass("fancybox-opened"),b.transitions[b.current.closeMethod]())))},play:function(a){var d=function(){clearTimeout(b.player.timer)},e=function(){d();b.current&&b.player.isActive&&(b.player.timer=
setTimeout(b.next,b.current.playSpeed))},c=function(){d();p.unbind(".player");b.player.isActive=!1;b.trigger("onPlayEnd")};if(!0===a||!b.player.isActive&&!1!==a){if(b.current&&(b.current.loop||b.current.index<b.group.length-1))b.player.isActive=!0,p.bind({"onCancel.player beforeClose.player":c,"onUpdate.player":e,"beforeLoad.player":d}),e(),b.trigger("onPlayStart")}else c()},next:function(a){var d=b.current;d&&(q(a)||(a=d.direction.next),b.jumpto(d.index+1,a,"next"))},prev:function(a){var d=b.current;
d&&(q(a)||(a=d.direction.prev),b.jumpto(d.index-1,a,"prev"))},jumpto:function(a,d,e){var c=b.current;c&&(a=l(a),b.direction=d||c.direction[a>=c.index?"next":"prev"],b.router=e||"jumpto",c.loop&&(0>a&&(a=c.group.length+a%c.group.length),a%=c.group.length),c.group[a]!==v&&(b.cancel(),b._start(a)))},reposition:function(a,d){var e=b.current,c=e?e.wrap:null,k;c&&(k=b._getPosition(d),a&&"scroll"===a.type?(delete k.position,c.stop(!0,!0).animate(k,200)):(c.css(k),e.pos=f.extend({},e.dim,k)))},update:function(a){var d=
a&&a.type,e=!d||"orientationchange"===d;e&&(clearTimeout(B),B=null);b.isOpen&&!B&&(B=setTimeout(function(){var c=b.current;c&&!b.isClosing&&(b.wrap.removeClass("fancybox-tmp"),(e||"load"===d||"resize"===d&&c.autoResize)&&b._setDimension(),"scroll"===d&&c.canShrink||b.reposition(a),b.trigger("onUpdate"),B=null)},e&&!s?0:300))},toggle:function(a){b.isOpen&&(b.current.fitToView="boolean"===f.type(a)?a:!b.current.fitToView,s&&(b.wrap.removeAttr("style").addClass("fancybox-tmp"),b.trigger("onUpdate")),
b.update())},hideLoading:function(){p.unbind(".loading");f("#fancybox-loading").remove()},showLoading:function(){var a,d;b.hideLoading();a=f('<div id="fancybox-loading"><div></div></div>').click(b.cancel).appendTo("body");p.bind("keydown.loading",function(a){if(27===(a.which||a.keyCode))a.preventDefault(),b.cancel()});b.defaults.fixed||(d=b.getViewport(),a.css({position:"absolute",top:0.5*d.h+d.y,left:0.5*d.w+d.x}))},getViewport:function(){var a=b.current&&b.current.locked||!1,d={x:n.scrollLeft(),
y:n.scrollTop()};a?(d.w=a[0].clientWidth,d.h=a[0].clientHeight):(d.w=s&&r.innerWidth?r.innerWidth:n.width(),d.h=s&&r.innerHeight?r.innerHeight:n.height());return d},unbindEvents:function(){b.wrap&&t(b.wrap)&&b.wrap.unbind(".fb");p.unbind(".fb");n.unbind(".fb")},bindEvents:function(){var a=b.current,d;a&&(n.bind("orientationchange.fb"+(s?"":" resize.fb")+(a.autoCenter&&!a.locked?" scroll.fb":""),b.update),(d=a.keys)&&p.bind("keydown.fb",function(e){var c=e.which||e.keyCode,k=e.target||e.srcElement;
if(27===c&&b.coming)return!1;!e.ctrlKey&&(!e.altKey&&!e.shiftKey&&!e.metaKey&&(!k||!k.type&&!f(k).is("[contenteditable]")))&&f.each(d,function(d,k){if(1<a.group.length&&k[c]!==v)return b[d](k[c]),e.preventDefault(),!1;if(-1<f.inArray(c,k))return b[d](),e.preventDefault(),!1})}),f.fn.mousewheel&&a.mouseWheel&&b.wrap.bind("mousewheel.fb",function(d,c,k,g){for(var h=f(d.target||null),j=!1;h.length&&!j&&!h.is(".fancybox-skin")&&!h.is(".fancybox-wrap");)j=h[0]&&!(h[0].style.overflow&&"hidden"===h[0].style.overflow)&&
(h[0].clientWidth&&h[0].scrollWidth>h[0].clientWidth||h[0].clientHeight&&h[0].scrollHeight>h[0].clientHeight),h=f(h).parent();if(0!==c&&!j&&1<b.group.length&&!a.canShrink){if(0<g||0<k)b.prev(0<g?"down":"left");else if(0>g||0>k)b.next(0>g?"up":"right");d.preventDefault()}}))},trigger:function(a,d){var e,c=d||b.coming||b.current;if(c){f.isFunction(c[a])&&(e=c[a].apply(c,Array.prototype.slice.call(arguments,1)));if(!1===e)return!1;c.helpers&&f.each(c.helpers,function(d,e){if(e&&b.helpers[d]&&f.isFunction(b.helpers[d][a]))b.helpers[d][a](f.extend(!0,
{},b.helpers[d].defaults,e),c)});p.trigger(a)}},isImage:function(a){return q(a)&&a.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i)},isSWF:function(a){return q(a)&&a.match(/\.(swf)((\?|#).*)?$/i)},_start:function(a){var d={},e,c;a=l(a);e=b.group[a]||null;if(!e)return!1;d=f.extend(!0,{},b.opts,e);e=d.margin;c=d.padding;"number"===f.type(e)&&(d.margin=[e,e,e,e]);"number"===f.type(c)&&(d.padding=[c,c,c,c]);d.modal&&f.extend(!0,d,{closeBtn:!1,closeClick:!1,nextClick:!1,arrows:!1,
mouseWheel:!1,keys:null,helpers:{overlay:{closeClick:!1}}});d.autoSize&&(d.autoWidth=d.autoHeight=!0);"auto"===d.width&&(d.autoWidth=!0);"auto"===d.height&&(d.autoHeight=!0);d.group=b.group;d.index=a;b.coming=d;if(!1===b.trigger("beforeLoad"))b.coming=null;else{c=d.type;e=d.href;if(!c)return b.coming=null,b.current&&b.router&&"jumpto"!==b.router?(b.current.index=a,b[b.router](b.direction)):!1;b.isActive=!0;if("image"===c||"swf"===c)d.autoHeight=d.autoWidth=!1,d.scrolling="visible";"image"===c&&(d.aspectRatio=
!0);"iframe"===c&&s&&(d.scrolling="scroll");d.wrap=f(d.tpl.wrap).addClass("fancybox-"+(s?"mobile":"desktop")+" fancybox-type-"+c+" fancybox-tmp "+d.wrapCSS).appendTo(d.parent||"body");f.extend(d,{skin:f(".fancybox-skin",d.wrap),outer:f(".fancybox-outer",d.wrap),inner:f(".fancybox-inner",d.wrap)});f.each(["Top","Right","Bottom","Left"],function(a,b){d.skin.css("padding"+b,w(d.padding[a]))});b.trigger("onReady");if("inline"===c||"html"===c){if(!d.content||!d.content.length)return b._error("content")}else if(!e)return b._error("href");
"image"===c?b._loadImage():"ajax"===c?b._loadAjax():"iframe"===c?b._loadIframe():b._afterLoad()}},_error:function(a){f.extend(b.coming,{type:"html",autoWidth:!0,autoHeight:!0,minWidth:0,minHeight:0,scrolling:"no",hasError:a,content:b.coming.tpl.error});b._afterLoad()},_loadImage:function(){var a=b.imgPreload=new Image;a.onload=function(){this.onload=this.onerror=null;b.coming.width=this.width/b.opts.pixelRatio;b.coming.height=this.height/b.opts.pixelRatio;b._afterLoad()};a.onerror=function(){this.onload=
this.onerror=null;b._error("image")};a.src=b.coming.href;!0!==a.complete&&b.showLoading()},_loadAjax:function(){var a=b.coming;b.showLoading();b.ajaxLoad=f.ajax(f.extend({},a.ajax,{url:a.href,error:function(a,e){b.coming&&"abort"!==e?b._error("ajax",a):b.hideLoading()},success:function(d,e){"success"===e&&(a.content=d,b._afterLoad())}}))},_loadIframe:function(){var a=b.coming,d=f(a.tpl.iframe.replace(/\{rnd\}/g,(new Date).getTime())).attr("scrolling",s?"auto":a.iframe.scrolling).attr("src",a.href);
f(a.wrap).bind("onReset",function(){try{f(this).find("iframe").hide().attr("src","//about:blank").end().empty()}catch(a){}});a.iframe.preload&&(b.showLoading(),d.one("load",function(){f(this).data("ready",1);s||f(this).bind("load.fb",b.update);f(this).parents(".fancybox-wrap").width("100%").removeClass("fancybox-tmp").show();b._afterLoad()}));a.content=d.appendTo(a.inner);a.iframe.preload||b._afterLoad()},_preloadImages:function(){var a=b.group,d=b.current,e=a.length,c=d.preload?Math.min(d.preload,
e-1):0,f,g;for(g=1;g<=c;g+=1)f=a[(d.index+g)%e],"image"===f.type&&f.href&&((new Image).src=f.href)},_afterLoad:function(){var a=b.coming,d=b.current,e,c,k,g,h;b.hideLoading();if(a&&!1!==b.isActive)if(!1===b.trigger("afterLoad",a,d))a.wrap.stop(!0).trigger("onReset").remove(),b.coming=null;else{d&&(b.trigger("beforeChange",d),d.wrap.stop(!0).removeClass("fancybox-opened").find(".fancybox-item, .fancybox-nav").remove());b.unbindEvents();e=a.content;c=a.type;k=a.scrolling;f.extend(b,{wrap:a.wrap,skin:a.skin,
outer:a.outer,inner:a.inner,current:a,previous:d});g=a.href;switch(c){case "inline":case "ajax":case "html":a.selector?e=f("<div>").html(e).find(a.selector):t(e)&&(e.data("fancybox-placeholder")||e.data("fancybox-placeholder",f('<div class="fancybox-placeholder"></div>').insertAfter(e).hide()),e=e.show().detach(),a.wrap.bind("onReset",function(){f(this).find(e).length&&e.hide().replaceAll(e.data("fancybox-placeholder")).data("fancybox-placeholder",!1)}));break;case "image":e=a.tpl.image.replace("{href}",
g);break;case "swf":e='<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="'+g+'"></param>',h="",f.each(a.swf,function(a,b){e+='<param name="'+a+'" value="'+b+'"></param>';h+=" "+a+'="'+b+'"'}),e+='<embed src="'+g+'" type="application/x-shockwave-flash" width="100%" height="100%"'+h+"></embed></object>"}(!t(e)||!e.parent().is(a.inner))&&a.inner.append(e);b.trigger("beforeShow");a.inner.css("overflow","yes"===k?"scroll":
"no"===k?"hidden":k);b._setDimension();b.reposition();b.isOpen=!1;b.coming=null;b.bindEvents();if(b.isOpened){if(d.prevMethod)b.transitions[d.prevMethod]()}else f(".fancybox-wrap").not(a.wrap).stop(!0).trigger("onReset").remove();b.transitions[b.isOpened?a.nextMethod:a.openMethod]();b._preloadImages()}},_setDimension:function(){var a=b.getViewport(),d=0,e=!1,c=!1,e=b.wrap,k=b.skin,g=b.inner,h=b.current,c=h.width,j=h.height,m=h.minWidth,u=h.minHeight,n=h.maxWidth,p=h.maxHeight,s=h.scrolling,q=h.scrollOutside?
h.scrollbarWidth:0,x=h.margin,y=l(x[1]+x[3]),r=l(x[0]+x[2]),v,z,t,C,A,F,B,D,H;e.add(k).add(g).width("auto").height("auto").removeClass("fancybox-tmp");x=l(k.outerWidth(!0)-k.width());v=l(k.outerHeight(!0)-k.height());z=y+x;t=r+v;C=E(c)?(a.w-z)*l(c)/100:c;A=E(j)?(a.h-t)*l(j)/100:j;if("iframe"===h.type){if(H=h.content,h.autoHeight&&1===H.data("ready"))try{H[0].contentWindow.document.location&&(g.width(C).height(9999),F=H.contents().find("body"),q&&F.css("overflow-x","hidden"),A=F.outerHeight(!0))}catch(G){}}else if(h.autoWidth||
h.autoHeight)g.addClass("fancybox-tmp"),h.autoWidth||g.width(C),h.autoHeight||g.height(A),h.autoWidth&&(C=g.width()),h.autoHeight&&(A=g.height()),g.removeClass("fancybox-tmp");c=l(C);j=l(A);D=C/A;m=l(E(m)?l(m,"w")-z:m);n=l(E(n)?l(n,"w")-z:n);u=l(E(u)?l(u,"h")-t:u);p=l(E(p)?l(p,"h")-t:p);F=n;B=p;h.fitToView&&(n=Math.min(a.w-z,n),p=Math.min(a.h-t,p));z=a.w-y;r=a.h-r;h.aspectRatio?(c>n&&(c=n,j=l(c/D)),j>p&&(j=p,c=l(j*D)),c<m&&(c=m,j=l(c/D)),j<u&&(j=u,c=l(j*D))):(c=Math.max(m,Math.min(c,n)),h.autoHeight&&
"iframe"!==h.type&&(g.width(c),j=g.height()),j=Math.max(u,Math.min(j,p)));if(h.fitToView)if(g.width(c).height(j),e.width(c+x),a=e.width(),y=e.height(),h.aspectRatio)for(;(a>z||y>r)&&(c>m&&j>u)&&!(19<d++);)j=Math.max(u,Math.min(p,j-10)),c=l(j*D),c<m&&(c=m,j=l(c/D)),c>n&&(c=n,j=l(c/D)),g.width(c).height(j),e.width(c+x),a=e.width(),y=e.height();else c=Math.max(m,Math.min(c,c-(a-z))),j=Math.max(u,Math.min(j,j-(y-r)));q&&("auto"===s&&j<A&&c+x+q<z)&&(c+=q);g.width(c).height(j);e.width(c+x);a=e.width();
y=e.height();e=(a>z||y>r)&&c>m&&j>u;c=h.aspectRatio?c<F&&j<B&&c<C&&j<A:(c<F||j<B)&&(c<C||j<A);f.extend(h,{dim:{width:w(a),height:w(y)},origWidth:C,origHeight:A,canShrink:e,canExpand:c,wPadding:x,hPadding:v,wrapSpace:y-k.outerHeight(!0),skinSpace:k.height()-j});!H&&(h.autoHeight&&j>u&&j<p&&!c)&&g.height("auto")},_getPosition:function(a){var d=b.current,e=b.getViewport(),c=d.margin,f=b.wrap.width()+c[1]+c[3],g=b.wrap.height()+c[0]+c[2],c={position:"absolute",top:c[0],left:c[3]};d.autoCenter&&d.fixed&&
!a&&g<=e.h&&f<=e.w?c.position="fixed":d.locked||(c.top+=e.y,c.left+=e.x);c.top=w(Math.max(c.top,c.top+(e.h-g)*d.topRatio));c.left=w(Math.max(c.left,c.left+(e.w-f)*d.leftRatio));return c},_afterZoomIn:function(){var a=b.current;a&&(b.isOpen=b.isOpened=!0,b.wrap.css("overflow","visible").addClass("fancybox-opened"),b.update(),(a.closeClick||a.nextClick&&1<b.group.length)&&b.inner.css("cursor","pointer").bind("click.fb",function(d){!f(d.target).is("a")&&!f(d.target).parent().is("a")&&(d.preventDefault(),
b[a.closeClick?"close":"next"]())}),a.closeBtn&&f(a.tpl.closeBtn).appendTo(b.skin).bind("click.fb",function(a){a.preventDefault();b.close()}),a.arrows&&1<b.group.length&&((a.loop||0<a.index)&&f(a.tpl.prev).appendTo(b.outer).bind("click.fb",b.prev),(a.loop||a.index<b.group.length-1)&&f(a.tpl.next).appendTo(b.outer).bind("click.fb",b.next)),b.trigger("afterShow"),!a.loop&&a.index===a.group.length-1?b.play(!1):b.opts.autoPlay&&!b.player.isActive&&(b.opts.autoPlay=!1,b.play()))},_afterZoomOut:function(a){a=
a||b.current;f(".fancybox-wrap").trigger("onReset").remove();f.extend(b,{group:{},opts:{},router:!1,current:null,isActive:!1,isOpened:!1,isOpen:!1,isClosing:!1,wrap:null,skin:null,outer:null,inner:null});b.trigger("afterClose",a)}});b.transitions={getOrigPosition:function(){var a=b.current,d=a.element,e=a.orig,c={},f=50,g=50,h=a.hPadding,j=a.wPadding,m=b.getViewport();!e&&(a.isDom&&d.is(":visible"))&&(e=d.find("img:first"),e.length||(e=d));t(e)?(c=e.offset(),e.is("img")&&(f=e.outerWidth(),g=e.outerHeight())):
(c.top=m.y+(m.h-g)*a.topRatio,c.left=m.x+(m.w-f)*a.leftRatio);if("fixed"===b.wrap.css("position")||a.locked)c.top-=m.y,c.left-=m.x;return c={top:w(c.top-h*a.topRatio),left:w(c.left-j*a.leftRatio),width:w(f+j),height:w(g+h)}},step:function(a,d){var e,c,f=d.prop;c=b.current;var g=c.wrapSpace,h=c.skinSpace;if("width"===f||"height"===f)e=d.end===d.start?1:(a-d.start)/(d.end-d.start),b.isClosing&&(e=1-e),c="width"===f?c.wPadding:c.hPadding,c=a-c,b.skin[f](l("width"===f?c:c-g*e)),b.inner[f](l("width"===
f?c:c-g*e-h*e))},zoomIn:function(){var a=b.current,d=a.pos,e=a.openEffect,c="elastic"===e,k=f.extend({opacity:1},d);delete k.position;c?(d=this.getOrigPosition(),a.openOpacity&&(d.opacity=0.1)):"fade"===e&&(d.opacity=0.1);b.wrap.css(d).animate(k,{duration:"none"===e?0:a.openSpeed,easing:a.openEasing,step:c?this.step:null,complete:b._afterZoomIn})},zoomOut:function(){var a=b.current,d=a.closeEffect,e="elastic"===d,c={opacity:0.1};e&&(c=this.getOrigPosition(),a.closeOpacity&&(c.opacity=0.1));b.wrap.animate(c,
{duration:"none"===d?0:a.closeSpeed,easing:a.closeEasing,step:e?this.step:null,complete:b._afterZoomOut})},changeIn:function(){var a=b.current,d=a.nextEffect,e=a.pos,c={opacity:1},f=b.direction,g;e.opacity=0.1;"elastic"===d&&(g="down"===f||"up"===f?"top":"left","down"===f||"right"===f?(e[g]=w(l(e[g])-200),c[g]="+=200px"):(e[g]=w(l(e[g])+200),c[g]="-=200px"));"none"===d?b._afterZoomIn():b.wrap.css(e).animate(c,{duration:a.nextSpeed,easing:a.nextEasing,complete:b._afterZoomIn})},changeOut:function(){var a=
b.previous,d=a.prevEffect,e={opacity:0.1},c=b.direction;"elastic"===d&&(e["down"===c||"up"===c?"top":"left"]=("up"===c||"left"===c?"-":"+")+"=200px");a.wrap.animate(e,{duration:"none"===d?0:a.prevSpeed,easing:a.prevEasing,complete:function(){f(this).trigger("onReset").remove()}})}};b.helpers.overlay={defaults:{closeClick:!0,speedOut:200,showEarly:!0,css:{},locked:!s,fixed:!0},overlay:null,fixed:!1,el:f("html"),create:function(a){a=f.extend({},this.defaults,a);this.overlay&&this.close();this.overlay=
f('<div class="fancybox-overlay"></div>').appendTo(b.coming?b.coming.parent:a.parent);this.fixed=!1;a.fixed&&b.defaults.fixed&&(this.overlay.addClass("fancybox-overlay-fixed"),this.fixed=!0)},open:function(a){var d=this;a=f.extend({},this.defaults,a);this.overlay?this.overlay.unbind(".overlay").width("auto").height("auto"):this.create(a);this.fixed||(n.bind("resize.overlay",f.proxy(this.update,this)),this.update());a.closeClick&&this.overlay.bind("click.overlay",function(a){if(f(a.target).hasClass("fancybox-overlay"))return b.isActive?
b.close():d.close(),!1});this.overlay.css(a.css).show()},close:function(){var a,b;n.unbind("resize.overlay");this.el.hasClass("fancybox-lock")&&(f(".fancybox-margin").removeClass("fancybox-margin"),a=n.scrollTop(),b=n.scrollLeft(),this.el.removeClass("fancybox-lock"),n.scrollTop(a).scrollLeft(b));f(".fancybox-overlay").remove().hide();f.extend(this,{overlay:null,fixed:!1})},update:function(){var a="100%",b;this.overlay.width(a).height("100%");I?(b=Math.max(G.documentElement.offsetWidth,G.body.offsetWidth),
p.width()>b&&(a=p.width())):p.width()>n.width()&&(a=p.width());this.overlay.width(a).height(p.height())},onReady:function(a,b){var e=this.overlay;f(".fancybox-overlay").stop(!0,!0);e||this.create(a);a.locked&&(this.fixed&&b.fixed)&&(e||(this.margin=p.height()>n.height()?f("html").css("margin-right").replace("px",""):!1),b.locked=this.overlay.append(b.wrap),b.fixed=!1);!0===a.showEarly&&this.beforeShow.apply(this,arguments)},beforeShow:function(a,b){var e,c;b.locked&&(!1!==this.margin&&(f("*").filter(function(){return"fixed"===
f(this).css("position")&&!f(this).hasClass("fancybox-overlay")&&!f(this).hasClass("fancybox-wrap")}).addClass("fancybox-margin"),this.el.addClass("fancybox-margin")),e=n.scrollTop(),c=n.scrollLeft(),this.el.addClass("fancybox-lock"),n.scrollTop(e).scrollLeft(c));this.open(a)},onUpdate:function(){this.fixed||this.update()},afterClose:function(a){this.overlay&&!b.coming&&this.overlay.fadeOut(a.speedOut,f.proxy(this.close,this))}};b.helpers.title={defaults:{type:"float",position:"bottom"},beforeShow:function(a){var d=
b.current,e=d.title,c=a.type;f.isFunction(e)&&(e=e.call(d.element,d));if(q(e)&&""!==f.trim(e)){d=f('<div class="fancybox-title fancybox-title-'+c+'-wrap">'+e+"</div>");switch(c){case "inside":c=b.skin;break;case "outside":c=b.wrap;break;case "over":c=b.inner;break;default:c=b.skin,d.appendTo("body"),I&&d.width(d.width()),d.wrapInner('<span class="child"></span>'),b.current.margin[2]+=Math.abs(l(d.css("margin-bottom")))}d["top"===a.position?"prependTo":"appendTo"](c)}}};f.fn.fancybox=function(a){var d,
e=f(this),c=this.selector||"",k=function(g){var h=f(this).blur(),j=d,k,l;!g.ctrlKey&&(!g.altKey&&!g.shiftKey&&!g.metaKey)&&!h.is(".fancybox-wrap")&&(k=a.groupAttr||"data-fancybox-group",l=h.attr(k),l||(k="rel",l=h.get(0)[k]),l&&(""!==l&&"nofollow"!==l)&&(h=c.length?f(c):e,h=h.filter("["+k+'="'+l+'"]'),j=h.index(this)),a.index=j,!1!==b.open(h,a)&&g.preventDefault())};a=a||{};d=a.index||0;!c||!1===a.live?e.unbind("click.fb-start").bind("click.fb-start",k):p.undelegate(c,"click.fb-start").delegate(c+
":not('.fancybox-item, .fancybox-nav')","click.fb-start",k);this.filter("[data-fancybox-start=1]").trigger("click");return this};p.ready(function(){var a,d;f.scrollbarWidth===v&&(f.scrollbarWidth=function(){var a=f('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo("body"),b=a.children(),b=b.innerWidth()-b.height(99).innerWidth();a.remove();return b});if(f.support.fixedPosition===v){a=f.support;d=f('<div style="position:fixed;top:20px;"></div>').appendTo("body");var e=20===
d[0].offsetTop||15===d[0].offsetTop;d.remove();a.fixedPosition=e}f.extend(b.defaults,{scrollbarWidth:f.scrollbarWidth(),fixed:f.support.fixedPosition,parent:f("body")});a=f(r).width();J.addClass("fancybox-lock-test");d=f(r).width();J.removeClass("fancybox-lock-test");f("<style type='text/css'>.fancybox-margin{margin-right:"+(d-a)+"px;}</style>").appendTo("head")})})(window,document,jQuery);debugLevel = 0;

function actionButtonEnable()
{
	jQuery('.validateActionButton').removeClass('disabledButton');
}

function actionButtonDisable()
{
	jQuery('.validateActionButton').addClass('disabledButton');
}

function _bindCloseValidation() {
    jQuery('.closeValidation').unbind('click').click(function(){
        jQuery(this).parent('.validationErrorContent').hide('slow');
    });
}

function _showErrorsNextToButton(caller) {
    if (caller) {
        var buttonErrorContainer = jQuery(caller).closest('.validateActionButtons').find('.validationErrorContent');

        if (buttonErrorContainer) {
            _bindCloseValidation();
            var errorKeys = collectErrorKeys('validationNotValid');

            buttonErrorContainer.show();
            buttonErrorContainer.find('.validationErrors').html(errorKeys);

            setTimeout(function(){jQuery('.validationErrorContent').hide('slow');},'10000');
        }

    }
}

function bindValidationEvents()
{
  jQuery('.closeValidation').unbind('click').click(function(){
			// get first error
			var toScroll = jQuery('.validationNotValid').first().offset().top - 60;
			jQuery("html, body").delay(500).animate({ 'scrollTop': toScroll }, "slow");
      jQuery(this).parent('.validationErrorContent').fadeOut();
  });
	jQuery('.isRequired').each(function()
	{
		var validationType = jQuery(this).attr('validationtype');

		if (typeof validationType == typeof undefined || validationType == false)
		{
			//jQuery(this).attr('validation-type','text');
			validationType = 'text';
		}

		if (validationType=='text' || validationType=='email')
		{
			jQuery(this).unbind('keyup').keyup(function()
			{
				if (jQuery(this).val().length>1)
				{
					jQuery(this).attr('validationtouched',1); // mark that this can be validated
				}
			});

			jQuery(this).unbind('blur').blur(function()
			{
				var isValid = _validateFormFields('live','validationNotValid','validationIsValid');
			});

			jQuery(this).unbind('mouseout').mouseout(function()
			{
				var isValid = _validateFormFields('live','validationNotValid','validationIsValid');
			});
		}

		if (validationType=='icheck')
		{
			jQuery(this).on('ifChecked',function()
			{
				jQuery(this).attr('validationtouched',1);
				var isValid = _validateFormFields('live','validationNotValid','validationIsValid');
			});

			jQuery(this).on('ifUnchecked',function()
			{
				var isValid = _validateFormFields('live','validationNotValid','validationIsValid');
			});

		}


		if (validationType=='select')
		{
			jQuery(this).change(function()
			{
				jQuery(this).attr('validationtouched',1);
				var isValid = _validateFormFields('live','validationNotValid','validationIsValid');

			});
		}

		if (validationType=='iradio') /* radios are always in groups*/
		{
			var groupContainer = jQuery(this);
			var groupName = groupContainer.attr('validationgroupname');

			groupContainer.find("input:radio[name='"+groupName+"']").on('ifChecked',function()
			{
				groupContainer.attr('validationtouched',1);
				var isValid = _validateFormFields('live','validationNotValid','validationIsValid');
			});
		}

		var isValid = _validateFormFields('onLoad','','');
	});

}


/**
 *
 *
 * @param method  LIVE|BUTTON|OTHER
 * @param notValidClassName Class name used to not valid fields. Leave empty if only want to validate
 * @param isValidClassName Class name used to show on valid fields
 * @param classSelector
 * @param idSelector
 * @param wrapperClass
 */

function _validateFormFields(method,notValidClassName,isValidClassName,requiredClassSelector,idSelector,wrapperClass)
{

	debugLevel = 0;

	var localIsValid = true;


	if (typeof id == typeof undefined || id == false) { id = ''; }
	if (typeof requiredClassSelector == typeof undefined || requiredClassSelector == false)	{requiredClassSelector = '';}
	if (typeof wrapperClass == typeof undefined || wrapperClass == false) { wrapperClass = ''; }

	var keyToFind = id+'.isRequired:visible'+requiredClassSelector;
	debug(keyToFind);


	jQuery(keyToFind).each(function()
	{
		var validate = true;
		var classValid = isValidClassName;
		var classNotValid = notValidClassName;

		/* If live validation, validate only those that have been once touched */
		var hasBeenTouched = jQuery(this).attr('validationtouched');
		if (method == 'live' && hasBeenTouched!=1)
		{
			classValid = classNotValid = '';
		}

		if (validate)
		{
			var validationType = jQuery(this).attr('validationtype');
			if (typeof validationType == typeof undefined || validationType == false)
			{
				validationType = 'text';
				//jQuery(this).attr('validationtype','text');
			}

			if (validationType=='text')
			{
				if (!validateTextField(this,classNotValid,classValid,wrapperClass))
				{
					localIsValid = false;
				}
			}

			if (validationType=='email')
			{
				if (!validateEmailField(this,classNotValid,classValid,wrapperClass))
				{
					localIsValid = false;
				}
			}

			if (validationType=='checkbox' || validationType=='icheck')
			{
				if (!validateCheckBox(this,classNotValid,classValid,wrapperClass))
				{
					localIsValid = false;
				}
			}

			if (validationType=='checkboxwrapper')
			{

				if (!validateCheckBoxWrapper(this,classNotValid,classValid,wrapperClass))
				{
					localIsValid = false;
				}
			}

			if (validationType=='select')
			{
				if (!validateSelect(this,classNotValid,classValid,wrapperClass))
				{
					localIsValid = false;
				}
			}

			/*** Needs always a container */
			if (validationType=='iradio')
			{
				if (!validateRadio(this,classNotValid,classValid,wrapperClass))
				{
					localIsValid = false;
				}
			}

		}
	});

	if (localIsValid)
	{
		actionButtonEnable();
	}
	else
	{
		actionButtonDisable();
	}

	return localIsValid;
}

function collectErrorKeys(classNotValid)
{
	var errorKeys = [];

	jQuery('.'+classNotValid).each(function()
	{
		var validationErrorId = jQuery(this).attr('validationerrorid'); // the DOM id to contain the error message
		if (typeof validationErrorId !== typeof undefined && validationErrorId !== false)
		{
			var errorKey = '#'+validationErrorId;
			if (exists(errorKey))
			{
				validationErrorId = jQuery(errorKey).html();
			}
			errorKeys.push('<li>'+validationErrorId+'</li>');
		}
	});

	if (errorKeys.length==0)
	{
		errorKeys.push('generic');
	}
	return errorKeys;
}


/**
 *
 *
 * @param element
 * @param notValidClassName
 * @param isValidClassName
 * @param wrapperClass
 * @returns {boolean}
 */
function validateTextField(element,notValidClassName,isValidClassName,wrapperClass)
{
	var localIsValid = true;
	var errorId = 0;
	var minLength = 1;
	var value = jQuery(element).val();

	if (!value)
	{
		localIsValid = false;
	}
	else
	{
		var requiredLength = jQuery(element).attr('validationminlength');
		if (typeof requiredLength !== typeof undefined && requiredLength !== false)
		{
			minLength = parseInt(requiredLength);
		}
		if (value.length<minLength)
		{
			localIsValid = false;
		}

		var maxLength = 999999;
		var maxLength = jQuery(element).attr('validationmaxlength');
		if (typeof maxLength !== typeof undefined && maxLength !== false)
		{
			maxLength = parseInt(maxLength);
		}
		if (value.length>maxLength)
		{
			localIsValid = false;
		}


	}

	if (notValidClassName!='')
	{
		if (!localIsValid)
		{
			addRequiredClass(element,notValidClassName,wrapperClass);
		}
		else
		{
			if (isValidClassName)
			{
				addRequiredClass(element,isValidClassName,wrapperClass);
			}
			removeRequiredClass(element,notValidClassName,wrapperClass);
		}
	}


	return localIsValid;
}





function validateEmailField(element,notValidClassName,isValidClassName,wrapperClass)
{
	var localIsValid = validateEmail(jQuery(element).val());

	if (notValidClassName!='')
	{
		if (!localIsValid)
		{
			addRequiredClass(element,notValidClassName,wrapperClass);
		}
		else
		{
			if (isValidClassName)
			{
				addRequiredClass(element,isValidClassName,wrapperClass);
			}
			removeRequiredClass(element,notValidClassName,wrapperClass);
		}
	}

	return localIsValid;

}

function validateCheckBox(element,notValidClassName,isValidClassName,wrapperClass)
{


	var localIsValid = true;
	if (jQuery(element).prop('checked')==false)
	{
		localIsValid = false;
	}

	if (notValidClassName!='')
	{
		if (wrapperClass == '')
		{
			wrapperClass = 'checkboxWrapper';
		}

		if (jQuery(element).attr('wrapperclass'))
		{
			wrapperClass = jQuery(element).attr('wrapperclass');
		}

		if (!localIsValid)
		{
			addRequiredClass(element,notValidClassName,wrapperClass);
		}
		else
		{
			removeRequiredClass(element,notValidClassName,wrapperClass);
		}
	}

	return localIsValid;
}

function validateCheckBoxWrapper(element,notValidClassName,isValidClassName,wrapperClass)
{


	var localIsValid = true;
	if (jQuery(element).find('input[type="checkbox"]').prop('checked')==false)
	{
		localIsValid = false;
	}

	if (notValidClassName!='')
	{

		if (jQuery(element).attr('wrapperclass'))
		{
			wrapperClass = jQuery(element).attr('wrapperclass');
		}

		if (!localIsValid)
		{
			addRequiredClass(element,notValidClassName,wrapperClass);
		}
		else
		{
			removeRequiredClass(element,notValidClassName,wrapperClass);
		}
	}

	return localIsValid;
}


function validateSelect(element,notValidClassName,isValidClassName,wrapperClass)
{
	var localIsValid = true;
	var val = jQuery.trim(jQuery(element).val());
	if (val=='N/C' || val=='' || val=='CHOOSE')
	{
		localIsValid = false;
	}

	if (notValidClassName!='')
	{
		if (!localIsValid)
		{
			addRequiredClass(element,notValidClassName,wrapperClass);
		}
		else
		{
			if (isValidClassName)
			{
				addRequiredClass(element,isValidClassName,wrapperClass);
			}
			removeRequiredClass(element,notValidClassName,wrapperClass);
		}
	}

	return localIsValid;
}



function validateRadio(element,notValidClassName,isValidClassName,wrapperClass)
{
	var localIsValid = true;
	var groupName = jQuery(element).attr('validationgroupname');
	var key = "input[name='"+groupName+"']:checked";
	var groupSelectedItemValue = jQuery(key).val();


	if (typeof groupSelectedItemValue !== typeof undefined && groupSelectedItemValue !== false)
	{
		if (groupSelectedItemValue=='validationExlude')
		{
			localIsValid = false;
		}
	}
	else
	{
		localIsValid = false;
	}


	if (notValidClassName!='')
	{
		if (!localIsValid)
		{
			addRequiredClass(element,notValidClassName,wrapperClass);
		}
		else
		{
			removeRequiredClass(element,notValidClassName,wrapperClass);
		}
	}

	return localIsValid;
}
function bindMobileMenu() {


    /*GOTHIA*/

    jQuery('.mobile_menu_control').click(function(){
        jQuery(this).toggleClass('icon-menu');
        if (jQuery('.top_links').hasClass('open')) {
            jQuery('.top_links').removeClass('open');
            jQuery('.top_bar_control').removeClass('icon-up-open').addClass('icon-cog');
        }

        jQuery('.loginIndicatorContainer').toggleClass('open');
    });


    jQuery('.top_bar_control').click(function(){
        jQuery(this).toggleClass('icon-cog icon-up-open');
        if (jQuery('.loginIndicatorContainer').hasClass('open')) {
            jQuery('.loginIndicatorContainer').removeClass('open');
            jQuery('.mobile_menu_control').addClass('icon-menu');

        }
        jQuery('.top_links').toggleClass('open');
    });

    jQuery('.bindTrustYouPopup').fancybox({
        width: 800,
        height: 800,
        autoSize: false
    });



    /* UPPER */

    jQuery('.upper-mobile-nav-toggle').click(function(){
        jQuery('.upper-links, body').toggleClass('open');
    });

    jQuery('.bindLangChange').unbind().click(function(){
        var lang = jQuery(this).attr('data-language');
        changeLang(lang);
    });

    //fix protected email in footer
    jQuery('.__cf_email__').parent('a').empty().attr('href', 'mailto:info@gothiatowers.com').text('info@gothiatowers.com');


}

function applePie() {
    return ( navigator.userAgent.match(/(iPhone|iPod|iPad)/i) );
}

$('.fancy-overlay').fancybox({
    your: 'settings',

});

function bindLoginPopup () {

    // in profile we need to remove the generic validation class from the popup

    jQuery('#loginPopup').find('.isRequired').removeClass('isRequired');

    // if getparameter for opening login is set
    if (findGetParameter('showLogin') == 1) {
        openLoginPopUp();
    }



    // if in bookingengine
    if (jQuery('body').hasClass('inBookingEngine')) {
        if (isMobile()) {
            jQuery('.bindOpenLoginPopup').fancybox({
                'padding': 0,
                'width': '100%',
                'height': '100%',
                'topRatio': 0,
                'leftRatio': 0,
                'margin': 0,
                'autoSize': false,
                'fitToView': true,
                'wrapCSS': 'smFancybox',
                afterShow: function() {
                    checkLoginAndEnrollFieldsOnOpen();
                    if ( applePie() ) {
                        jQuery('body').css({'position': 'fixed'});
                    }
                },
                afterClose: function() {
                    checkLoginAndEnrollFieldsOnClose();
                    if ( applePie() ) { jQuery('body').css({'position': ''}); }
                }
            });

            jQuery('.bindLoginFromCode').fancybox({
                'padding': 0,
                'width': '100%',
                'height': '100%',
                'topRatio': 0,
                'leftRatio': 0,
                'margin': 0,
                'autoSize': false,
                'fitToView': true,
                'wrapCSS': 'smFancybox',
                afterShow: function() {
                    checkLoginAndEnrollFieldsOnOpen();
                    if ( applePie() ) {
                        jQuery('body').css({'position': 'fixed'});
                    }
                },
                afterClose: function() {
                    checkLoginAndEnrollFieldsOnClose();
                    if ( applePie() ) { jQuery('body').css({'position': ''}); }
                }
            });

        }
        else {
            jQuery('.bindOpenLoginPopup').fancybox({
                'padding': 0,
                'minWidth': 500,
                'maxWidth': 500,
                'wrapCSS': 'smFancybox',
                afterShow: function() {
                    checkLoginAndEnrollFieldsOnOpen();
                },
                afterClose: function() {
                    checkLoginAndEnrollFieldsOnClose();
                }
            });
            jQuery('.bindLoginFromCode').fancybox({
                'padding': 0,
                'minWidth': 500,
                'maxWidth': 500,
                'wrapCSS': 'smFancybox',
                afterShow: function() {
                    checkLoginAndEnrollFieldsOnOpen();
                },
                afterClose: function() {
                    checkLoginAndEnrollFieldsOnClose();
                }
            });
        }


    }



    // if in homepage
    else {
        jQuery('.bindOpenLoginPopup').click(function(e){
            e.preventDefault();
            document.location = jsConfig.baseUrl+'/reserve/home?showLogin=1'
        });

        jQuery('.bindLoginFromCode').click(function(e){
            e.preventDefault();
            document.location = jsConfig.baseUrl+'/reserve/home?showLogin=1'
        });
    }

}

function findGetParameter(parameterName) {
    var result = null,
        tmp = [];
    location.search
        .substr(1)
        .split("&")
        .forEach(function (item) {
            tmp = item.split("=");
            if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
        });
    return result;
}

function openLoginPopUp() {
    jQuery.fancybox.open(jQuery('#loginPopup'),{
        'padding': 0,
        'minWidth': 500,
        'maxWidth': 500,
        'wrapCSS': 'smFancybox'
    });
}
/**
 * When any profile values keyup, check if the all fields filled, fire GA
 *
 * https://developers.google.com/tag-manager/enhanced-ecommerce
 *
 * Specs:
 * https://docs.google.com/spreadsheets/d/1tTYE8ZpUGYazJgA8K6TVbxiV9VJlhbkdXaYB0S-YCB0/edit#gid=1696563682
 *
 *
 * Product Detail Impressions (Show rate codes)
 * Checkout (Show checkout details)
 * Purchases (Show recept) (edited)
 */


function gaAlert(msg)
{
    /*alert(msg);*/
}

function _gaGetProduct(elem)
{
    var product = {};
    var pname        = _GetHtml(elem,null);
    var pid          = _GetData(elem,'id',null);
    var category   = _GetData(elem,'category',null);
    var pvariant 	= _GetData(elem,'variant',null);
    var price 	    = _GetData(elem,'price',null);
    var position    = _GetData(elem,'position',null);
    var brand       = _GetData(elem,'brand',null);
    var list        = _GetData(elem,'list',null);
    var qty         = _GetData(elem,'quantity',null);
    var coupun      = _GetData(elem,'coupon',null);

    var dim1         = _GetData(elem,'dim1',null);
    var dim2         = _GetData(elem,'dim2',null);
    var dim3         = _GetData(elem,'dim3',null);
    var dim4         = _GetData(elem,'dim4',null);
    var dim5         = _GetData(elem, 'dim5', null);
    var dim6         = _GetData(elem, 'dim6', null);

    var dim10         = _GetData(elem,'dim10',null);
    var dim11         = _GetData(elem,'dim11',null);



    /*	 THIS IS THE REALS STUFF */
    if (_isDef(pid)) product.id = pid;
    if (_isDef(pname)) product.name = pname;
    if (_isDef(category)) product.category = category;
    if (_isDef(pvariant)) product.variant = pvariant;
    if (_isDef(price)) product.price = price.toString();
    if (_isDef(position)) product.position = position;
    if (_isDef(brand)) product.brand = brand;
    if (_isDef(list)) product.list = list;
    if (_isDef(qty)) product.quantity = parseInt(qty);
    if (_isDef(coupun)) product.coupon = coupun;

    if (_isDef(dim1)) product.dimension1 = dim1;
    if (_isDef(dim2)) product.dimension2 = dim2;
    if (_isDef(dim3)) product.dimension3 = dim3;
    if (_isDef(dim4)) product.dimension4 = dim4;
    if (_isDef(dim4)) product.dimension5 = dim5;
    if (_isDef(dim4)) product.dimension6 = dim6;

    if (_isDef(dim10)) product.dimension10 = dim10;
    if (_isDef(dim11)) product.dimension11 = dim11;

    var action         = _GetData(elem,'action',null);
    if (_isDef(action))
    {
        if (action=='remove')
        {
            elem.remove();
        }
    }


    return product;
}

function _gaGetProducts(selector)
{
    var products = [];

    jQuery(selector).each(function ()
    {
        product = _gaGetProduct(this);

        products.push(product);
    });

    return products;
}


function _gaGetAppPhase()
{
    if (exists('#gaFunnelCategory'))
    {
        return _GetData('#gaFunnelCategory','appphase');
    }
    return false;
}



function dataLayerCallback() {

}




var gaFiredProfile = false;
function _bindGaProfileTriggers()
{
    if (_gaGetAppPhase()=='profile')
    {
        if (isLoggedIn)
        {
            gaSendCheckOutStep(1,'Profile filled');
        }
        else
        {
            jQuery('.gaTriggerProfile').unbind('keydown').keydown(function()
            {
                var allFilled = true;
                jQuery('.gaTriggerProfile').each(function()
                {
                    if (jQuery(this).val()=='')
                    {
                        allFilled = false;
                    }
                });

                if (allFilled && !gaFiredProfile)
                {
                    gaFiredProfile = true;
                    gaSendCheckOutStep(1,'Profile filled');
                }
            });
        }
    }
}




/***
 * Should be only one at the time, controlled in templates
 *
 * Note: List problem: https://github.com/rishuk51/analytics-issues/issues/553
 * @param category
 * @param label
 */
function _gaSendAddToCart(products)
{
    gaAlert('addTocart'+products);
    dataLayer.push({
        'event': 'addToCart',
        'ecommerce': {
            'currencyCode': 'SEK',
            'add': {
                'actionField': {'list': 'logi'},
                'products' : products
            }
        }
    });
}

function _gaSendSearchMaskCode(codeValue) {
    dataLayer.push({
        'event': 'Code',
        'eventCategory': 'E-commerce',
        'eventAction': 'Code',
        'eventLabel': 'Code',
        'eventValue': codeValue
    });
}

function _gaSendLoginEvent() {
    dataLayer.push({
        'event': 'Login',
        'eventCategory': 'E-commerce',
        'eventAction': 'Login',
        'eventLabel': 'Login',
    });
}

function _gaSendRegisterEvent() {
    dataLayer.push({
        'event': 'Create Login',
        'eventCategory': 'E-commerce',
        'eventAction': 'Create Login',
        'eventLabel': 'CreateLogin',
    });
}

function _gaSendRemoveFromCart(products)
{
    gaAlert('RemoveFromCart'+products);
    dataLayer.push({
        'event': 'removeFromCart',
        'ecommerce': {
            'currencyCode': 'SEK',
            'remove': {
                'actionField': {'list': 'logi'},
                'products' : products
            }
        }
    });

}

function _gaSendInternalReferral(eventLabel) {
    dataLayer.push({
        'hitType': 'event',
        'eventCategory': 'Ecommerce',
        'eventAction': 'internalReferral',
        'eventLabel': eventLabel,
    });
}

function sendReferralAndRedirect() {
    jQuery('.bindSendReferralAndRedirect').click(function(e){
        e.preventDefault();
        _gaSendInternalReferral(jQuery(this).data('source'));
        var link = jQuery(this).data('link');
        setTimeout(function(){
            window.location.href = link;
        },1000)


    });

}



function _gaSendPackageAddToCart()
{
    if (exists('.gaPackageAddToCartObject'))
    {
        gaSendAddToCardBySelector('.gaPackageAddToCartObject');
    }
}

function _gaSendPackageRemoveFromCart()
{
    if (exists('.gaPackageRemoveFromCartObject'))
    {
        gaSendRemoveFromCardBySelector('.gaPackageRemoveFromCartObject');
    }
}



/***
 *
 * @param category
 * @param label
 */
function _gaSendCheckoutStep(products,step,option)
{
    dataLayer.push({
        'event': 'checkout',
        'ecommerce': {
            'checkout': {
                'actionField': {'step': step,	'option': option , 'list':'logi'},
                'products' : products
            }
        }
    });
}





function _gaSendImpressions() {

    if (exists('.gaImpressionDetailObject'))
    {
        var impressions = _gaGetProducts('.gaImpressionDetailObject');
        dataLayer.push({
            'ecommerce': {

                'detail':
                {
                    'actionField': {'list': 'logi'},
                    'products': impressions
                }
            }
        });
    }

    if (exists('.gaImpressionObject'))
    {
        var impressions = _gaGetProducts('.gaImpressionObject');
        dataLayer.push({
            'ecommerce': {
                'currencyCode': 'SEK',                       // Local currency is optional.
                'impressions': impressions
            }
        });
    }
}

function _gaSendVirtualPageViews() {
    if (exists('.gaVirtualPageViewObject'))
    {
        var page = _GetData('.gaVirtualPageViewObject', 'page', null);
        var title = _GetData('.gaVirtualPageViewObject', 'title', null);
        // old
        /*dataLayer.push({
            'hitType': 'pageview',
            'page': page,
            'title': title,
        }); */
        //new requested by johan.
        dataLayer.push({
            'event': 'virtualPageview',
            'virtualPage': page,
            'virtualTitle': title,
        });
    }
}


function _gaBindTermsAndConditionsEvent()
{
    jQuery('#checkTC').change(function(){
        if (jQuery(this).is(':checked'))
        {
            gaSendCheckOutStep(2,'Accept terms');
        }
    });
}


/** Public functions used in code**/

function bindAnalyticsTriggersOnAjaxComplete()
{
    _gaSendPackageAddToCart(); /* packages added through ajax */
    _gaSendPackageRemoveFromCart();
}

function bindAnalyticsTriggersOnPageComplete()
{
    _bindGaProfileTriggers(); // bind a check to all profile fields when they are filled

    _gaSendImpressions();

    _gaBindTermsAndConditionsEvent();

    _gaSendVirtualPageViews();
}




function gaSendCheckOutStep(step,option)
{
    var products = _gaGetProducts('.gaFunnelProduct');
    _gaSendCheckoutStep(products,step,option);
    gaAlert('Checkout step:'+step+' - option:'+option);
    return true;
}

function gaSendAddToCardBySelector(selector)
{
    var products = _gaGetProducts(selector);
    _gaSendAddToCart(products);
    return true;
}

function sendAddToCartInAvailabilityList(elem) {
    var gaData = jQuery(elem).find('.gaImpressionObject');
    gaSendAddToCardByElement(gaData);
}

function gaSendAddToCardByElement(elem)
{
    var product     = _gaGetProduct(elem);
    var products    = [product];

    _gaSendAddToCart(products);
    return true;
}


function gaSendRemoveFromCardBySelector(selector)
{
    var products = _gaGetProducts(selector);
    _gaSendRemoveFromCart(products);
    return true;
}













