//MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006 Valerio Proietti, <http://mad4milk.net>, MIT Style License.
var MooTools={version:"1.12"};function $defined(a){return(a!=undefined)}function $type(b){if(!$defined(b)){return false}if(b.htmlElement){return"element"}var a=typeof b;if(a=="object"&&b.nodeName){switch(b.nodeType){case 1:return"element";case 3:return(/\S/).test(b.nodeValue)?"textnode":"whitespace"}}if(a=="object"||a=="function"){switch(b.constructor){case Array:return"array";case RegExp:return"regexp";case Class:return"class"}if(typeof b.length=="number"){if(b.item){return"collection"}if(b.callee){return"arguments"}}}return a}function $merge(){var c={};for(var b=0;b<arguments.length;b++){for(var f in arguments[b]){var a=arguments[b][f];var d=c[f];if(d&&$type(a)=="object"&&$type(d)=="object"){c[f]=$merge(d,a)}else{c[f]=a}}}return c}var $extend=function(){var a=arguments;if(!a[1]){a=[this,a[0]]}for(var b in a[1]){a[0][b]=a[1][b]}return a[0]};var $native=function(){for(var b=0,a=arguments.length;b<a;b++){arguments[b].extend=function(c){for(var d in c){if(!this.prototype[d]){this.prototype[d]=c[d]}if(!this[d]){this[d]=$native.generic(d)}}}}};$native.generic=function(a){return function(b){return this.prototype[a].apply(b,Array.prototype.slice.call(arguments,1))}};$native(Function,Array,String,Number);function $chk(a){return !!(a||a===0)}function $pick(b,a){return $defined(b)?b:a}function $random(b,a){return Math.floor(Math.random()*(a-b+1)+b)}function $time(){return new Date().getTime()}function $clear(a){clearTimeout(a);clearInterval(a);return null}var Abstract=function(a){a=a||{};a.extend=$extend;return a};var Window=new Abstract(window);var Document=new Abstract(document);document.head=document.getElementsByTagName("head")[0];window.xpath=!!(document.evaluate);if(window.ActiveXObject){window.ie=window[window.XMLHttpRequest?"ie7":"ie6"]=true}else{if(document.childNodes&&!document.all&&!navigator.taintEnabled){window.webkit=window[window.xpath?"webkit420":"webkit419"]=true}else{if(document.getBoxObjectFor!=null||window.mozInnerScreenX!=null){window.gecko=true}}}window.khtml=window.webkit;Object.extend=$extend;if(typeof HTMLElement=="undefined"){var HTMLElement=function(){};if(window.webkit){document.createElement("iframe")}HTMLElement.prototype=(window.webkit)?window["[[DOMElement.prototype]]"]:{}}HTMLElement.prototype.htmlElement=function(){};if(window.ie6){try{document.execCommand("BackgroundImageCache",false,true)}catch(e){}}var Class=function(b){var a=function(){return(arguments[0]!==null&&this.initialize&&$type(this.initialize)=="function")?this.initialize.apply(this,arguments):this};$extend(a,this);a.prototype=b;a.constructor=Class;return a};Class.empty=function(){};Class.prototype={extend:function(b){var c=new this(null);for(var d in b){var a=c[d];c[d]=Class.Merge(a,b[d])}return new Class(c)},implement:function(){for(var b=0,a=arguments.length;b<a;b++){$extend(this.prototype,arguments[b])}}};Class.Merge=function(c,d){if(c&&c!=d){var b=$type(d);if(b!=$type(c)){return d}switch(b){case"function":var a=function(){this.parent=arguments.callee.parent;return d.apply(this,arguments)};a.parent=c;return a;case"object":return $merge(c,d)}}return d};var Chain=new Class({chain:function(a){this.chains=this.chains||[];this.chains.push(a);return this},callChain:function(){if(this.chains&&this.chains.length){this.chains.shift().delay(10,this)}},clearChain:function(){this.chains=[]}});var Events=new Class({addEvent:function(b,a){if(a!=Class.empty){this.$events=this.$events||{};this.$events[b]=this.$events[b]||[];this.$events[b].include(a)}return this},fireEvent:function(c,b,a){if(this.$events&&this.$events[c]){this.$events[c].each(function(d){d.create({bind:this,delay:a,"arguments":b})()},this)}return this},removeEvent:function(b,a){if(this.$events&&this.$events[b]){this.$events[b].remove(a)}return this}});var Options=new Class({setOptions:function(){this.options=$merge.apply(null,[this.options].extend(arguments));if(this.addEvent){for(var a in this.options){if($type(this.options[a]=="function")&&(/^on[A-Z]/).test(a)){this.addEvent(a,this.options[a])}}}return this}});Array.extend({forEach:function(c,d){for(var b=0,a=this.length;b<a;b++){c.call(d,this[b],b,this)}},filter:function(d,f){var c=[];for(var b=0,a=this.length;b<a;b++){if(d.call(f,this[b],b,this)){c.push(this[b])}}return c},map:function(d,f){var c=[];for(var b=0,a=this.length;b<a;b++){c[b]=d.call(f,this[b],b,this)}return c},every:function(c,d){for(var b=0,a=this.length;b<a;b++){if(!c.call(d,this[b],b,this)){return false}}return true},some:function(c,d){for(var b=0,a=this.length;b<a;b++){if(c.call(d,this[b],b,this)){return true}}return false},indexOf:function(c,d){var a=this.length;for(var b=(d<0)?Math.max(0,a+d):d||0;b<a;b++){if(this[b]===c){return b}}return -1},copy:function(d,c){d=d||0;if(d<0){d=this.length+d}c=c||(this.length-d);var a=[];for(var b=0;b<c;b++){a[b]=this[d++]}return a},remove:function(c){var b=0;var a=this.length;while(b<a){if(this[b]===c){this.splice(b,1);a--}else{b++}}return this},contains:function(a,b){return this.indexOf(a,b)!=-1},associate:function(c){var d={},b=Math.min(this.length,c.length);for(var a=0;a<b;a++){d[c[a]]=this[a]}return d},extend:function(c){for(var b=0,a=c.length;b<a;b++){this.push(c[b])}return this},merge:function(c){for(var b=0,a=c.length;b<a;b++){this.include(c[b])}return this},include:function(a){if(!this.contains(a)){this.push(a)}return this},getRandom:function(){return this[$random(0,this.length-1)]||null},getLast:function(){return this[this.length-1]||null}});Array.prototype.each=Array.prototype.forEach;Array.each=Array.forEach;function $A(a){return Array.copy(a)}function $each(c,b,d){if(c&&typeof c.length=="number"&&$type(c)!="object"){Array.forEach(c,b,d)}else{for(var a in c){b.call(d||c,c[a],a)}}}Array.prototype.test=Array.prototype.contains;String.extend({test:function(a,b){return(($type(a)=="string")?new RegExp(a,b):a).test(this)},toInt:function(){return parseInt(this,10)},toFloat:function(){return parseFloat(this)},camelCase:function(){return this.replace(/-\D/g,function(a){return a.charAt(1).toUpperCase()})},hyphenate:function(){return this.replace(/\w[A-Z]/g,function(a){return(a.charAt(0)+"-"+a.charAt(1).toLowerCase())})},capitalize:function(){return this.replace(/\b[a-z]/g,function(a){return a.toUpperCase()})},trim:function(){return this.replace(/^\s+|\s+$/g,"")},clean:function(){return this.replace(/\s{2,}/g," ").trim()},rgbToHex:function(b){var a=this.match(/\d{1,3}/g);return(a)?a.rgbToHex(b):false},hexToRgb:function(b){var a=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);return(a)?a.slice(1).hexToRgb(b):false},contains:function(a,b){return(b)?(b+this+b).indexOf(b+a+b)>-1:this.indexOf(a)>-1},escapeRegExp:function(){return this.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")}});Array.extend({rgbToHex:function(d){if(this.length<3){return false}if(this.length==4&&this[3]==0&&!d){return"transparent"}var b=[];for(var a=0;a<3;a++){var c=(this[a]-0).toString(16);b.push((c.length==1)?"0"+c:c)}return d?b:"#"+b.join("")},hexToRgb:function(c){if(this.length!=3){return false}var a=[];for(var b=0;b<3;b++){a.push(parseInt((this[b].length==1)?this[b]+this[b]:this[b],16))}return c?a:"rgb("+a.join(",")+")"}});Function.extend({create:function(a){var b=this;a=$merge({bind:b,event:false,"arguments":null,delay:false,periodical:false,attempt:false},a);if($chk(a.arguments)&&$type(a.arguments)!="array"){a.arguments=[a.arguments]}return function(f){var c;if(a.event){f=f||window.event;c=[(a.event===true)?f:new a.event(f)];if(a.arguments){c.extend(a.arguments)}}else{c=a.arguments||arguments}var g=function(){return b.apply($pick(a.bind,b),c)};if(a.delay){return setTimeout(g,a.delay)}if(a.periodical){return setInterval(g,a.periodical)}if(a.attempt){try{return g()}catch(d){return false}}return g()}},pass:function(a,b){return this.create({"arguments":a,bind:b})},attempt:function(a,b){return this.create({"arguments":a,bind:b,attempt:true})()},bind:function(b,a){return this.create({bind:b,"arguments":a})},bindAsEventListener:function(b,a){return this.create({bind:b,event:true,"arguments":a})},delay:function(b,c,a){return this.create({delay:b,bind:c,"arguments":a})()},periodical:function(a,c,b){return this.create({periodical:a,bind:c,"arguments":b})()}});Number.extend({toInt:function(){return parseInt(this)},toFloat:function(){return parseFloat(this)},limit:function(b,a){return Math.min(a,Math.max(b,this))},round:function(a){a=Math.pow(10,a||0);return Math.round(this*a)/a},times:function(b){for(var a=0;a<this;a++){b(a)}}});var Element=new Class({initialize:function(d,c){if($type(d)=="string"){if(window.ie&&c&&(c.name||c.type)){var a=(c.name)?' name="'+c.name+'"':"";var b=(c.type)?' type="'+c.type+'"':"";delete c.name;delete c.type;d="<"+d+a+b+">"}d=document.createElement(d)}d=$(d);return(!c||!d)?d:d.set(c)}});var Elements=new Class({initialize:function(a){return(a)?$extend(a,this):this}});Elements.extend=function(a){for(var b in a){this.prototype[b]=a[b];this[b]=$native.generic(b)}};function $(b){if(!b){return null}if(b.htmlElement){return Garbage.collect(b)}if([window,document].contains(b)){return b}var a=$type(b);if(a=="string"){b=document.getElementById(b);a=(b)?"element":false}if(a!="element"){return null}if(b.htmlElement){return Garbage.collect(b)}if(["object","embed"].contains(b.tagName.toLowerCase())){return b}$extend(b,Element.prototype);b.htmlElement=function(){};return Garbage.collect(b)}document.getElementsBySelector=document.getElementsByTagName;function $$(){var d=[];for(var c=0,b=arguments.length;c<b;c++){var a=arguments[c];switch($type(a)){case"element":d.push(a);case"boolean":break;case false:break;case"string":a=document.getElementsBySelector(a,true);default:d.extend(a)}}return $$.unique(d)}$$.unique=function(j){var f=[];for(var c=0,a=j.length;c<a;c++){if(j[c].$included){continue}var b=$(j[c]);if(b&&!b.$included){b.$included=true;f.push(b)}}for(var h=0,g=f.length;h<g;h++){f[h].$included=null}return new Elements(f)};Elements.Multi=function(a){return function(){var d=arguments;var b=[];var h=true;for(var f=0,c=this.length,g;f<c;f++){g=this[f][a].apply(this[f],d);if($type(g)!="element"){h=false}b.push(g)}return(h)?$$.unique(b):b}};Element.extend=function(a){for(var b in a){HTMLElement.prototype[b]=a[b];Element.prototype[b]=a[b];Element[b]=$native.generic(b);var c=(Array.prototype[b])?b+"Elements":b;Elements.prototype[c]=Elements.Multi(b)}};Element.extend({set:function(a){for(var c in a){var b=a[c];switch(c){case"styles":this.setStyles(b);break;case"events":if(this.addEvents){this.addEvents(b)}break;case"properties":this.setProperties(b);break;default:this.setProperty(c,b)}}return this},inject:function(c,a){c=$(c);switch(a){case"before":c.parentNode.insertBefore(this,c);break;case"after":var b=c.getNext();if(!b){c.parentNode.appendChild(this)}else{c.parentNode.insertBefore(this,b)}break;case"top":var d=c.firstChild;if(d){c.insertBefore(this,d);break}default:c.appendChild(this)}return this},injectBefore:function(a){return this.inject(a,"before")},injectAfter:function(a){return this.inject(a,"after")},injectInside:function(a){return this.inject(a,"bottom")},injectTop:function(a){return this.inject(a,"top")},adopt:function(){var a=[];$each(arguments,function(b){a=a.concat(b)});$$(a).inject(this);return this},remove:function(){return this.parentNode.removeChild(this)},clone:function(c){var b=$(this.cloneNode(c!==false));if(!b.$events){return b}b.$events={};for(var a in this.$events){b.$events[a]={keys:$A(this.$events[a].keys),values:$A(this.$events[a].values)}}return b.removeEvents()},replaceWith:function(a){a=$(a);this.parentNode.replaceChild(a,this);return a},appendText:function(a){this.appendChild(document.createTextNode(a));return this},hasClass:function(a){return this.className.contains(a," ")},addClass:function(a){if(!this.hasClass(a)){this.className=(this.className+" "+a).clean()}return this},removeClass:function(a){this.className=this.className.replace(new RegExp("(^|\\s)"+a+"(?:\\s|$)"),"$1").clean();return this},toggleClass:function(a){return this.hasClass(a)?this.removeClass(a):this.addClass(a)},setStyle:function(b,a){switch(b){case"opacity":return this.setOpacity(parseFloat(a));case"float":b=(window.ie)?"styleFloat":"cssFloat"}b=b.camelCase();switch($type(a)){case"number":if(!["zIndex","zoom"].contains(b)){a+="px"}break;case"array":a="rgb("+a.join(",")+")"}this.style[b]=a;return this},setStyles:function(a){switch($type(a)){case"object":Element.setMany(this,"setStyle",a);break;case"string":this.style.cssText=a}return this},setOpacity:function(a){if(a==0){if(this.style.visibility!="hidden"){this.style.visibility="hidden"}}else{if(this.style.visibility!="visible"){this.style.visibility="visible"}}if(!this.currentStyle||!this.currentStyle.hasLayout){this.style.zoom=1}if(window.ie){this.style.filter=(a==1)?"":"alpha(opacity="+a*100+")"}this.style.opacity=this.$tmp.opacity=a;return this},getStyle:function(c){c=c.camelCase();var a=this.style[c];if(!$chk(a)){if(c=="opacity"){return this.$tmp.opacity}a=[];for(var b in Element.Styles){if(c==b){Element.Styles[b].each(function(g){var f=this.getStyle(g);a.push(parseInt(f)?f:"0px")},this);if(c=="border"){var d=a.every(function(f){return(f==a[0])});return(d)?a[0]:false}return a.join(" ")}}if(c.contains("border")){if(Element.Styles.border.contains(c)){return["Width","Style","Color"].map(function(f){return this.getStyle(c+f)},this).join(" ")}else{if(Element.borderShort.contains(c)){return["Top","Right","Bottom","Left"].map(function(f){return this.getStyle("border"+f+c.replace("border",""))},this).join(" ")}}}if(document.defaultView){a=document.defaultView.getComputedStyle(this,null).getPropertyValue(c.hyphenate())}else{if(this.currentStyle){a=this.currentStyle[c]}}}if(window.ie){a=Element.fixStyle(c,a,this)}if(a&&c.test(/color/i)&&a.contains("rgb")){return a.split("rgb").splice(1,4).map(function(f){return f.rgbToHex()}).join(" ")}return a},getStyles:function(){return Element.getMany(this,"getStyle",arguments)},walk:function(a,c){a+="Sibling";var b=(c)?this[c]:this[a];while(b&&$type(b)!="element"){b=b[a]}return $(b)},getPrevious:function(){return this.walk("previous")},getNext:function(){return this.walk("next")},getFirst:function(){return this.walk("next","firstChild")},getLast:function(){return this.walk("previous","lastChild")},getParent:function(){return $(this.parentNode)},getChildren:function(){return $$(this.childNodes)},hasChild:function(a){return !!$A(this.getElementsByTagName("*")).contains(a)},getProperty:function(d){var b=Element.Properties[d];if(b){return this[b]}var a=Element.PropertiesIFlag[d]||0;if(!window.ie||a){return this.getAttribute(d,a)}var c=this.attributes[d];return(c)?c.nodeValue:null},removeProperty:function(b){var a=Element.Properties[b];if(a){this[a]=""}else{this.removeAttribute(b)}return this},getProperties:function(){return Element.getMany(this,"getProperty",arguments)},setProperty:function(c,b){var a=Element.Properties[c];if(a){this[a]=b}else{this.setAttribute(c,b)}return this},setProperties:function(a){return Element.setMany(this,"setProperty",a)},setHTML:function(){this.innerHTML=$A(arguments).join("");return this},setText:function(b){var a=this.getTag();if(["style","script"].contains(a)){if(window.ie){if(a=="style"){this.styleSheet.cssText=b}else{if(a=="script"){this.setProperty("text",b)}}return this}else{this.removeChild(this.firstChild);return this.appendText(b)}}this[$defined(this.innerText)?"innerText":"textContent"]=b;return this},getText:function(){var a=this.getTag();if(["style","script"].contains(a)){if(window.ie){if(a=="style"){return this.styleSheet.cssText}else{if(a=="script"){return this.getProperty("text")}}}else{return this.innerHTML}}return($pick(this.innerText,this.textContent))},getTag:function(){return this.tagName.toLowerCase()},empty:function(){Garbage.trash(this.getElementsByTagName("*"));return this.setHTML("")}});Element.fixStyle=function(f,a,d){if($chk(parseInt(a))){return a}if(["height","width"].contains(f)){var b=(f=="width")?["left","right"]:["top","bottom"];var c=0;b.each(function(g){c+=d.getStyle("border-"+g+"-width").toInt()+d.getStyle("padding-"+g).toInt()});return d["offset"+f.capitalize()]-c+"px"}else{if(f.test(/border(.+)Width|margin|padding/)){return"0px"}}return a};Element.Styles={border:[],padding:[],margin:[]};["Top","Right","Bottom","Left"].each(function(b){for(var a in Element.Styles){Element.Styles[a].push(a+b)}});Element.borderShort=["borderWidth","borderStyle","borderColor"];Element.getMany=function(b,d,c){var a={};$each(c,function(f){a[f]=b[d](f)});return a};Element.setMany=function(b,d,c){for(var a in c){b[d](a,c[a])}return b};Element.Properties=new Abstract({"class":"className","for":"htmlFor",colspan:"colSpan",rowspan:"rowSpan",accesskey:"accessKey",tabindex:"tabIndex",maxlength:"maxLength",readonly:"readOnly",frameborder:"frameBorder",value:"value",disabled:"disabled",checked:"checked",multiple:"multiple",selected:"selected"});Element.PropertiesIFlag={href:2,src:2};Element.Methods={Listeners:{addListener:function(b,a){if(this.addEventListener){this.addEventListener(b,a,false)}else{this.attachEvent("on"+b,a)}return this},removeListener:function(b,a){if(this.removeEventListener){this.removeEventListener(b,a,false)}else{this.detachEvent("on"+b,a)}return this}}};window.extend(Element.Methods.Listeners);document.extend(Element.Methods.Listeners);Element.extend(Element.Methods.Listeners);var Garbage={elements:[],collect:function(a){if(!a.$tmp){Garbage.elements.push(a);a.$tmp={opacity:1}}return a},trash:function(f){for(var b=0,a=f.length,c;b<a;b++){if(!(c=f[b])||!c.$tmp){continue}if(c.$events){c.fireEvent("trash").removeEvents()}for(var g in c.$tmp){c.$tmp[g]=null}for(var h in Element.prototype){c[h]=null}Garbage.elements[Garbage.elements.indexOf(c)]=null;c.htmlElement=c.$tmp=c=null}Garbage.elements.remove(null)},empty:function(){Garbage.collect(window);Garbage.collect(document);Garbage.trash(Garbage.elements)}};window.addListener("beforeunload",function(){window.addListener("unload",Garbage.empty);if(window.ie){window.addListener("unload",CollectGarbage)}});var Event=new Class({initialize:function(c){if(c&&c.$extended){return c}this.$extended=true;c=c||window.event;this.event=c;this.type=c.type;this.target=c.target||c.srcElement;if(this.target.nodeType==3){this.target=this.target.parentNode}this.shift=c.shiftKey;this.control=c.ctrlKey;this.alt=c.altKey;this.meta=c.metaKey;if(["DOMMouseScroll","mousewheel"].contains(this.type)){this.wheel=(c.wheelDelta)?c.wheelDelta/120:-(c.detail||0)/3}else{if(this.type.contains("key")){this.code=c.which||c.keyCode;for(var b in Event.keys){if(Event.keys[b]==this.code){this.key=b;break}}if(this.type=="keydown"){var a=this.code-111;if(a>0&&a<13){this.key="f"+a}}this.key=this.key||String.fromCharCode(this.code).toLowerCase()}else{if(this.type.test(/(click|mouse|menu)/)){this.page={x:c.pageX||c.clientX+document.documentElement.scrollLeft,y:c.pageY||c.clientY+document.documentElement.scrollTop};this.client={x:c.pageX?c.pageX-window.pageXOffset:c.clientX,y:c.pageY?c.pageY-window.pageYOffset:c.clientY};this.rightClick=(c.which==3)||(c.button==2);switch(this.type){case"mouseover":this.relatedTarget=c.relatedTarget||c.fromElement;break;case"mouseout":this.relatedTarget=c.relatedTarget||c.toElement}this.fixRelatedTarget()}}}return this},stop:function(){return this.stopPropagation().preventDefault()},stopPropagation:function(){if(this.event.stopPropagation){this.event.stopPropagation()}else{this.event.cancelBubble=true}return this},preventDefault:function(){if(this.event.preventDefault){this.event.preventDefault()}else{this.event.returnValue=false}return this}});Event.fix={relatedTarget:function(){if(this.relatedTarget&&this.relatedTarget.nodeType==3){this.relatedTarget=this.relatedTarget.parentNode}},relatedTargetGecko:function(){try{Event.fix.relatedTarget.call(this)}catch(a){this.relatedTarget=this.target}}};Event.prototype.fixRelatedTarget=(window.gecko)?Event.fix.relatedTargetGecko:Event.fix.relatedTarget;Event.keys=new Abstract({enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46});Element.Methods.Events={addEvent:function(c,b){this.$events=this.$events||{};this.$events[c]=this.$events[c]||{keys:[],values:[]};if(this.$events[c].keys.contains(b)){return this}this.$events[c].keys.push(b);var a=c;var d=Element.Events[c];if(d){if(d.add){d.add.call(this,b)}if(d.map){b=d.map}if(d.type){a=d.type}}if(!this.addEventListener){b=b.create({bind:this,event:true})}this.$events[c].values.push(b);return(Element.NativeEvents.contains(a))?this.addListener(a,b):this},removeEvent:function(c,b){if(!this.$events||!this.$events[c]){return this}var g=this.$events[c].keys.indexOf(b);if(g==-1){return this}var a=this.$events[c].keys.splice(g,1)[0];var f=this.$events[c].values.splice(g,1)[0];var d=Element.Events[c];if(d){if(d.remove){d.remove.call(this,b)}if(d.type){c=d.type}}return(Element.NativeEvents.contains(c))?this.removeListener(c,f):this},addEvents:function(a){return Element.setMany(this,"addEvent",a)},removeEvents:function(a){if(!this.$events){return this}if(!a){for(var b in this.$events){this.removeEvents(b)}this.$events=null}else{if(this.$events[a]){this.$events[a].keys.each(function(c){this.removeEvent(a,c)},this);this.$events[a]=null}}return this},fireEvent:function(c,b,a){if(this.$events&&this.$events[c]){this.$events[c].keys.each(function(d){d.create({bind:this,delay:a,"arguments":b})()},this)}return this},cloneEvents:function(c,a){if(!c.$events){return this}if(!a){for(var b in c.$events){this.cloneEvents(c,b)}}else{if(c.$events[a]){c.$events[a].keys.each(function(d){this.addEvent(a,d)},this)}}return this}};window.extend(Element.Methods.Events);document.extend(Element.Methods.Events);Element.extend(Element.Methods.Events);Element.Events=new Abstract({mouseenter:{type:"mouseover",map:function(a){a=new Event(a);if(a.relatedTarget!=this&&!this.hasChild(a.relatedTarget)){this.fireEvent("mouseenter",a)}}},mouseleave:{type:"mouseout",map:function(a){a=new Event(a);if(a.relatedTarget!=this&&!this.hasChild(a.relatedTarget)){this.fireEvent("mouseleave",a)}}},mousewheel:{type:(window.gecko)?"DOMMouseScroll":"mousewheel"}});Element.NativeEvents=["click","dblclick","mouseup","mousedown","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","keydown","keypress","keyup","load","unload","beforeunload","resize","move","focus","blur","change","submit","reset","select","error","abort","contextmenu","scroll"];Function.extend({bindWithEvent:function(b,a){return this.create({bind:b,"arguments":a,event:Event})}});Elements.extend({filterByTag:function(a){return new Elements(this.filter(function(b){return(Element.getTag(b)==a)}))},filterByClass:function(a,c){var b=this.filter(function(d){return(d.className&&d.className.contains(a," "))});return(c)?b:new Elements(b)},filterById:function(c,b){var a=this.filter(function(d){return(d.id==c)});return(b)?a:new Elements(a)},filterByAttribute:function(b,a,d,f){var c=this.filter(function(g){var h=Element.getProperty(g,b);if(!h){return false}if(!a){return true}switch(a){case"=":return(h==d);case"*=":return(h.contains(d));case"^=":return(h.substr(0,d.length)==d);case"$=":return(h.substr(h.length-d.length)==d);case"!=":return(h!=d);case"~=":return h.contains(d," ")}return false});return(f)?c:new Elements(c)}});function $E(a,b){return($(b)||document).getElement(a)}function $ES(a,b){return($(b)||document).getElementsBySelector(a)}$$.shared={regexp:/^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)["']?([^"'\]]*)["']?)?])?$/,xpath:{getParam:function(b,d,f,c){var a=[d.namespaceURI?"xhtml:":"",f[1]];if(f[2]){a.push('[@id="',f[2],'"]')}if(f[3]){a.push('[contains(concat(" ", @class, " "), " ',f[3],' ")]')}if(f[4]){if(f[5]&&f[6]){switch(f[5]){case"*=":a.push("[contains(@",f[4],', "',f[6],'")]');break;case"^=":a.push("[starts-with(@",f[4],', "',f[6],'")]');break;case"$=":a.push("[substring(@",f[4],", string-length(@",f[4],") - ",f[6].length,' + 1) = "',f[6],'"]');break;case"=":a.push("[@",f[4],'="',f[6],'"]');break;case"!=":a.push("[@",f[4],'!="',f[6],'"]')}}else{a.push("[@",f[4],"]")}}b.push(a.join(""));return b},getItems:function(b,f,h){var g=[];var a=document.evaluate(".//"+b.join("//"),f,$$.shared.resolver,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);for(var d=0,c=a.snapshotLength;d<c;d++){g.push(a.snapshotItem(d))}return(h)?g:new Elements(g.map($))}},normal:{getParam:function(a,c,f,b){if(b==0){if(f[2]){var d=c.getElementById(f[2]);if(!d||((f[1]!="*")&&(Element.getTag(d)!=f[1]))){return false}a=[d]}else{a=$A(c.getElementsByTagName(f[1]))}}else{a=$$.shared.getElementsByTagName(a,f[1]);if(f[2]){a=Elements.filterById(a,f[2],true)}}if(f[3]){a=Elements.filterByClass(a,f[3],true)}if(f[4]){a=Elements.filterByAttribute(a,f[4],f[5],f[6],true)}return a},getItems:function(a,b,c){return(c)?a:$$.unique(a)}},resolver:function(a){return(a=="xhtml")?"http://www.w3.org/1999/xhtml":false},getElementsByTagName:function(d,c){var f=[];for(var b=0,a=d.length;b<a;b++){f.extend(d[b].getElementsByTagName(c))}return f}};$$.shared.method=(window.xpath)?"xpath":"normal";Element.Methods.Dom={getElements:function(a,k){var c=[];a=a.trim().split(" ");for(var f=0,d=a.length;f<d;f++){var g=a[f];var h=g.match($$.shared.regexp);if(!h){break}h[1]=h[1]||"*";var b=$$.shared[$$.shared.method].getParam(c,this,h,f);if(!b){break}c=b}return $$.shared[$$.shared.method].getItems(c,this,k)},getElement:function(a){return $(this.getElements(a,true)[0]||false)},getElementsBySelector:function(a,f){var d=[];a=a.split(",");for(var c=0,b=a.length;c<b;c++){d=d.concat(this.getElements(a[c],true))}return(f)?d:$$.unique(d)}};Element.extend({getElementById:function(c){var b=document.getElementById(c);if(!b){return false}for(var a=b.parentNode;a!=this;a=a.parentNode){if(!a){return false}}return b},getElementsByClassName:function(a){return this.getElements("."+a)}});document.extend(Element.Methods.Dom);Element.extend(Element.Methods.Dom);Element.extend({getValue:function(){switch(this.getTag()){case"select":var a=[];$each(this.options,function(b){if(b.selected){a.push($pick(b.value,b.text))}});return(this.multiple)?a:a[0];case"input":if(!(this.checked&&["checkbox","radio"].contains(this.type))&&!["hidden","text","password"].contains(this.type)){break}case"textarea":return this.value}return false},getFormElements:function(){return $$(this.getElementsByTagName("input"),this.getElementsByTagName("select"),this.getElementsByTagName("textarea"))},toQueryString:function(){var a=[];this.getFormElements().each(function(d){var c=d.name;var f=d.getValue();if(f===false||!c||d.disabled){return}var b=function(g){a.push(c+"="+encodeURIComponent(g))};if($type(f)=="array"){f.each(b)}else{b(f)}});return a.join("&")}});Element.extend({scrollTo:function(a,b){this.scrollLeft=a;this.scrollTop=b},getSize:function(){return{scroll:{x:this.scrollLeft,y:this.scrollTop},size:{x:this.offsetWidth,y:this.offsetHeight},scrollSize:{x:this.scrollWidth,y:this.scrollHeight}}},getPosition:function(a){a=a||[];var b=this,d=0,c=0;do{d+=b.offsetLeft||0;c+=b.offsetTop||0;b=b.offsetParent}while(b);a.each(function(f){d-=f.scrollLeft||0;c-=f.scrollTop||0});return{x:d,y:c}},getTop:function(a){return this.getPosition(a).y},getLeft:function(a){return this.getPosition(a).x},getCoordinates:function(b){var a=this.getPosition(b);var c={width:this.offsetWidth,height:this.offsetHeight,left:a.x,top:a.y};c.right=c.left+c.width;c.bottom=c.top+c.height;return c}});Element.Events.domready={add:function(b){if(window.loaded){b.call(this);return}var a=function(){if(window.loaded){return}window.loaded=true;window.timer=$clear(window.timer);this.fireEvent("domready")}.bind(this);if(document.readyState&&window.webkit){window.timer=function(){if(["loaded","complete"].contains(document.readyState)){a()}}.periodical(50)}else{if(document.readyState&&window.ie){if(!$("ie_ready")){var c=(window.location.protocol=="https:")?"://0":"javascript:void(0)";document.write('<script id="ie_ready" defer src="'+c+'"><\/script>');$("ie_ready").onreadystatechange=function(){if(this.readyState=="complete"){a()}}}}else{window.addListener("load",a);document.addListener("DOMContentLoaded",a)}}}};window.onDomReady=function(a){return this.addEvent("domready",a)};window.extend({getWidth:function(){if(this.webkit419){return this.innerWidth}if(this.opera){return document.body.clientWidth}return document.documentElement.clientWidth},getHeight:function(){if(this.webkit419){return this.innerHeight}if(this.opera){return document.body.clientHeight}return document.documentElement.clientHeight},getScrollWidth:function(){if(this.ie){return Math.max(document.documentElement.offsetWidth,document.documentElement.scrollWidth)}if(this.webkit){return document.body.scrollWidth}return document.documentElement.scrollWidth},getScrollHeight:function(){if(this.ie){return Math.max(document.documentElement.offsetHeight,document.documentElement.scrollHeight)}if(this.webkit){return document.body.scrollHeight}return document.documentElement.scrollHeight},getScrollLeft:function(){return this.pageXOffset||document.documentElement.scrollLeft},getScrollTop:function(){return this.pageYOffset||document.documentElement.scrollTop},getSize:function(){return{size:{x:this.getWidth(),y:this.getHeight()},scrollSize:{x:this.getScrollWidth(),y:this.getScrollHeight()},scroll:{x:this.getScrollLeft(),y:this.getScrollTop()}}},getPosition:function(){return{x:0,y:0}}});var Fx={};Fx.Base=new Class({options:{onStart:Class.empty,onComplete:Class.empty,onCancel:Class.empty,transition:function(a){return -(Math.cos(Math.PI*a)-1)/2},duration:500,unit:"px",wait:true,fps:50},initialize:function(a){this.element=this.element||null;this.setOptions(a);if(this.options.initialize){this.options.initialize.call(this)}},step:function(){var a=$time();if(a<this.time+this.options.duration){this.delta=this.options.transition((a-this.time)/this.options.duration);this.setNow();this.increase()}else{this.stop(true);this.set(this.to);this.fireEvent("onComplete",this.element,10);this.callChain()}},set:function(a){this.now=a;this.increase();return this},setNow:function(){this.now=this.compute(this.from,this.to)},compute:function(b,a){return(a-b)*this.delta+b},start:function(b,a){if(!this.options.wait){this.stop()}else{if(this.timer){return this}}this.from=b;this.to=a;this.change=this.to-this.from;this.time=$time();this.timer=this.step.periodical(Math.round(1000/this.options.fps),this);this.fireEvent("onStart",this.element);return this},stop:function(a){if(!this.timer){return this}this.timer=$clear(this.timer);if(!a){this.fireEvent("onCancel",this.element)}return this},custom:function(b,a){return this.start(b,a)},clearTimer:function(a){return this.stop(a)}});Fx.Base.implement(new Chain,new Events,new Options);Fx.CSS={select:function(b,c){if(b.test(/color/i)){return this.Color}var a=$type(c);if((a=="array")||(a=="string"&&c.contains(" "))){return this.Multi}return this.Single},parse:function(c,d,a){if(!a.push){a=[a]}var g=a[0],f=a[1];if(!$chk(f)){f=g;g=c.getStyle(d)}var b=this.select(d,f);return{from:b.parse(g),to:b.parse(f),css:b}}};Fx.CSS.Single={parse:function(a){return parseFloat(a)},getNow:function(c,b,a){return a.compute(c,b)},getValue:function(c,a,b){if(a=="px"&&b!="opacity"){c=Math.round(c)}return c+a}};Fx.CSS.Multi={parse:function(a){return a.push?a:a.split(" ").map(function(b){return parseFloat(b)})},getNow:function(f,d,c){var a=[];for(var b=0;b<f.length;b++){a[b]=c.compute(f[b],d[b])}return a},getValue:function(c,a,b){if(a=="px"&&b!="opacity"){c=c.map(Math.round)}return c.join(a+" ")+a}};Fx.CSS.Color={parse:function(a){return a.push?a:a.hexToRgb(true)},getNow:function(f,d,c){var a=[];for(var b=0;b<f.length;b++){a[b]=Math.round(c.compute(f[b],d[b]))}return a},getValue:function(a){return"rgb("+a.join(",")+")"}};Fx.Style=Fx.Base.extend({initialize:function(b,c,a){this.element=$(b);this.property=c;this.parent(a)},hide:function(){return this.set(0)},setNow:function(){this.now=this.css.getNow(this.from,this.to,this)},set:function(a){this.css=Fx.CSS.select(this.property,a);return this.parent(this.css.parse(a))},start:function(c,b){if(this.timer&&this.options.wait){return this}var a=Fx.CSS.parse(this.element,this.property,[c,b]);this.css=a.css;return this.parent(a.from,a.to)},increase:function(){this.element.setStyle(this.property,this.css.getValue(this.now,this.options.unit,this.property))}});Element.extend({effect:function(b,a){return new Fx.Style(this,b,a)}});Fx.Styles=Fx.Base.extend({initialize:function(b,a){this.element=$(b);this.parent(a)},setNow:function(){for(var a in this.from){this.now[a]=this.css[a].getNow(this.from[a],this.to[a],this)}},set:function(c){var a={};this.css={};for(var b in c){this.css[b]=Fx.CSS.select(b,c[b]);a[b]=this.css[b].parse(c[b])}return this.parent(a)},start:function(c){if(this.timer&&this.options.wait){return this}this.now={};this.css={};var f={},d={};for(var b in c){var a=Fx.CSS.parse(this.element,b,c[b]);f[b]=a.from;d[b]=a.to;this.css[b]=a.css}return this.parent(f,d)},increase:function(){for(var a in this.now){this.element.setStyle(a,this.css[a].getValue(this.now[a],this.options.unit,a))}}});Element.extend({effects:function(a){return new Fx.Styles(this,a)}});Fx.Elements=Fx.Base.extend({initialize:function(b,a){this.elements=$$(b);this.parent(a)},setNow:function(){for(var c in this.from){var g=this.from[c],f=this.to[c],b=this.css[c],a=this.now[c]={};for(var d in g){a[d]=b[d].getNow(g[d],f[d],this)}}},set:function(h){var b={};this.css={};for(var d in h){var g=h[d],c=this.css[d]={},a=b[d]={};for(var f in g){c[f]=Fx.CSS.select(f,g[f]);a[f]=c[f].parse(g[f])}}return this.parent(b)},start:function(d){if(this.timer&&this.options.wait){return this}this.now={};this.css={};var k={},l={};for(var f in d){var h=d[f],a=k[f]={},j=l[f]={},c=this.css[f]={};for(var b in h){var g=Fx.CSS.parse(this.elements[f],b,h[b]);a[b]=g.from;j[b]=g.to;c[b]=g.css}}return this.parent(k,l)},increase:function(){for(var c in this.now){var a=this.now[c],b=this.css[c];for(var d in a){this.elements[c].setStyle(d,b[d].getValue(a[d],this.options.unit,d))}}}});Fx.Scroll=Fx.Base.extend({options:{overflown:[],offset:{x:0,y:0},wheelStops:true},initialize:function(b,a){this.now=[];this.element=$(b);this.bound={stop:this.stop.bind(this,false)};this.parent(a);if(this.options.wheelStops){this.addEvent("onStart",function(){document.addEvent("mousewheel",this.bound.stop)}.bind(this));this.addEvent("onComplete",function(){document.removeEvent("mousewheel",this.bound.stop)}.bind(this))}},setNow:function(){for(var a=0;a<2;a++){this.now[a]=this.compute(this.from[a],this.to[a])}},scrollTo:function(b,g){if(this.timer&&this.options.wait){return this}var d=this.element.getSize();var c={x:b,y:g};for(var f in d.size){var a=d.scrollSize[f]-d.size[f];if($chk(c[f])){c[f]=($type(c[f])=="number")?c[f].limit(0,a):a}else{c[f]=d.scroll[f]}c[f]+=this.options.offset[f]}return this.start([d.scroll.x,d.scroll.y],[c.x,c.y])},toTop:function(){return this.scrollTo(false,0)},toBottom:function(){return this.scrollTo(false,"full")},toLeft:function(){return this.scrollTo(0,false)},toRight:function(){return this.scrollTo("full",false)},toElement:function(b){var a=this.element.getPosition(this.options.overflown);var c=$(b).getPosition(this.options.overflown);return this.scrollTo(c.x-a.x,c.y-a.y)},increase:function(){this.element.scrollTo(this.now[0],this.now[1])}});Fx.Slide=Fx.Base.extend({options:{mode:"vertical"},initialize:function(b,a){this.element=$(b);this.wrapper=new Element("div",{styles:$extend(this.element.getStyles("margin"),{overflow:"hidden"})}).injectAfter(this.element).adopt(this.element);this.element.setStyle("margin",0);this.setOptions(a);this.now=[];this.parent(this.options);this.open=true;this.addEvent("onComplete",function(){this.open=(this.now[0]===0)});if(window.webkit419){this.addEvent("onComplete",function(){if(this.open){this.element.remove().inject(this.wrapper)}})}},setNow:function(){for(var a=0;a<2;a++){this.now[a]=this.compute(this.from[a],this.to[a])}},vertical:function(){this.margin="margin-top";this.layout="height";this.offset=this.element.offsetHeight},horizontal:function(){this.margin="margin-left";this.layout="width";this.offset=this.element.offsetWidth},slideIn:function(a){this[a||this.options.mode]();return this.start([this.element.getStyle(this.margin).toInt(),this.wrapper.getStyle(this.layout).toInt()],[0,this.offset])},slideOut:function(a){this[a||this.options.mode]();return this.start([this.element.getStyle(this.margin).toInt(),this.wrapper.getStyle(this.layout).toInt()],[-this.offset,0])},hide:function(a){this[a||this.options.mode]();this.open=false;return this.set([-this.offset,0])},show:function(a){this[a||this.options.mode]();this.open=true;return this.set([0,this.offset])},toggle:function(a){if(this.wrapper.offsetHeight==0||this.wrapper.offsetWidth==0){return this.slideIn(a)}return this.slideOut(a)},increase:function(){this.element.setStyle(this.margin,this.now[0]+this.options.unit);this.wrapper.setStyle(this.layout,this.now[1]+this.options.unit)}});Fx.Transition=function(b,a){a=a||[];if($type(a)!="array"){a=[a]}return $extend(b,{easeIn:function(c){return b(c,a)},easeOut:function(c){return 1-b(1-c,a)},easeInOut:function(c){return(c<=0.5)?b(2*c,a)/2:(2-b(2*(1-c),a))/2}})};Fx.Transitions=new Abstract({linear:function(a){return a}});Fx.Transitions.extend=function(a){for(var b in a){Fx.Transitions[b]=new Fx.Transition(a[b]);Fx.Transitions.compat(b)}};Fx.Transitions.compat=function(a){["In","Out","InOut"].each(function(b){Fx.Transitions[a.toLowerCase()+b]=Fx.Transitions[a]["ease"+b]})};Fx.Transitions.extend({Pow:function(b,a){return Math.pow(b,a[0]||6)},Expo:function(a){return Math.pow(2,8*(a-1))},Circ:function(a){return 1-Math.sin(Math.acos(a))},Sine:function(a){return 1-Math.sin((1-a)*Math.PI/2)},Back:function(b,a){a=a[0]||1.618;return Math.pow(b,2)*((a+1)*b-a)},Bounce:function(g){var f;for(var d=0,c=1;1;d+=c,c/=2){if(g>=(7-4*d)/11){f=-Math.pow((11-6*d-11*g)/4,2)+c*c;break}}return f},Elastic:function(b,a){return Math.pow(2,10*--b)*Math.cos(20*b*Math.PI*(a[0]||1)/3)}});["Quad","Cubic","Quart","Quint"].each(function(b,a){Fx.Transitions[b]=new Fx.Transition(function(c){return Math.pow(c,[a+2])});Fx.Transitions.compat(b)});var Drag={};Drag.Base=new Class({options:{handle:false,unit:"px",onStart:Class.empty,onBeforeStart:Class.empty,onComplete:Class.empty,onSnap:Class.empty,onDrag:Class.empty,limit:false,modifiers:{x:"left",y:"top"},grid:false,snap:6},initialize:function(b,a){this.setOptions(a);this.element=$(b);this.handle=$(this.options.handle)||this.element;this.mouse={now:{},pos:{}};this.value={start:{},now:{}};this.bound={start:this.start.bindWithEvent(this),check:this.check.bindWithEvent(this),drag:this.drag.bindWithEvent(this),stop:this.stop.bind(this)};this.attach();if(this.options.initialize){this.options.initialize.call(this)}},attach:function(){this.handle.addEvent("mousedown",this.bound.start);return this},detach:function(){this.handle.removeEvent("mousedown",this.bound.start);return this},start:function(c){this.fireEvent("onBeforeStart",this.element);this.mouse.start=c.page;var a=this.options.limit;this.limit={x:[],y:[]};for(var d in this.options.modifiers){if(!this.options.modifiers[d]){continue}this.value.now[d]=this.element.getStyle(this.options.modifiers[d]).toInt();this.mouse.pos[d]=c.page[d]-this.value.now[d];if(a&&a[d]){for(var b=0;b<2;b++){if($chk(a[d][b])){this.limit[d][b]=($type(a[d][b])=="function")?a[d][b]():a[d][b]}}}}if($type(this.options.grid)=="number"){this.options.grid={x:this.options.grid,y:this.options.grid}}document.addListener("mousemove",this.bound.check);document.addListener("mouseup",this.bound.stop);this.fireEvent("onStart",this.element);c.stop()},check:function(a){var b=Math.round(Math.sqrt(Math.pow(a.page.x-this.mouse.start.x,2)+Math.pow(a.page.y-this.mouse.start.y,2)));if(b>this.options.snap){document.removeListener("mousemove",this.bound.check);document.addListener("mousemove",this.bound.drag);this.drag(a);this.fireEvent("onSnap",this.element)}a.stop()},drag:function(a){this.out=false;this.mouse.now=a.page;for(var b in this.options.modifiers){if(!this.options.modifiers[b]){continue}this.value.now[b]=this.mouse.now[b]-this.mouse.pos[b];if(this.limit[b]){if($chk(this.limit[b][1])&&(this.value.now[b]>this.limit[b][1])){this.value.now[b]=this.limit[b][1];this.out=true}else{if($chk(this.limit[b][0])&&(this.value.now[b]<this.limit[b][0])){this.value.now[b]=this.limit[b][0];this.out=true}}}if(this.options.grid[b]){this.value.now[b]-=(this.value.now[b]%this.options.grid[b])}this.element.setStyle(this.options.modifiers[b],this.value.now[b]+this.options.unit)}this.fireEvent("onDrag",this.element);a.stop()},stop:function(){document.removeListener("mousemove",this.bound.check);document.removeListener("mousemove",this.bound.drag);document.removeListener("mouseup",this.bound.stop);this.fireEvent("onComplete",this.element)}});Drag.Base.implement(new Events,new Options);Element.extend({makeResizable:function(a){return new Drag.Base(this,$merge({modifiers:{x:"width",y:"height"}},a))}});Drag.Move=Drag.Base.extend({options:{droppables:[],container:false,overflown:[]},initialize:function(b,a){this.setOptions(a);this.element=$(b);this.droppables=$$(this.options.droppables);this.container=$(this.options.container);this.position={element:this.element.getStyle("position"),container:false};if(this.container){this.position.container=this.container.getStyle("position")}if(!["relative","absolute","fixed"].contains(this.position.element)){this.position.element="absolute"}var d=this.element.getStyle("top").toInt();var c=this.element.getStyle("left").toInt();if(this.position.element=="absolute"&&!["relative","absolute","fixed"].contains(this.position.container)){d=$chk(d)?d:this.element.getTop(this.options.overflown);c=$chk(c)?c:this.element.getLeft(this.options.overflown)}else{d=$chk(d)?d:0;c=$chk(c)?c:0}this.element.setStyles({top:d,left:c,position:this.position.element});this.parent(this.element)},start:function(c){this.overed=null;if(this.container){var a=this.container.getCoordinates();var b=this.element.getCoordinates();if(this.position.element=="absolute"&&!["relative","absolute","fixed"].contains(this.position.container)){this.options.limit={x:[a.left,a.right-b.width],y:[a.top,a.bottom-b.height]}}else{this.options.limit={y:[0,a.height-b.height],x:[0,a.width-b.width]}}}this.parent(c)},drag:function(a){this.parent(a);var b=this.out?false:this.droppables.filter(this.checkAgainst,this).getLast();if(this.overed!=b){if(this.overed){this.overed.fireEvent("leave",[this.element,this])}this.overed=b?b.fireEvent("over",[this.element,this]):null}return this},checkAgainst:function(b){b=b.getCoordinates(this.options.overflown);var a=this.mouse.now;return(a.x>b.left&&a.x<b.right&&a.y<b.bottom&&a.y>b.top)},stop:function(){if(this.overed&&!this.out){this.overed.fireEvent("drop",[this.element,this])}else{this.element.fireEvent("emptydrop",this)}this.parent();return this}});Element.extend({makeDraggable:function(a){return new Drag.Move(this,a)}});var XHR=new Class({options:{method:"post",async:true,onRequest:Class.empty,onSuccess:Class.empty,onFailure:Class.empty,urlEncoded:true,encoding:"utf-8",autoCancel:false,headers:{}},setTransport:function(){this.transport=(window.XMLHttpRequest)?new XMLHttpRequest():(window.ie?new ActiveXObject("Microsoft.XMLHTTP"):false);return this},initialize:function(a){this.setTransport().setOptions(a);this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.headers={};if(this.options.urlEncoded&&this.options.method=="post"){var b=(this.options.encoding)?"; charset="+this.options.encoding:"";this.setHeader("Content-type","application/x-www-form-urlencoded"+b)}if(this.options.initialize){this.options.initialize.call(this)}},onStateChange:function(){if(this.transport.readyState!=4||!this.running){return}this.running=false;var a=0;try{a=this.transport.status}catch(b){}if(this.options.isSuccess.call(this,a)){this.onSuccess()}else{this.onFailure()}this.transport.onreadystatechange=Class.empty},isSuccess:function(a){return((a>=200)&&(a<300))},onSuccess:function(){this.response={text:this.transport.responseText,xml:this.transport.responseXML};this.fireEvent("onSuccess",[this.response.text,this.response.xml]);this.callChain()},onFailure:function(){this.fireEvent("onFailure",this.transport)},setHeader:function(a,b){this.headers[a]=b;return this},send:function(a,c){if(this.options.autoCancel){this.cancel()}else{if(this.running){return this}}this.running=true;if(c&&this.options.method=="get"){a=a+(a.contains("?")?"&":"?")+c;c=null}this.transport.open(this.options.method.toUpperCase(),a,this.options.async);this.transport.onreadystatechange=this.onStateChange.bind(this);if((this.options.method=="post")&&this.transport.overrideMimeType){this.setHeader("Connection","close")}$extend(this.headers,this.options.headers);for(var b in this.headers){try{this.transport.setRequestHeader(b,this.headers[b])}catch(d){}}this.fireEvent("onRequest");this.transport.send($pick(c,null));return this},cancel:function(){if(!this.running){return this}this.running=false;this.transport.abort();this.transport.onreadystatechange=Class.empty;this.setTransport();this.fireEvent("onCancel");return this}});XHR.implement(new Chain,new Events,new Options);var Ajax=XHR.extend({options:{data:null,update:null,onComplete:Class.empty,evalScripts:false,evalResponse:false},initialize:function(b,a){this.addEvent("onSuccess",this.onComplete);this.setOptions(a);this.options.data=this.options.data||this.options.postBody;if(!["post","get"].contains(this.options.method)){this._method="_method="+this.options.method;this.options.method="post"}this.parent();this.setHeader("X-Requested-With","XMLHttpRequest");this.setHeader("Accept","text/javascript, text/html, application/xml, text/xml, */*");this.url=b},onComplete:function(){if(this.options.update){$(this.options.update).empty().setHTML(this.response.text)}if(this.options.evalScripts||this.options.evalResponse){this.evalScripts()}this.fireEvent("onComplete",[this.response.text,this.response.xml],20)},request:function(a){a=a||this.options.data;switch($type(a)){case"element":a=$(a).toQueryString();break;case"object":a=Object.toQueryString(a)}if(this._method){a=(a)?[this._method,a].join("&"):this._method}return this.send(this.url,a)},evalScripts:function(){var b,a;if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){a=this.response.text}else{a=[];var c=/<script[^>]*>([\s\S]*?)<\/script>/gi;while((b=c.exec(this.response.text))){a.push(b[1])}a=a.join("\n")}if(a){(window.execScript)?window.execScript(a):window.setTimeout(a,0)}},getHeader:function(a){try{return this.transport.getResponseHeader(a)}catch(b){}return null}});Object.toQueryString=function(b){var c=[];for(var a in b){c.push(encodeURIComponent(a)+"="+encodeURIComponent(b[a]))}return c.join("&")};Element.extend({send:function(a){return new Ajax(this.getProperty("action"),$merge({data:this.toQueryString()},a,{method:"post"})).request()}});var Cookie=new Abstract({options:{domain:false,path:false,duration:false,secure:false},set:function(c,d,b){b=$merge(this.options,b);d=encodeURIComponent(d);if(b.domain){d+="; domain="+b.domain}if(b.path){d+="; path="+b.path}if(b.duration){var a=new Date();a.setTime(a.getTime()+b.duration*24*60*60*1000);d+="; expires="+a.toGMTString()}if(b.secure){d+="; secure"}document.cookie=c+"="+d;return $extend(b,{key:c,value:d})},get:function(a){var b=document.cookie.match("(?:^|;)\\s*"+a.escapeRegExp()+"=([^;]*)");return b?decodeURIComponent(b[1]):false},remove:function(b,a){if($type(b)=="object"){this.set(b.key,"",$merge(b,{duration:-1}))}else{this.set(b,"",$merge(a,{duration:-1}))}}});var Json={toString:function(c){switch($type(c)){case"string":return'"'+c.replace(/(["\\])/g,"\\$1")+'"';case"array":return"["+c.map(Json.toString).join(",")+"]";case"object":var a=[];for(var b in c){a.push(Json.toString(b)+":"+Json.toString(c[b]))}return"{"+a.join(",")+"}";case"number":if(isFinite(c)){break}case false:return"null"}return String(c)},evaluate:function(str,secure){return(($type(str)!="string")||(secure&&!str.test(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/)))?null:eval("("+str+")")}};Json.Remote=XHR.extend({initialize:function(b,a){this.url=b;this.addEvent("onSuccess",this.onComplete);this.parent(a);this.setHeader("X-Request","JSON")},send:function(a){return this.parent(this.url,"json="+Json.toString(a))},onComplete:function(){this.fireEvent("onComplete",[Json.evaluate(this.response.text,this.options.secure)])}});var Asset=new Abstract({javascript:function(c,b){b=$merge({onload:Class.empty},b);var a=new Element("script",{src:c}).addEvents({load:b.onload,readystatechange:function(){if(this.readyState=="complete"){this.fireEvent("load")}}});delete b.onload;return a.setProperties(b).inject(document.head)},css:function(b,a){return new Element("link",$merge({rel:"stylesheet",media:"screen",type:"text/css",href:b},a)).inject(document.head)},image:function(c,b){b=$merge({onload:Class.empty,onabort:Class.empty,onerror:Class.empty},b);var d=new Image();d.src=c;var a=new Element("img",{src:c});["load","abort","error"].each(function(f){var g=b["on"+f];delete b["on"+f];a.addEvent(f,function(){this.removeEvent(f,arguments.callee);g.call(this)})});if(d.width&&d.height){a.fireEvent("load",a,1)}return a.setProperties(b)},images:function(d,c){c=$merge({onComplete:Class.empty,onProgress:Class.empty},c);if(!d.push){d=[d]}var a=[];var b=0;d.each(function(g){var f=new Asset.image(g,{onload:function(){c.onProgress.call(this,b);b++;if(b==d.length){c.onComplete()}}});a.push(f)});return new Elements(a)}});var Hash=new Class({length:0,initialize:function(a){this.obj=a||{};this.setLength()},get:function(a){return(this.hasKey(a))?this.obj[a]:null},hasKey:function(a){return(a in this.obj)},set:function(a,b){if(!this.hasKey(a)){this.length++}this.obj[a]=b;return this},setLength:function(){this.length=0;for(var a in this.obj){this.length++}return this},remove:function(a){if(this.hasKey(a)){delete this.obj[a];this.length--}return this},each:function(a,b){$each(this.obj,a,b)},extend:function(a){$extend(this.obj,a);return this.setLength()},merge:function(){this.obj=$merge.apply(null,[this.obj].extend(arguments));return this.setLength()},empty:function(){this.obj={};this.length=0;return this},keys:function(){var a=[];for(var b in this.obj){a.push(b)}return a},values:function(){var a=[];for(var b in this.obj){a.push(this.obj[b])}return a}});function $H(a){return new Hash(a)}Hash.Cookie=Hash.extend({initialize:function(b,a){this.name=b;this.options=$extend({autoSave:true},a||{});this.load()},save:function(){if(this.length==0){Cookie.remove(this.name,this.options);return true}var a=Json.toString(this.obj);if(a.length>4096){return false}Cookie.set(this.name,a,this.options);return true},load:function(){this.obj=Json.evaluate(Cookie.get(this.name),true)||{};this.setLength()}});Hash.Cookie.Methods={};["extend","set","merge","empty","remove"].each(function(a){Hash.Cookie.Methods[a]=function(){Hash.prototype[a].apply(this,arguments);if(this.options.autoSave){this.save()}return this}});Hash.Cookie.implement(Hash.Cookie.Methods);var Color=new Class({initialize:function(b,d){d=d||(b.push?"rgb":"hex");var c,a;switch(d){case"rgb":c=b;a=c.rgbToHsb();break;case"hsb":c=b.hsbToRgb();a=b;break;default:c=b.hexToRgb(true);a=c.rgbToHsb()}c.hsb=a;c.hex=c.rgbToHex();return $extend(c,Color.prototype)},mix:function(){var a=$A(arguments);var c=($type(a[a.length-1])=="number")?a.pop():50;var b=this.copy();a.each(function(d){d=new Color(d);for(var f=0;f<3;f++){b[f]=Math.round((b[f]/100*(100-c))+(d[f]/100*c))}});return new Color(b,"rgb")},invert:function(){return new Color(this.map(function(a){return 255-a}))},setHue:function(a){return new Color([a,this.hsb[1],this.hsb[2]],"hsb")},setSaturation:function(a){return new Color([this.hsb[0],a,this.hsb[2]],"hsb")},setBrightness:function(a){return new Color([this.hsb[0],this.hsb[1],a],"hsb")}});function $RGB(d,c,a){return new Color([d,c,a],"rgb")}function $HSB(d,c,a){return new Color([d,c,a],"hsb")}Array.extend({rgbToHsb:function(){var b=this[0],c=this[1],k=this[2];var h,g,i;var j=Math.max(b,c,k),f=Math.min(b,c,k);var l=j-f;i=j/255;g=(j!=0)?l/j:0;if(g==0){h=0}else{var d=(j-b)/l;var a=(j-c)/l;var m=(j-k)/l;if(b==j){h=m-a}else{if(c==j){h=2+d-m}else{h=4+a-d}}h/=6;if(h<0){h++}}return[Math.round(h*360),Math.round(g*100),Math.round(i*100)]},hsbToRgb:function(){var c=Math.round(this[2]/100*255);if(this[1]==0){return[c,c,c]}else{var a=this[0]%360;var g=a%60;var h=Math.round((this[2]*(100-this[1]))/10000*255);var d=Math.round((this[2]*(6000-this[1]*g))/600000*255);var b=Math.round((this[2]*(6000-this[1]*(60-g)))/600000*255);switch(Math.floor(a/60)){case 0:return[c,b,h];case 1:return[d,c,h];case 2:return[h,c,b];case 3:return[h,d,c];case 4:return[b,h,c];case 5:return[c,h,d]}}return false}});var Scroller=new Class({options:{area:20,velocity:1,onChange:function(a,b){this.element.scrollTo(a,b)}},initialize:function(b,a){this.setOptions(a);this.element=$(b);this.mousemover=([window,document].contains(b))?$(document.body):this.element},start:function(){this.coord=this.getCoords.bindWithEvent(this);this.mousemover.addListener("mousemove",this.coord)},stop:function(){this.mousemover.removeListener("mousemove",this.coord);this.timer=$clear(this.timer)},getCoords:function(a){this.page=(this.element==window)?a.client:a.page;if(!this.timer){this.timer=this.scroll.periodical(50,this)}},scroll:function(){var a=this.element.getSize();var d=this.element.getPosition();var c={x:0,y:0};for(var b in this.page){if(this.page[b]<(this.options.area+d[b])&&a.scroll[b]!=0){c[b]=(this.page[b]-this.options.area-d[b])*this.options.velocity}else{if(this.page[b]+this.options.area>(a.size[b]+d[b])&&a.scroll[b]+a.size[b]!=a.scrollSize[b]){c[b]=(this.page[b]-a.size[b]+this.options.area-d[b])*this.options.velocity}}}if(c.y||c.x){this.fireEvent("onChange",[a.scroll.x+c.x,a.scroll.y+c.y])}}});Scroller.implement(new Events,new Options);var Slider=new Class({options:{onChange:Class.empty,onComplete:Class.empty,onTick:function(a){this.knob.setStyle(this.p,a)},mode:"horizontal",steps:100,offset:0},initialize:function(d,a,b){this.element=$(d);this.knob=$(a);this.setOptions(b);this.previousChange=-1;this.previousEnd=-1;this.step=-1;this.element.addEvent("mousedown",this.clickedElement.bindWithEvent(this));var c,g;switch(this.options.mode){case"horizontal":this.z="x";this.p="left";c={x:"left",y:false};g="offsetWidth";break;case"vertical":this.z="y";this.p="top";c={x:false,y:"top"};g="offsetHeight"}this.max=this.element[g]-this.knob[g]+(this.options.offset*2);this.half=this.knob[g]/2;this.getPos=this.element["get"+this.p.capitalize()].bind(this.element);this.knob.setStyle("position","relative").setStyle(this.p,-this.options.offset);var f={};f[this.z]=[-this.options.offset,this.max-this.options.offset];this.drag=new Drag.Base(this.knob,{limit:f,modifiers:c,snap:0,onStart:function(){this.draggedKnob()}.bind(this),onDrag:function(){this.draggedKnob()}.bind(this),onComplete:function(){this.draggedKnob();this.end()}.bind(this)});if(this.options.initialize){this.options.initialize.call(this)}},set:function(a){this.step=a.limit(0,this.options.steps);this.checkStep();this.end();this.fireEvent("onTick",this.toPosition(this.step));return this},clickedElement:function(b){var a=b.page[this.z]-this.getPos()-this.half;a=a.limit(-this.options.offset,this.max-this.options.offset);this.step=this.toStep(a);this.checkStep();this.end();this.fireEvent("onTick",a)},draggedKnob:function(){this.step=this.toStep(this.drag.value.now[this.z]);this.checkStep()},checkStep:function(){if(this.previousChange!=this.step){this.previousChange=this.step;this.fireEvent("onChange",this.step)}},end:function(){if(this.previousEnd!==this.step){this.previousEnd=this.step;this.fireEvent("onComplete",this.step+"")}},toStep:function(a){return Math.round((a+this.options.offset)/this.max*this.options.steps)},toPosition:function(a){return this.max*a/this.options.steps}});Slider.implement(new Events);Slider.implement(new Options);var SmoothScroll=Fx.Scroll.extend({initialize:function(b){this.parent(window,b);this.links=(this.options.links)?$$(this.options.links):$$(document.links);var a=window.location.href.match(/^[^#]*/)[0]+"#";this.links.each(function(d){if(d.href.indexOf(a)!=0){return}var c=d.href.substr(a.length);if(c&&$(c)){this.useLink(d,c)}},this);if(!window.webkit419){this.addEvent("onComplete",function(){window.location.hash=this.anchor})}},useLink:function(b,a){b.addEvent("click",function(c){this.anchor=a;this.toElement(a);c.stop()}.bindWithEvent(this))}});var Sortables=new Class({options:{handles:false,onStart:Class.empty,onComplete:Class.empty,ghost:true,snap:3,onDragStart:function(a,b){b.setStyle("opacity",0.7);a.setStyle("opacity",0.7)},onDragComplete:function(a,b){a.setStyle("opacity",1);b.remove();this.trash.remove()}},initialize:function(d,b){this.setOptions(b);this.list=$(d);this.elements=this.list.getChildren();this.handles=(this.options.handles)?$$(this.options.handles):this.elements;this.bound={start:[],moveGhost:this.moveGhost.bindWithEvent(this)};for(var c=0,a=this.handles.length;c<a;c++){this.bound.start[c]=this.start.bindWithEvent(this,this.elements[c])}this.attach();if(this.options.initialize){this.options.initialize.call(this)}this.bound.move=this.move.bindWithEvent(this);this.bound.end=this.end.bind(this)},attach:function(){this.handles.each(function(b,a){b.addEvent("mousedown",this.bound.start[a])},this)},detach:function(){this.handles.each(function(b,a){b.removeEvent("mousedown",this.bound.start[a])},this)},start:function(c,b){this.active=b;this.coordinates=this.list.getCoordinates();if(this.options.ghost){var a=b.getPosition();this.offset=c.page.y-a.y;this.trash=new Element("div").inject(document.body);this.ghost=b.clone().inject(this.trash).setStyles({position:"absolute",left:a.x,top:c.page.y-this.offset});document.addListener("mousemove",this.bound.moveGhost);this.fireEvent("onDragStart",[b,this.ghost])}document.addListener("mousemove",this.bound.move);document.addListener("mouseup",this.bound.end);this.fireEvent("onStart",b);c.stop()},moveGhost:function(a){var b=a.page.y-this.offset;b=b.limit(this.coordinates.top,this.coordinates.bottom-this.ghost.offsetHeight);this.ghost.setStyle("top",b);a.stop()},move:function(f){var b=f.page.y;this.previous=this.previous||b;var a=((this.previous-b)>0);var d=this.active.getPrevious();var c=this.active.getNext();if(d&&a&&b<d.getCoordinates().bottom){this.active.injectBefore(d)}if(c&&!a&&b>c.getCoordinates().top){this.active.injectAfter(c)}this.previous=b},serialize:function(a){return this.list.getChildren().map(a||function(b){return this.elements.indexOf(b)},this)},end:function(){this.previous=null;document.removeListener("mousemove",this.bound.move);document.removeListener("mouseup",this.bound.end);if(this.options.ghost){document.removeListener("mousemove",this.bound.moveGhost);this.fireEvent("onDragComplete",[this.active,this.ghost])}this.fireEvent("onComplete",this.active)}});Sortables.implement(new Events,new Options);var Tips=new Class({options:{onShow:function(a){a.setStyle("visibility","visible")},onHide:function(a){a.setStyle("visibility","hidden")},maxTitleChars:30,showDelay:100,hideDelay:100,className:"tool",offsets:{x:16,y:16},fixed:false},initialize:function(b,a){this.setOptions(a);this.toolTip=new Element("div",{"class":this.options.className+"-tip",styles:{position:"absolute",top:"0",left:"0",visibility:"hidden"}}).inject(document.body);this.wrapper=new Element("div").inject(this.toolTip);$$(b).each(this.build,this);if(this.options.initialize){this.options.initialize.call(this)}},build:function(b){b.$tmp.myTitle=(b.href&&b.getTag()=="a")?b.href.replace("http://",""):(b.rel||false);if(b.title){var c=b.title.split("::");if(c.length>1){b.$tmp.myTitle=c[0].trim();b.$tmp.myText=c[1].trim()}else{b.$tmp.myText=b.title}b.removeAttribute("title")}else{b.$tmp.myText=false}if(b.$tmp.myTitle&&b.$tmp.myTitle.length>this.options.maxTitleChars){b.$tmp.myTitle=b.$tmp.myTitle.substr(0,this.options.maxTitleChars-1)+"&hellip;"}b.addEvent("mouseenter",function(d){this.start(b);if(!this.options.fixed){this.locate(d)}else{this.position(b)}}.bind(this));if(!this.options.fixed){b.addEvent("mousemove",this.locate.bindWithEvent(this))}var a=this.end.bind(this);b.addEvent("mouseleave",a);b.addEvent("trash",a)},start:function(a){this.wrapper.empty();if(a.$tmp.myTitle){this.title=new Element("span").inject(new Element("div",{"class":this.options.className+"-title"}).inject(this.wrapper)).setHTML(a.$tmp.myTitle)}if(a.$tmp.myText){this.text=new Element("span").inject(new Element("div",{"class":this.options.className+"-text"}).inject(this.wrapper)).setHTML(a.$tmp.myText)}$clear(this.timer);this.timer=this.show.delay(this.options.showDelay,this)},end:function(a){$clear(this.timer);this.timer=this.hide.delay(this.options.hideDelay,this)},position:function(a){var b=a.getPosition();this.toolTip.setStyles({left:b.x+this.options.offsets.x,top:b.y+this.options.offsets.y})},locate:function(b){var d={x:window.getWidth(),y:window.getHeight()};var a={x:window.getScrollLeft(),y:window.getScrollTop()};var c={x:this.toolTip.offsetWidth,y:this.toolTip.offsetHeight};var h={x:"left",y:"top"};for(var f in h){var g=b.page[f]+this.options.offsets[f];if((g+c[f]-a[f])>d[f]){g=b.page[f]-this.options.offsets[f]-c[f]}this.toolTip.setStyle(h[f],g)}},show:function(){if(this.options.timeout){this.timer=this.hide.delay(this.options.timeout,this)}this.fireEvent("onShow",[this.toolTip])},hide:function(){this.fireEvent("onHide",[this.toolTip])}});Tips.implement(new Events,new Options);var Group=new Class({initialize:function(){this.instances=$A(arguments);this.events={};this.checker={}},addEvent:function(b,a){this.checker[b]=this.checker[b]||{};this.events[b]=this.events[b]||[];if(this.events[b].contains(a)){return false}else{this.events[b].push(a)}this.instances.each(function(c,d){c.addEvent(b,this.check.bind(this,[b,c,d]))},this);return this},check:function(c,a,b){this.checker[c][b]=true;var d=this.instances.every(function(g,f){return this.checker[c][f]||false},this);if(!d){return}this.checker[c]={};this.events[c].each(function(f){f.call(this,this.instances,a)},this)}});var Accordion=Fx.Elements.extend({options:{onActive:Class.empty,onBackground:Class.empty,display:0,show:false,height:true,width:false,opacity:true,fixedHeight:false,fixedWidth:false,wait:false,alwaysHide:false},initialize:function(){var c,f,g,b;$each(arguments,function(k,j){switch($type(k)){case"object":c=k;break;case"element":b=$(k);break;default:var h=$$(k);if(!f){f=h}else{g=h}}});this.togglers=f||[];this.elements=g||[];this.container=$(b);this.setOptions(c);this.previous=-1;if(this.options.alwaysHide){this.options.wait=true}if($chk(this.options.show)){this.options.display=false;this.previous=this.options.show}if(this.options.start){this.options.display=false;this.options.show=false}this.effects={};if(this.options.opacity){this.effects.opacity="fullOpacity"}if(this.options.width){this.effects.width=this.options.fixedWidth?"fullWidth":"offsetWidth"}if(this.options.height){this.effects.height=this.options.fixedHeight?"fullHeight":"scrollHeight"}for(var d=0,a=this.togglers.length;d<a;d++){this.addSection(this.togglers[d],this.elements[d])}this.elements.each(function(j,h){if(this.options.show===h){this.fireEvent("onActive",[this.togglers[h],j])}else{for(var k in this.effects){j.setStyle(k,0)}}},this);this.parent(this.elements);if($chk(this.options.display)){this.display(this.options.display)}},addSection:function(f,c,h){f=$(f);c=$(c);var g=this.togglers.contains(f);var b=this.togglers.length;this.togglers.include(f);this.elements.include(c);if(b&&(!g||h)){h=$pick(h,b-1);f.injectBefore(this.togglers[h]);c.injectAfter(f)}else{if(this.container&&!g){f.inject(this.container);c.inject(this.container)}}var a=this.togglers.indexOf(f);f.addEvent("click",this.display.bind(this,a));if(this.options.height){c.setStyles({"padding-top":0,"border-top":"none","padding-bottom":0,"border-bottom":"none"})}if(this.options.width){c.setStyles({"padding-left":0,"border-left":"none","padding-right":0,"border-right":"none"})}c.fullOpacity=1;if(this.options.fixedWidth){c.fullWidth=this.options.fixedWidth}if(this.options.fixedHeight){c.fullHeight=this.options.fixedHeight}c.setStyle("overflow","hidden");if(!g){for(var d in this.effects){c.setStyle(d,0)}}return this},display:function(a){a=($type(a)=="element")?this.elements.indexOf(a):a;if((this.timer&&this.options.wait)||(a===this.previous&&!this.options.alwaysHide)){return this}this.previous=a;var b={};this.elements.each(function(f,d){b[d]={};var c=(d!=a)||(this.options.alwaysHide&&(f.offsetHeight>0));this.fireEvent(c?"onBackground":"onActive",[this.togglers[d],f]);for(var g in this.effects){b[d][g]=c?0:f[this.effects[g]]}},this);return this.start(b)},showThisHideOpen:function(a){return this.display(a)}});Fx.Accordion=Accordion;
/**
* This is a small fix to correct the png transparency problem under IE under version 7
*/
window.addEvent('load', function(e) {
var arVersion = navigator.appVersion.split("MSIE");
var version = parseFloat(arVersion[1]);
if ((version >= 5.5) && (version < 7) && (document.body.filters)) {
for(var i=0; i<document.images.length; i++) {
var img = document.images[i];
var imgName = img.src.toUpperCase();
if ((imgName.substring(imgName.length-3, imgName.length) == "PNG" || imgName.indexOf('FILETYPE=PNG') != -1) && (img.height && img.width)) {
var imgID = (img.id) ? "id='" + img.id + "' " : "";
var imgClass = (img.className) ? "class='" + img.className + "' " : "";
var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' ";
var imgStyle = "display:inline-block;" + img.style.cssText;
if (img.align == "left") imgStyle = "float:left;" + imgStyle;
if (img.align == "right") imgStyle = "float:right;" + imgStyle;
if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle;
var strNewHTML = "<span " + imgID + imgClass + imgTitle
+ " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
+ "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
+ "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>";
img.outerHTML = strNewHTML;
i = i-1;
}
}
}
});
var PrintingWindow = new Class({
options: {
container: document.getElement('body'),
containerClass : 'Synergee-Web-Page-Component-PrintingWindow',
outputId: 'printingWindowFrame',
width : 750,
height : 370,
button : null
},
initialize: function(options) {
this.setOptions(options);
this.output =  new Element('iframe').injectInside(document.getElement('body'));
this.output.setStyle('display','none');
this.output.setAttribute('id', this.options.outputId);
if(this.options.button)this.options.button.addEvent('click', this.displayPrintWindow.bind(this));
},
displayPrintWindow : function(){
Lightbox.show('{hiddenId|' + this.output.id + '}', '', 'width=' + this.options.width + ', height=' + this.options.height);
if (/msie/i.test(navigator.userAgent)) {
// IE
// seems to be a bug in IE that makes contentWindow raise an error in some cases
try {
var w = this.output.contentWindow;
} catch(ex) {
}
var d = w ? w.document : null;
} else {
try {
var d = this.output.contentDocument;
}
catch (ex) {
}	// in case of cross domain scripting
var w = d ? d.defaultView : null;
}
if (d) {
try {
var tempContainer = new Element('div');
var child = this.options.container.clone();
child.injectInside(tempContainer);
child.getElements('script').each(function(item, index){
item.innerHTML = '';
}.bind(this));
d.open();
d.write('<html><head/><body >'+ tempContainer.innerHTML +'</body></html>');
d.close();
var body = d.getElementsByTagName("body")[0];
body.style.textAlign = 'left';
body.setAttribute('class', this.options.containerClass);
//                    if (this.options.button && this.options.button.id && d.getElementById(this.options.button.id)) {
//                        d.getElementById(this.options.button.id).removeChild(d.getElementById(this.options.button.id).childNodes[0]);
//                    }
var styleSheets = document.getElementsByTagName("LINK");
var head = d.getElementsByTagName("HEAD")[0];
if (!head) {
head = d.createElement("HEAD");
d.getElementsByTagName("HTML")[0].insertBefore(head, d.getElementsByTagName("BODY")[0]);
}
for (var i = 0; i < styleSheets.length; i++) {
if (styleSheets[i].getAttribute("rel") == 'stylesheet') {
var linkElement = d.createElement('LINK');
linkElement.setAttribute('href', styleSheets[i].getAttribute("href"));
linkElement.setAttribute('rel', 'stylesheet');
linkElement.setAttribute('type', 'text/css');
head.appendChild(linkElement);
}
}
w.focus();
w.print();
} catch (ex) {
}
}
}
});
PrintingWindow.implement(new Events);
PrintingWindow.implement(new Options);
var ResultHelper = Events.extend( {
initialize: function (resultsPerPage, countResults) {
this.resultsPerPage = resultsPerPage;
this.countResults = countResults;
if (this.resultsPerPage == 0)
this.resultsPerPage = 1;
this.countPages = Math.ceil(this.countResults / this.resultsPerPage);
this.currentPage = 0;
},
getCountPages : function () {
return this.countPages;
},
getCurrentPage : function () {
return this.currentPage;
},
injectNavBar : function(toInjectNavBarClass, tagName, navClassBaseName, separator) {
var s = "";
for (var i=0; i<this.countPages; i++) {
var className = navClassBaseName + i;
s += "<" + (tagName == 'button' ? tagName + ' type="button"' : tagName) + " class='" + className + "'>" + (i+1) + "</" + tagName + ">";
if (i != this.countPages - 1) {
s += separator;
}
}
$$('.'+toInjectNavBarClass).setHTML(s);
},
nextPage : function () {
if (this.currentPage < this.countPages - 1) {
this.fireEvent('onPageChangeBefore');
this.currentPage++;
this.fireEvent('onPageChangeAfter');
if (this.currentPage == this.countPages - 1) {
this.fireEvent('onPageChangeUpperLimit');
}
}
},
previousPage : function () {
if (this.currentPage > 0) {
this.fireEvent('onPageChangeBefore');
this.currentPage--;
this.fireEvent('onPageChangeAfter');
if (this.currentPage == 0) {
this.fireEvent('onPageChangeLowerLimit');
}
}
},
selectPage : function (page) {
if (page >=0 && page < this.countPages) {
this.fireEvent('onPageChangeBefore');
this.currentPage = page;
this.fireEvent('onPageChangeAfter');
if (this.currentPage == 0) {
this.fireEvent('onPageChangeLowerLimit');
}
if (this.currentPage == this.countPages - 1) {
this.fireEvent('onPageChangeUpperLimit');
}
}
},
firstPage : function () {
this.selectPage(0);
},
lastPage : function () {
this.selectPage(this.countPages - 1);
}
});
/****************************************************************
*                                                              *
*  curvyCorners                                                *
*  ------------                                                *
*                                                              *
*  This script generates rounded corners for your divs.        *
*                                                              *
*  Version 1.2.9                                               *
*  Copyright (c) 2006 Cameron Cooke                            *
*  By: Cameron Cooke and Tim Hutchison.                        *
*                                                              *
*                                                              *
*  Website: http://www.curvycorners.net                        *
*  Email:   info@totalinfinity.com                             *
*  Forum:   http://www.curvycorners.net/forum/                 *
*                                                              *
*                                                              *
*  This library is free software; you can redistribute         *
*  it and/or modify it under the terms of the GNU              *
*  Lesser General Public License as published by the           *
*  Free Software Foundation; either version 2.1 of the         *
*  License, or (at your option) any later version.             *
*                                                              *
*  This library is distributed in the hope that it will        *
*  be useful, but WITHOUT ANY WARRANTY; without even the       *
*  implied warranty of MERCHANTABILITY or FITNESS FOR A        *
*  PARTICULAR PURPOSE. See the GNU Lesser General Public       *
*  License for more details.                                   *
*                                                              *
*  You should have received a copy of the GNU Lesser           *
*  General Public License along with this library;             *
*  Inc., 59 Temple Place, Suite 330, Boston,                   *
*  MA 02111-1307 USA                                           *
*                                                              *
****************************************************************/
var isIE = navigator.userAgent.toLowerCase().indexOf("msie") > -1; var isMoz = document.implementation && document.implementation.createDocument; var isSafari = ((navigator.userAgent.toLowerCase().indexOf('safari')!=-1)&&(navigator.userAgent.toLowerCase().indexOf('mac')!=-1))?true:false; function curvyCorners()
{ if(typeof(arguments[0]) != "object") throw newCurvyError("First parameter of curvyCorners() must be an object."); if(typeof(arguments[1]) != "object" && typeof(arguments[1]) != "string") throw newCurvyError("Second parameter of curvyCorners() must be an object or a class name."); if(typeof(arguments[1]) == "string")
{ var startIndex = 0; var boxCol = getElementsByClass(arguments[1]);}
else
{ var startIndex = 1; var boxCol = arguments;}
var curvyCornersCol = new Array(); if(arguments[0].validTags)
var validElements = arguments[0].validTags; else
var validElements = ["div"]; for(var i = startIndex, j = boxCol.length; i < j; i++)
{ var currentTag = boxCol[i].tagName.toLowerCase(); if(inArray(validElements, currentTag) !== false)
{ curvyCornersCol[curvyCornersCol.length] = new curvyObject(arguments[0], boxCol[i]);}
}
this.objects = curvyCornersCol; this.applyCornersToAll = function()
{ for(var x = 0, k = this.objects.length; x < k; x++)
{ this.objects[x].applyCorners();}
}
}
function curvyObject()
{ this.box = arguments[1]; this.settings = arguments[0]; this.topContainer = null; this.bottomContainer = null; this.masterCorners = new Array(); this.contentDIV = null; var boxHeight = get_style(this.box, "height", "height"); var boxWidth = get_style(this.box, "width", "width"); var borderWidth = get_style(this.box, "borderBottomWidth", "border-bottom-width"); var borderColour = get_style(this.box, "borderBottomColor", "border-bottom-color"); var boxColour = get_style(this.box, "backgroundColor", "background-color"); var backgroundImage = get_style(this.box, "backgroundImage", "background-image"); var boxPosition = get_style(this.box, "position", "position"); var boxPadding = get_style(this.box, "paddingBottom", "padding-bottom"); this.boxHeight = parseInt(((boxHeight != "" && boxHeight != "auto" && boxHeight.indexOf("%") == -1)? boxHeight.substring(0, boxHeight.indexOf("px")) : this.box.scrollHeight)); this.boxWidth = parseInt(((boxWidth != "" && boxWidth != "auto" && boxWidth.indexOf("%") == -1)? boxWidth.substring(0, boxWidth.indexOf("px")) : this.box.scrollWidth)); this.borderWidth = parseInt(((borderWidth != "" && borderWidth.indexOf("px") !== -1)? borderWidth.slice(0, borderWidth.indexOf("px")) : 0)); this.boxColour = format_colour(boxColour); this.boxPadding = parseInt(((boxPadding != "" && boxPadding.indexOf("px") !== -1)? boxPadding.slice(0, boxPadding.indexOf("px")) : 0)); this.borderColour = format_colour(borderColour); this.borderString = this.borderWidth + "px" + " solid " + this.borderColour; this.backgroundImage = ((backgroundImage != "none")? backgroundImage : ""); this.boxContent = this.box.innerHTML; if(boxPosition != "absolute") this.box.style.position = "relative"; this.box.style.padding = "0px"; if(isIE && boxWidth == "auto" && boxHeight == "auto") this.box.style.width = "100%"; if(this.settings.autoPad == true && this.boxPadding > 0)
this.box.innerHTML = ""; this.applyCorners = function()
{ for(var t = 0; t < 2; t++)
{ switch(t)
{ case 0:
if(this.settings.tl || this.settings.tr)
{ var newMainContainer = document.createElement("DIV"); newMainContainer.style.width = "100%"; newMainContainer.style.fontSize = "1px"; newMainContainer.style.overflow = "hidden"; newMainContainer.style.position = "absolute"; newMainContainer.style.paddingLeft = this.borderWidth + "px"; newMainContainer.style.paddingRight = this.borderWidth + "px"; var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0); newMainContainer.style.height = topMaxRadius + "px"; newMainContainer.style.top = 0 - topMaxRadius + "px"; newMainContainer.style.left = 0 - this.borderWidth + "px"; this.topContainer = this.box.appendChild(newMainContainer);}
break; case 1:
if(this.settings.bl || this.settings.br)
{ var newMainContainer = document.createElement("DIV"); newMainContainer.style.width = "100%"; newMainContainer.style.fontSize = "1px"; newMainContainer.style.overflow = "hidden"; newMainContainer.style.position = "absolute"; newMainContainer.style.paddingLeft = this.borderWidth + "px"; newMainContainer.style.paddingRight = this.borderWidth + "px"; var botMaxRadius = Math.max(this.settings.bl ? this.settings.bl.radius : 0, this.settings.br ? this.settings.br.radius : 0); newMainContainer.style.height = botMaxRadius + "px"; newMainContainer.style.bottom = 0 - botMaxRadius + "px"; newMainContainer.style.left = 0 - this.borderWidth + "px"; this.bottomContainer = this.box.appendChild(newMainContainer);}
break;}
}
if(this.topContainer) this.box.style.borderTopWidth = "0px"; if(this.bottomContainer) this.box.style.borderBottomWidth = "0px"; var corners = ["tr", "tl", "br", "bl"]; for(var i in corners)
{ if(i > -1 < 4)
{ var cc = corners[i]; if(!this.settings[cc])
{ if(((cc == "tr" || cc == "tl") && this.topContainer != null) || ((cc == "br" || cc == "bl") && this.bottomContainer != null))
{ var newCorner = document.createElement("DIV"); newCorner.style.position = "relative"; newCorner.style.fontSize = "1px"; newCorner.style.overflow = "hidden"; if(this.backgroundImage == "")
newCorner.style.backgroundColor = this.boxColour; else
newCorner.style.backgroundImage = this.backgroundImage; switch(cc)
{ case "tl":
newCorner.style.height = topMaxRadius - this.borderWidth + "px"; newCorner.style.marginRight = this.settings.tr.radius - (this.borderWidth*2) + "px"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.left = -this.borderWidth + "px"; break; case "tr":
newCorner.style.height = topMaxRadius - this.borderWidth + "px"; newCorner.style.marginLeft = this.settings.tl.radius - (this.borderWidth*2) + "px"; newCorner.style.borderRight = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px"; newCorner.style.left = this.borderWidth + "px"; break; case "bl":
newCorner.style.height = botMaxRadius - this.borderWidth + "px"; newCorner.style.marginRight = this.settings.br.radius - (this.borderWidth*2) + "px"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = -this.borderWidth + "px"; newCorner.style.backgroundPosition = "-" + (this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px"; break; case "br":
newCorner.style.height = botMaxRadius - this.borderWidth + "px"; newCorner.style.marginLeft = this.settings.bl.radius - (this.borderWidth*2) + "px"; newCorner.style.borderRight = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = this.borderWidth + "px"
newCorner.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px"; break;}
}
}
else
{ if(this.masterCorners[this.settings[cc].radius])
{ var newCorner = this.masterCorners[this.settings[cc].radius].cloneNode(true);}
else
{ var newCorner = document.createElement("DIV"); newCorner.style.height = this.settings[cc].radius + "px"; newCorner.style.width = this.settings[cc].radius + "px"; newCorner.style.position = "absolute"; newCorner.style.fontSize = "1px"; newCorner.style.overflow = "hidden"; var borderRadius = parseInt(this.settings[cc].radius - this.borderWidth); for(var intx = 0, j = this.settings[cc].radius; intx < j; intx++)
{ if((intx +1) >= borderRadius)
var y1 = -1; else
var y1 = (Math.floor(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow((intx+1), 2))) - 1); if(borderRadius != j)
{ if((intx) >= borderRadius)
var y2 = -1; else
var y2 = Math.ceil(Math.sqrt(Math.pow(borderRadius,2) - Math.pow(intx, 2))); if((intx+1) >= j)
var y3 = -1; else
var y3 = (Math.floor(Math.sqrt(Math.pow(j ,2) - Math.pow((intx+1), 2))) - 1);}
if((intx) >= j)
var y4 = -1; else
var y4 = Math.ceil(Math.sqrt(Math.pow(j ,2) - Math.pow(intx, 2))); if(y1 > -1) this.drawPixel(intx, 0, this.boxColour, 100, (y1+1), newCorner, -1, this.settings[cc].radius); if(borderRadius != j)
{ for(var inty = (y1 + 1); inty < y2; inty++)
{ if(this.settings.antiAlias)
{ if(this.backgroundImage != "")
{ var borderFract = (pixelFraction(intx, inty, borderRadius) * 100); if(borderFract < 30)
{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, 0, this.settings[cc].radius);}
else
{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, -1, this.settings[cc].radius);}
}
else
{ var pixelcolour = BlendColour(this.boxColour, this.borderColour, pixelFraction(intx, inty, borderRadius)); this.drawPixel(intx, inty, pixelcolour, 100, 1, newCorner, 0, this.settings[cc].radius, cc);}
}
}
if(this.settings.antiAlias)
{ if(y3 >= y2)
{ if (y2 == -1) y2 = 0; this.drawPixel(intx, y2, this.borderColour, 100, (y3 - y2 + 1), newCorner, 0, 0);}
}
else
{ if(y3 >= y1)
{ this.drawPixel(intx, (y1 + 1), this.borderColour, 100, (y3 - y1), newCorner, 0, 0);}
}
var outsideColour = this.borderColour;}
else
{ var outsideColour = this.boxColour; var y3 = y1;}
if(this.settings.antiAlias)
{ for(var inty = (y3 + 1); inty < y4; inty++)
{ this.drawPixel(intx, inty, outsideColour, (pixelFraction(intx, inty , j) * 100), 1, newCorner, ((this.borderWidth > 0)? 0 : -1), this.settings[cc].radius);}
}
}
this.masterCorners[this.settings[cc].radius] = newCorner.cloneNode(true);}
if(cc != "br")
{ for(var t = 0, k = newCorner.childNodes.length; t < k; t++)
{ var pixelBar = newCorner.childNodes[t]; var pixelBarTop = parseInt(pixelBar.style.top.substring(0, pixelBar.style.top.indexOf("px"))); var pixelBarLeft = parseInt(pixelBar.style.left.substring(0, pixelBar.style.left.indexOf("px"))); var pixelBarHeight = parseInt(pixelBar.style.height.substring(0, pixelBar.style.height.indexOf("px"))); if(cc == "tl" || cc == "bl"){ pixelBar.style.left = this.settings[cc].radius -pixelBarLeft -1 + "px";}
if(cc == "tr" || cc == "tl"){ pixelBar.style.top = this.settings[cc].radius -pixelBarHeight -pixelBarTop + "px";}
switch(cc)
{ case "tr":
pixelBar.style.backgroundPosition = "-" + Math.abs((this.boxWidth - this.settings[cc].radius + this.borderWidth) + pixelBarLeft) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px"; break; case "tl":
pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px"; break; case "bl":
pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs((this.boxHeight + this.settings[cc].radius + pixelBarTop) -this.borderWidth) + "px"; break;}
}
}
}
if(newCorner)
{ switch(cc)
{ case "tl":
if(newCorner.style.position == "absolute") newCorner.style.top = "0px"; if(newCorner.style.position == "absolute") newCorner.style.left = "0px"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case "tr":
if(newCorner.style.position == "absolute") newCorner.style.top = "0px"; if(newCorner.style.position == "absolute") newCorner.style.right = "0px"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case "bl":
if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px"; if(newCorner.style.position == "absolute") newCorner.style.left = "0px"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break; case "br":
if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px"; if(newCorner.style.position == "absolute") newCorner.style.right = "0px"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break;}
}
}
}
var radiusDiff = new Array(); radiusDiff["t"] = Math.abs(this.settings.tl.radius - this.settings.tr.radius)
radiusDiff["b"] = Math.abs(this.settings.bl.radius - this.settings.br.radius); for(z in radiusDiff)
{ if(z == "t" || z == "b")
{ if(radiusDiff[z])
{ var smallerCornerType = ((this.settings[z + "l"].radius < this.settings[z + "r"].radius)? z +"l" : z +"r"); var newFiller = document.createElement("DIV"); newFiller.style.height = radiusDiff[z] + "px"; newFiller.style.width = this.settings[smallerCornerType].radius+ "px"
newFiller.style.position = "absolute"; newFiller.style.fontSize = "1px"; newFiller.style.overflow = "hidden"; newFiller.style.backgroundColor = this.boxColour; switch(smallerCornerType)
{ case "tl":
newFiller.style.bottom = "0px"; newFiller.style.left = "0px"; newFiller.style.borderLeft = this.borderString; this.topContainer.appendChild(newFiller); break; case "tr":
newFiller.style.bottom = "0px"; newFiller.style.right = "0px"; newFiller.style.borderRight = this.borderString; this.topContainer.appendChild(newFiller); break; case "bl":
newFiller.style.top = "0px"; newFiller.style.left = "0px"; newFiller.style.borderLeft = this.borderString; this.bottomContainer.appendChild(newFiller); break; case "br":
newFiller.style.top = "0px"; newFiller.style.right = "0px"; newFiller.style.borderRight = this.borderString; this.bottomContainer.appendChild(newFiller); break;}
}
var newFillerBar = document.createElement("DIV"); newFillerBar.style.position = "relative"; newFillerBar.style.fontSize = "1px"; newFillerBar.style.overflow = "hidden"; newFillerBar.style.backgroundColor = this.boxColour; newFillerBar.style.backgroundImage = this.backgroundImage; switch(z)
{ case "t":
if(this.topContainer)
{ if(this.settings.tl.radius && this.settings.tr.radius)
{ newFillerBar.style.height = topMaxRadius - this.borderWidth + "px"; newFillerBar.style.marginLeft = this.settings.tl.radius - this.borderWidth + "px"; newFillerBar.style.marginRight = this.settings.tr.radius - this.borderWidth + "px"; newFillerBar.style.borderTop = this.borderString; if(this.backgroundImage != "")
newFillerBar.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px"; this.topContainer.appendChild(newFillerBar);}
this.box.style.backgroundPosition = "0px -" + (topMaxRadius - this.borderWidth) + "px";}
break; case "b":
if(this.bottomContainer)
{ if(this.settings.bl.radius && this.settings.br.radius)
{ newFillerBar.style.height = botMaxRadius - this.borderWidth + "px"; newFillerBar.style.marginLeft = this.settings.bl.radius - this.borderWidth + "px"; newFillerBar.style.marginRight = this.settings.br.radius - this.borderWidth + "px"; newFillerBar.style.borderBottom = this.borderString; if(this.backgroundImage != "")
newFillerBar.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (topMaxRadius + this.borderWidth)) + "px"; this.bottomContainer.appendChild(newFillerBar);}
}
break;}
}
}
if(this.settings.autoPad == true && this.boxPadding > 0)
{ var contentContainer = document.createElement("DIV"); contentContainer.style.position = "relative"; contentContainer.innerHTML = this.boxContent; contentContainer.className = "autoPadDiv"; var topPadding = Math.abs(topMaxRadius - this.boxPadding); var botPadding = Math.abs(botMaxRadius - this.boxPadding); if(topMaxRadius < this.boxPadding)
contentContainer.style.paddingTop = topPadding + "px"; if(botMaxRadius < this.boxPadding)
contentContainer.style.paddingBottom = botMaxRadius + "px"; contentContainer.style.paddingLeft = this.boxPadding + "px"; contentContainer.style.paddingRight = this.boxPadding + "px"; this.contentDIV = this.box.appendChild(contentContainer);}
}
this.drawPixel = function(intx, inty, colour, transAmount, height, newCorner, image, cornerRadius)
{ var pixel = document.createElement("DIV"); pixel.style.height = height + "px"; pixel.style.width = "1px"; pixel.style.position = "absolute"; pixel.style.fontSize = "1px"; pixel.style.overflow = "hidden"; var topMaxRadius = Math.max(this.settings["tr"].radius, this.settings["tl"].radius); if(image == -1 && this.backgroundImage != "")
{ pixel.style.backgroundImage = this.backgroundImage; pixel.style.backgroundPosition = "-" + (this.boxWidth - (cornerRadius - intx) + this.borderWidth) + "px -" + ((this.boxHeight + topMaxRadius + inty) -this.borderWidth) + "px";}
else
{ pixel.style.backgroundColor = colour;}
if (transAmount != 100)
setOpacity(pixel, transAmount); pixel.style.top = inty + "px"; pixel.style.left = intx + "px"; newCorner.appendChild(pixel);}
}
function insertAfter(parent, node, referenceNode)
{ parent.insertBefore(node, referenceNode.nextSibling);}
function BlendColour(Col1, Col2, Col1Fraction)
{ var red1 = parseInt(Col1.substr(1,2),16); var green1 = parseInt(Col1.substr(3,2),16); var blue1 = parseInt(Col1.substr(5,2),16); var red2 = parseInt(Col2.substr(1,2),16); var green2 = parseInt(Col2.substr(3,2),16); var blue2 = parseInt(Col2.substr(5,2),16); if(Col1Fraction > 1 || Col1Fraction < 0) Col1Fraction = 1; var endRed = Math.round((red1 * Col1Fraction) + (red2 * (1 - Col1Fraction))); if(endRed > 255) endRed = 255; if(endRed < 0) endRed = 0; var endGreen = Math.round((green1 * Col1Fraction) + (green2 * (1 - Col1Fraction))); if(endGreen > 255) endGreen = 255; if(endGreen < 0) endGreen = 0; var endBlue = Math.round((blue1 * Col1Fraction) + (blue2 * (1 - Col1Fraction))); if(endBlue > 255) endBlue = 255; if(endBlue < 0) endBlue = 0; return "#" + IntToHex(endRed)+ IntToHex(endGreen)+ IntToHex(endBlue);}
function IntToHex(strNum)
{ base = strNum / 16; rem = strNum % 16; base = base - (rem / 16); baseS = MakeHex(base); remS = MakeHex(rem); return baseS + '' + remS;}
function MakeHex(x)
{ if((x >= 0) && (x <= 9))
{ return x;}
else
{ switch(x)
{ case 10: return "A"; case 11: return "B"; case 12: return "C"; case 13: return "D"; case 14: return "E"; case 15: return "F";}
}
}
function pixelFraction(x, y, r)
{ var pixelfraction = 0; var xvalues = new Array(1); var yvalues = new Array(1); var point = 0; var whatsides = ""; var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x,2))); if ((intersect >= y) && (intersect < (y+1)))
{ whatsides = "Left"; xvalues[point] = 0; yvalues[point] = intersect - y; point = point + 1;}
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y+1,2))); if ((intersect >= x) && (intersect < (x+1)))
{ whatsides = whatsides + "Top"; xvalues[point] = intersect - x; yvalues[point] = 1; point = point + 1;}
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x+1,2))); if ((intersect >= y) && (intersect < (y+1)))
{ whatsides = whatsides + "Right"; xvalues[point] = 1; yvalues[point] = intersect - y; point = point + 1;}
var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y,2))); if ((intersect >= x) && (intersect < (x+1)))
{ whatsides = whatsides + "Bottom"; xvalues[point] = intersect - x; yvalues[point] = 0;}
switch (whatsides)
{ case "LeftRight":
pixelfraction = Math.min(yvalues[0],yvalues[1]) + ((Math.max(yvalues[0],yvalues[1]) - Math.min(yvalues[0],yvalues[1]))/2); break; case "TopRight":
pixelfraction = 1-(((1-xvalues[0])*(1-yvalues[1]))/2); break; case "TopBottom":
pixelfraction = Math.min(xvalues[0],xvalues[1]) + ((Math.max(xvalues[0],xvalues[1]) - Math.min(xvalues[0],xvalues[1]))/2); break; case "LeftBottom":
pixelfraction = (yvalues[0]*xvalues[1])/2; break; default:
pixelfraction = 1;}
return pixelfraction;}
function rgb2Hex(rgbColour)
{ try{ var rgbArray = rgb2Array(rgbColour); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); var hexColour = "#" + IntToHex(red) + IntToHex(green) + IntToHex(blue);}
catch(e){ alert("There was an error converting the RGB value to Hexadecimal in function rgb2Hex");}
return hexColour;}
function rgb2Array(rgbColour)
{ var rgbValues = rgbColour.substring(4, rgbColour.indexOf(")")); var rgbArray = rgbValues.split(", "); return rgbArray;}
function setOpacity(obj, opacity)
{ opacity = (opacity == 100)?99.999:opacity; if(isSafari && obj.tagName != "IFRAME")
{ var rgbArray = rgb2Array(obj.style.backgroundColor); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); obj.style.backgroundColor = "rgba(" + red + ", " + green + ", " + blue + ", " + opacity/100 + ")";}
else if(typeof(obj.style.opacity) != "undefined")
{ obj.style.opacity = opacity/100;}
else if(typeof(obj.style.MozOpacity) != "undefined")
{ obj.style.MozOpacity = opacity/100;}
else if(typeof(obj.style.filter) != "undefined")
{ obj.style.filter = "alpha(opacity:" + opacity + ")";}
else if(typeof(obj.style.KHTMLOpacity) != "undefined")
{ obj.style.KHTMLOpacity = opacity/100;}
}
function inArray(array, value)
{ for(var i = 0; i < array.length; i++){ if (array[i] === value) return i;}
return false;}
function inArrayKey(array, value)
{ for(key in array){ if(key === value) return true;}
return false;}
function addEvent(elm, evType, fn, useCapture) { if (elm.addEventListener) { elm.addEventListener(evType, fn, useCapture); return true;}
else if (elm.attachEvent) { var r = elm.attachEvent('on' + evType, fn); return r;}
else { elm['on' + evType] = fn;}
}
function removeEvent(obj, evType, fn, useCapture){ if (obj.removeEventListener){ obj.removeEventListener(evType, fn, useCapture); return true;} else if (obj.detachEvent){ var r = obj.detachEvent("on"+evType, fn); return r;} else { alert("Handler could not be removed");}
}
function format_colour(colour)
{ var returnColour = "#ffffff"; if(colour != "" && colour != "transparent")
{ if(colour.substr(0, 3) == "rgb")
{ returnColour = rgb2Hex(colour);}
else if(colour.length == 4)
{ returnColour = "#" + colour.substring(1, 2) + colour.substring(1, 2) + colour.substring(2, 3) + colour.substring(2, 3) + colour.substring(3, 4) + colour.substring(3, 4);}
else
{ returnColour = colour;}
}
return returnColour;}
function get_style(obj, property, propertyNS)
{ try
{ if(obj.currentStyle)
{ var returnVal = eval("obj.currentStyle." + property);}
else
{ if(isSafari && obj.style.display == "none")
{ obj.style.display = ""; var wasHidden = true;}
var returnVal = document.defaultView.getComputedStyle(obj, '').getPropertyValue(propertyNS); if(isSafari && wasHidden)
{ obj.style.display = "none";}
}
}
catch(e)
{ }
return returnVal;}
function getElementsByClass(searchClass, node, tag)
{ var classElements = new Array(); if(node == null)
node = document; if(tag == null)
tag = '*'; var els = node.getElementsByTagName(tag); var elsLen = els.length; var pattern = new RegExp("(^|\s)"+searchClass+"(\s|$)"); for (i = 0, j = 0; i < elsLen; i++)
{ if(pattern.test(els[i].className))
{ classElements[j] = els[i]; j++;}
}
return classElements;}
function newCurvyError(errorMessage)
{ return new Error("curvyCorners Error:\n" + errorMessage)
}
/**
* This class is used for the price estimation functionnalities
*
* @event Event heightModified this event is fired when the price estimation is displayed
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @param Element input the input div
* @param Element output the output div
**/
var School = Events.extend({
/**
* This is the initialization function
*/
initialize : function(schoolPriceDTO, translationsDTO, schoolContainer, listContainer, parent) {
this._parent = parent;
this._schoolContainer = schoolContainer;
this._listContainer = listContainer;
this._classNameBase = this._parent.getClassNameBase();
this._schoolPriceCalculatorDTO = schoolPriceDTO;
this._translateDTO = translationsDTO;
this.courses = new SchoolCourses(this._schoolPriceCalculatorDTO.schoolFixedDatesCourses, this._schoolPriceCalculatorDTO.schoolVariableDatesCourses, this._schoolPriceCalculatorDTO.schoolOptionalCourses,  this._translateDTO.courses, this._listContainer, this);
this.courses.getHtml().injectInside(this._schoolContainer);
this.accommodations = new SchoolAccommodations(this._schoolPriceCalculatorDTO.schoolAccommodations, this._translateDTO.accommodations, this._listContainer, this);
this.accommodations.getHtml().injectInside(this._schoolContainer);
this.transfers = new SchoolTransfers(this._schoolPriceCalculatorDTO.schoolTransfers, this._translateDTO.transfers, this);
this.transfers.getHtml().injectInside(this._schoolContainer);
this.courses.addEvent('refreshPrice', function() {
this.transfers.refreshTransfers();
this.fireEvent('refreshPrice');
}.bind(this));
this.accommodations.addEvent('refreshAccommodations', function() {
this.transfers.refreshTransfers();
this.fireEvent('refreshPrice');
}.bind(this));
this.accommodations.addEvent('refreshPrice', function() {
this.transfers.refreshTransfers();
this.fireEvent('refreshPrice');
}.bind(this));
this.transfers.addEvent('refreshPrice', function() {
this.fireEvent('refreshPrice');
}.bind(this));
this.addEvent('heightModified', function() {
this.getParent().fireEvent('heightModified');
}.bind(this));
this.addEvent('refreshAccommodations', function() {
this.accommodations.refreshAccommodations('lists');
this.transfers.refreshTransfers();
this.checkMandatoryCourseAccommodations();
});
},
getSchoolContainer : function(){
return this._schoolContainer;
},
/**
*  Return the classNameBase
*/
getClassNameBase : function() {
return this._classNameBase;
},
/**
* Returns an object containing the informations for the calculation price
*
* @return Object The informations needed to calculate the price
*/
getDTO : function() {
var priceEstimationDTO = new Object();
priceEstimationDTO.variableDatesCourses = this.courses.getVariableCoursesDTO();
priceEstimationDTO.fixedDatesCourses = this.courses.getFixedCoursesDTO();
priceEstimationDTO.optionalCourses = this.courses.getOptionalCoursesDTO();
priceEstimationDTO.accommodations = this.accommodations.getDTO();
priceEstimationDTO.transfers = this.transfers.getDTO();
return priceEstimationDTO;
},
/**
* populate the price calculator with the DTO given in parameter
*
* @param DTO toPopulateDTO the DTO to populate from
*/
populateFromDTO : function(toPopulateDTO) {
this.courses.populateCoursesFromDTO(toPopulateDTO.fixedDatesCourses, toPopulateDTO.variableDatesCourses, toPopulateDTO.optionalCourses);
this.accommodations.populateFromDTO(toPopulateDTO.accommodations);
this.transfers.populateFromDTO(toPopulateDTO.transfers);
this.courses.fireEvent("refreshCourses");
},
checkMandatoryCourseAccommodations : function(){
var validCourses = this.courses.getValidAddedCourses();
if(validCourses.length){
var mandatoryAccommodations = this.courses.getMandatoryAccommodations();
if(mandatoryAccommodations.length){
var courseToCheck = new Array();
// find which course have a problem
var accommodations = this.accommodations.getCompletedAccommodations();
for (var i = 0; i < validCourses.length; i++) {
if (validCourses[i].getCourseDetails().type != 'optional' && validCourses[i].getCourseDetails().accommodationMandatory == true) {
var courseDetails = validCourses[i].getCourseDetails();
var isOk = false;
for(var j = 0; j < accommodations.length; j++){
if(accommodations[j].getIsAttachedToCourse() && accommodations[j].getAttachedToCourse().courseId == courseDetails.id){
isOk = true;
}
}
if(!isOk){
courseToCheck.push(validCourses[i]);
}
}
}
if(courseToCheck.length){
if(courseToCheck[0].getCourseDetails().type == "variableDate"){
var durations = courseToCheck[0]._schoolDurationList.getValidListItems();
for(var i = 0; i < durations.length; i++){
if(parseInt(durations[i].getValue()) > courseToCheck[0].getCourseDuration()){
durations[i].getHtml().fireEvent('click');
break;
}
}
if(i == durations.length){
courseToCheck[0]._deleteButton.fireEvent('click');
}
}else{
courseToCheck[0]._deleteButton.fireEvent('click');
}
}
}
}
},
/**
* Return the school accommodations object
*
* @return SchoolAccommodations the school accommodations object
*/
getAccommodations : function() {
return this.accommodations;
},
/**
* Return the school course object
*
* @return SchoolCourses the school courses object
*/
getCourses : function() {
return this.courses;
},
/**
* Returns the accommodation base start date
*
* @return Date The accommodations start date
*/
getAccommodationStartDate : function() {
return this.courses.getAccommodationStartDate();
},
/**
* Returns the end date of the accommodation
*
* @return Date The end date of the accommodation
*/
getAccommodationEndDate : function() {
return this.courses.getAccommodationEndDate();
},
/**
* Return the max accommodation end date for a course
*
* @param integer courseId The Course ID
* @param Date startDate the course start date
* @param SchoolAccommodationObject accommodation The accommodation
*
* @return Date The course accommodation end date
*/
getCourseAccommodationEndDate : function(courseId, startDate, accommodation) {
var course = this.courses.getAddedCourses().filter(function(item) {
return item.getCourseDetails().id == courseId && item.getCourseStartDate().getTime() == startDate.getTime();
});
if (course.length) {
var endDate = (new Date()).fromIso(course[0].getDTO().endDate);
var endDateDay = endDate.getDay();
if (endDateDay == 0) endDateDay = 7;
while (endDateDay != accommodation.getAccommodationOptionDetails().accommodationEndDay) {
endDate.setDate(endDate.getDate() + 1);
endDateDay = endDate.getDay();
if (endDateDay == 0) endDateDay = 7;
}
return endDate;
}
return false;
},
/**
* return true if the course is a fixed one type
*
* @param String coursePosition The position of the course -1 for the last one
*/
getIsFixedDateCourse : function(coursePosition) {
var courses = this.courses.getCompletedCourses();
if (courses.length) {
switch (coursePosition) {
case -1 :
return courses.getLast().getIsFixedCourse();
break;
default :
if (courses[coursePosition]) {
return courses[coursePosition].getIsFixedCourse();
} else {
return null;
}
break;
}
}
},
/**
*  Return the courses end date
*
* @return Date the courses end date
*
*/
getCoursesEndDate : function() {
var completedCourses = this.courses.getCompletedCourses();
if (completedCourses.length) {
var endDate = completedCourses[0].getDTO().endDate;
for (var i = 0; i < completedCourses.length; i++) {
if (completedCourses[i].getDTO().endDate > endDate) {
endDate = completedCourses[0].getDTO().endDate;
}
}
return endDate;
}
return null;
},
/**
* This method returns the number of completed courses
*
* @return Number The number of courses completed
*
*/
getCompletedCourses : function() {
return this.courses.getCompletedCourses();
},
/**
*  Returns the available accommodations
*
* @return Array of integer The Accommodation IDs
*/
getAvailableAccommodations : function() {
return this.courses.getAvailableAccommodations();
},
/**
* This method returns the completed accommodations
*
* @return SchoolAccommodationObject[] The completed accommodations
*
*/
getCompletedAccommodations : function() {
return this.accommodations.getCompletedAccommodations();
},
/**
* This method returns the number of completed transfers
*
* @return Number The number of transfers completed
*
*/
getCompletedTransfers : function() {
return this.transfers.getCompletedTransfers();
},
/**
* Returns the number of participant
*
* @return Number The number of participants
*
*/
getParticipants : function() {
return this.getParent().getParticipants();
},
/**
* Return an array containing the mandatory accommodations with their start and end date
*
* @return Array of MandatoryAccommodationsDTO
*/
getMandatoryAccommodations : function() {
return this.courses.getMandatoryAccommodations();
},
/**
* Return true if the transfer is mandatory
*
* @return boolean true if the transfers are mandatory
*/
getIsTransferMandatory : function() {
return this.courses.getIsTransferMandatory();
},
/**
* Return an array containing the available transfers
*
* @return Array of transfers ID
*/
getAvailableTransfers : function() {
return this.accommodations.getAvailableTransfers();
},
/**
* This method return the list container
*
* @return Element The element containing the lists
*/
getListContainer : function() {
return this.getParent()._listContainer;
},
/**
* This function set the same height for the column
*
* @param Element column1 The first column
* @param Element column2 The second column
*/
setSameColumnSize : function(column1, column2) {
this.getParent().setSameColumnSize(column1, column2);
},
/**
* Returns the  parent
*
* @return Object the parent
*
*/
getParent : function() {
return this._parent;
},
/**
*  This method return the localized dateFormat
*
*  @return String The localized date format
*/
getDateFormat : function() {
return this.getParent().getDateFormat();
},
/**
*  This method return the localized month translations
*
*  @return String[] The localized month translations
*/
getMonthTranslations : function() {
return this._translateDTO.months;
}
});/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @event Event deleteAccommodation This event is fired when a course is deleted
*
* @param AccommodationListItemDTO accommodationDetails The object containing the accommodation informations
* @param AccommodationListItemDTO accommodationOptionDetails The object containing the accommodation options informations
* @param Object translateDTO The object containing all the translations for this class
* @param SchoolCourses parent The parent
*
**/
var SchoolAccommodationObject = Events.extend({
/**
* This is the initialization function
*/
initialize : function(accommodationDetails, accommodationOptionDetails, translateDTO, classNamePrefix, oSchoolAccommodationsContainer) {
this._created = false;
this._translateDTO = translateDTO;
this._accommodationDetails = accommodationDetails;
this._accommodationOptionDetails = accommodationOptionDetails;
this._schoolAccommodationsContainer = oSchoolAccommodationsContainer;
this._classNameBase = classNamePrefix;
this._listContainer = this._schoolAccommodationsContainer.getSchool().getListContainer();
this._dateFormat = this._schoolAccommodationsContainer.getSchool().getDateFormat();
this._monthsTranslations = this._schoolAccommodationsContainer.getSchool().getMonthTranslations();
this._validDurations = new Array();
this._additionalNightsBefore = 0;
this._additionalNightsAfter = 0;
this._accommodationStartDate = null;
this._accommodationEndDate = null;
this._accommodationDuration = null;
this._accommodationAttachedToCourse = null;
this._validStartDates = new Array();
this._calculatedStartDate = new Date();
this._calculatedEndDate = new Date();
this._manager = this._schoolAccommodationsContainer.getSchool().getParent();
this._manager.addEvent('descriptionsUpdated', function() {
this.updateDescriptions();
}.bind(this));
},
/**
* Returns an object containing the informations for the calculation price
*
* @return Object The informations needed to calculate the price
*/
getDTO : function() {
var accommodationDTO = new Object();
accommodationDTO.id = this._accommodationOptionDetails.id;
accommodationDTO.startDate = this._accommodationStartDate.toIso();
accommodationDTO.endDate = this._accommodationEndDate.toIso();
accommodationDTO.additionalNightsBefore = this._additionalNightsBefore;
accommodationDTO.additionalNightsAfter = this._additionalNightsAfter;
return accommodationDTO;
},
/**
* Return the accommodation details DTO
*
* @return AccommodationDetailsDTO The Accommodation details
*/
getAccommodationDetails : function() {
return this._accommodationDetails;
},
/**
* Populate the accommodation from the given DTO
*
*
* @param AccommodationDTO toPopulateDTO The DTO to populate from
*/
populateFromDTO : function(toPopulateDTO) {
this._accommodationEndDate = (new Date()).fromIso(toPopulateDTO.endDate);
this._accommodationStartDate = (new Date()).fromIso(toPopulateDTO.startDate);
this._additionalNightsBefore = toPopulateDTO.additionalNightsBefore ? parseInt(toPopulateDTO.additionalNightsBefore) : 0;
this._additionalNightsAfter = toPopulateDTO.additionalNightsAfter ? parseInt(toPopulateDTO.additionalNightsAfter) : 0;
this.updateStartDateLabel();
this._accommodationDuration = Math.round((this._accommodationEndDate - this._accommodationStartDate) / (1000 * 60 * 60 * 24 * 7));
if (this._accommodationDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace('%0', this._accommodationDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._accommodationDuration));
}
this._accommodationEndDate = this.getCalculatedEndDate();
this.updateEndDateLabel();
},
getAvailableDaysBefore : function() {
if(this._accommodationOptionDetails.additionalNightsOnBounds){
var accommodations = this._schoolAccommodationsContainer.getAccommodations();
if(accommodations.length > 1 && accommodations.indexOf(this) != 0){
return 0;
}
}
return this._accommodationOptionDetails.additionalNightsBefore;
},
getAvailableDaysAfter : function() {
if(this._accommodationOptionDetails.additionalNightsOnBounds){
var accommodations = this._schoolAccommodationsContainer.getAccommodations();
if(accommodations.length > 1 && accommodations.getLast() != this){
return 0;
}
}
return this._accommodationOptionDetails.additionalNightsAfter;
},
/**
* set The accommodations start date for the given accommodation
*
* @param Date startDate The Start date
*/
setAttachedAccommodationStartDate : function(startDate) {
this._accommodationStartDate = startDate;
this.updateStartDateLabel();
},
/**
* set The accommodations duration for the given accommodation
*
* @param integer duration The duration
*/
setAttachedAccommodationDuration : function(duration) {
this._accommodationDuration = duration;
if (this._accommodationDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace('%0', this._accommodationDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._accommodationDuration));
}
this._accommodationEndDate = this.getCalculatedEndDate();
this.updateEndDateLabel();
},
/**
* Generate the html structure of the accommodation
*/
createVisualAccommodation : function(attachedAccommodation) {
if(!this._created){
this._container = new Element('div', {'class': this._classNameBase + 'ItemAdded'});
this._title = new Element('div', {'class': this._classNameBase + 'Section-Item-Title'});
this._subTitle = new Element('div', {'class': this._classNameBase + 'Section-Item-SubTitle'});
this._moreInfo = new Element('div', {'class': this._classNameBase + 'Section-Item-SubTitle MoreInfos'});
this._moreInfo.setStyle('display','none');
this._startDateContainer = new Element('div', {'class': this._classNameBase + 'Section-Item-StartDate-Container'});
this._endDateContainer = new Element('div', {'class': this._classNameBase + 'Section-Item-EndDate-Container'});
this._startDate = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._startDateValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Value ' + this._classNameBase + 'Section-Item-ToUpdate'});
this._endDate = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._endDateValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Value'});
this._durationContainer = new Element('div', {'class': this._classNameBase + 'Section-Item-Duration-Container'});
this._duration = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._durationValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Value ' + this._classNameBase + 'Section-Item-ToUpdate'});
this._deleteButton = new Element('div', {'class': this._classNameBase + 'Section-Item-DeleteButton'});
this._duration.injectInside(this._durationContainer);
this._durationValue.injectInside(this._durationContainer);
this._startDate.injectInside(this._startDateContainer);
this._startDateValue.injectInside(this._startDateContainer);
this._endDate.injectInside(this._endDateContainer);
this._endDateValue.injectInside(this._endDateContainer);
this._title.injectInside(this._container);
this._moreInfo.injectInside(this._container);
this._subTitle.injectInside(this._container);
var element = new Element('div').injectInside(this._container);
element.setStyle('clear','both');
this._startDateContainer.injectInside(this._container);
this._endDateContainer.injectInside(this._container);
this._durationContainer.injectInside(this._container);
this._deleteButton.injectInside(this._container);
var element = new Element('div',{'style':'clear:both'}).injectInside(this._container);
element.setStyle('clear','both');
this._title.setHTML(this._accommodationDetails.name);
if(this._accommodationOptionDetails.noAccommodation){
this._subTitle.setStyle('display','none');
}else{
this._subTitle.removeAttribute('style');
}
this._subTitle.setHTML(this._accommodationOptionDetails.name);
this._moreInfo.setHTML(this._translateDTO.moreInfos);
this._startDate.setHTML(this._translateDTO.startDate);
this.updateStartDateLabel();
this._endDate.setHTML(this._translateDTO.endDate);
this.updateEndDateLabel();
this._duration.setHTML(this._translateDTO.duration);
this._durationValue.setHTML(this._translateDTO.durationSelect);
this._deleteButton.setHTML(this._translateDTO.deleteButton);
// add event listener
this._deleteButton.addEvent('click', function(e) {
this.removeAccommodation();
this.fireEvent('deleteAccommodation');
}.bind(this));
this.updateDescriptions();
this._accommodationOptionsList = new SchoolList(this._title, this._classNameBase);
this._accommodationDurationsList = new SchoolList(this._durationValue, this._classNameBase);
this.getVisualAccommodation(this._accommodationOptionsList);
this._accommodationOptionsList.getHtml().injectInside(this._listContainer);
this._accommodationOptionsList.initializeEvents();
this._startDateValue.addEvent('click', function(){
if(!this._startDateValue.hasClass(this._classNameBase + 'Section-Item-Info-ValueNotEditable')){
this._schoolAccommodationsContainer.getCalendar().setValidDates(this.getValidStartDates(), this.getAvailableDaysBefore() , 0, this._accommodationOptionDetails.additionalNightsOnBounds);
if (this._accommodationStartDate) {
this._schoolAccommodationsContainer.getCalendar().setSelectedDate(this._accommodationStartDate, this._additionalNightsBefore, 0);
}
else {
if (this.getValidStartDates().length)
this._schoolAccommodationsContainer.getCalendar().displayMonths(this.getValidStartDates()[0].getMonth(), this.getValidStartDates()[0].getFullYear());
}
this._schoolAccommodationsContainer.getCalendar().show(this._startDateValue);
}
}.bind(this));
this._startDateValue.addEvent('dateselected', function(date){
this._additionalNightsBefore = date.additionalNightsBefore;
if(date.relativeDate < this._accommodationEndDate){
this.refreshAccommodationData(date.relativeDate, null, this._accommodationEndDate);
}else {
this.refreshAccommodationData(date.relativeDate, this._accommodationDuration, null);
}
}.bind(this));
this._endDateValue.addEvent('click', function(){
this._schoolAccommodationsContainer.getCalendar().setValidDates(this.getValidEndDates(),0, this.getAvailableDaysAfter(), this._accommodationOptionDetails.additionalNightsOnBounds);
if(this._accommodationEndDate){
this._schoolAccommodationsContainer.getCalendar().setSelectedDate(this._accommodationEndDate, 0, this._additionalNightsAfter);
}else {
if(this.getValidEndDates().length)
this._schoolAccommodationsContainer.getCalendar().displayMonths(this.getValidEndDates()[0].getMonth(), this.getValidEndDates()[0].getFullYear());
}
this._schoolAccommodationsContainer.getCalendar().show(this._endDateValue);
}.bind(this));
this._endDateValue.addEvent('dateselected', function(date){
this._additionalNightsAfter = date.additionalNightsAfter;
this.refreshAccommodationData(this._accommodationStartDate, null , date.relativeDate);
}.bind(this));
this.refreshValidStartDates();
this.getVisualDurations(this._accommodationDurationsList);
this._accommodationDurationsList.getHtml().injectInside(this._listContainer);
this._accommodationDurationsList.initializeEvents();
this._created = true;
// if it is the first to be added, set the right date
if (this._schoolAccommodationsContainer.getAccommodations().length == 1 && !attachedAccommodation) {
// find the earliest start date
var startDate;
if(this._validStartDates.length){
startDate = this._validStartDates[0];
}
if (startDate) {
this._accommodationStartDate = startDate;
this.refreshVisualDurations(this._accommodationDurationsList);
// find the longest duration
var duration;
for (var i = this._accommodationDurationsList.getListItems().length - 1; i >= 0; i--) {
var listItem = this._accommodationDurationsList.getListItems()[i];
if (listItem.getIsSelectionnable()) {
duration = parseInt(listItem.getValue());
break;
}
}
if (duration) {
this._accommodationStartDate = null;
this.refreshAccommodationData(startDate, duration, null);
}
}
}
}
},
/**
* Update the descriptions
*/
updateDescriptions : function(){
if (this._manager.getDescription && this._manager.getDescription('accommodation', this._accommodationDetails.accommodationType) && this._manager.getDescription('accommodation', this._accommodationDetails.accommodationType) != '') {
this._moreInfo.setAttribute('title', this._accommodationDetails.name + ' :: ' + this._manager.getDescription('accommodation', this._accommodationDetails.accommodationType));
this._moreInfo.setStyle('display','');
if(!this._descriptionToolTip ){
this._descriptionToolTip = new SynergeeTips(this._moreInfo, {'className':'PriceEstimationToolTip', 'hideDelay':1000, 'fixed':true, 'closeButton':true, 'maxHeight':280});
}else {
this._descriptionToolTip.build(this._moreInfo);
}
}else {
if(this._moreInfo)
this._moreInfo.setStyle('display','none');
}
},
/**
* Returns the html view of this accommodation
*
* @return Element the html view of this accommodation
*/
getHtml : function() {
return this._container;
},
/**
* Generate the list for the possible durations of this accommodation
*
* @param SchoolList The duration list
*/
getVisualDurations : function(list) {
list.clear();
var index = 0;
var durations = this.getDurations();
durations.each(function(item, index) {
list.addItem(item, this._translateDTO.weeks.replace('%0', item));
index = list.getListItems().indexOf(list.getListItems().getLast());
list.getListItems().getLast().getHtml().addEvent('click', function(e) {
if (list.getListItems()[index].getIsSelectionnable())this.refreshAccommodationData(this._accommodationStartDate, item, this._accommodationEndDate);
}.bind(this));
}.bind(this));
this.refreshVisualDurations(list);
},
/**
* Refresh the list for the possible durations of this accommodation
*
* @param SchoolList The duration list
*/
refreshVisualDurations : function(list) {
var firstValid = true;
this._validDurations = this._schoolAccommodationsContainer.getAccommodationValidDuration(this, list);
list.getListItems().each(function(item, index) {
if (this._validDurations.contains(parseInt(item.getValue()))) {
item.setIsValid(true);
item.setIsSelectionnable(true);
if (firstValid)list.setSelectedItem(item);
if (this._accommodationDuration == item.getValue()) {
list.setSelectedItem(item);
}
firstValid = false;
} else {
if (item.getValue == 'error')item.setIsValid(false);
item.setIsSelectionnable(false);
}
}.bind(this));
},
/**
* Refresh the list of possible startdates
*
* @param Array list The list of possible startdates
*/
refreshValidStartDates :  function(){
this._validStartDates = this._schoolAccommodationsContainer.getAccommodationValidStartDates(this);
},
/**
* Generate the accommodations list
*
* @param SchoolList list The list we want to refresh
*
*/
getVisualAccommodation : function(list) {
list.clear();
// Get the school accommodations informations to create the list
this._schoolAccommodationsContainer.getSchoolAccommodationsDTO().each(function(SectionItem, index) {
var section = SectionItem;
var sectionId = parseInt(SectionItem.id);
var value = new Object();
value.type = 'category';
value.sectionId = sectionId;
list.addItem(value, SectionItem.name);
list.getListItems().getLast().getHtml().addClass(this._classNameBase + 'List-Item-Category');
// for each accommodation options in the accommodation section
SectionItem.option.each(function(item, index) {
item.parentId = sectionId;
list.addItem(item, item.name);
list.getListItems().getLast().getHtml().addClass(this._classNameBase + 'List-Item-Accommodation');
// add the event on the option button
list.getListItems().getLast().getHtml().addEvent('click', function(e) {
this.setAccommodation(section, item);
}.bind(this));
}.bind(this));
}.bind(this));
list.addItem('error', this._translateDTO.notAvailable);
if (this._schoolAccommodationsContainer.getSchool().getCompletedCourses().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
this.refreshVisualAccommodation(list);
},
/**
* Refresh the accommodations list
*
* @param SchoolList list The list we want to refresh
*
*/
refreshVisualAccommodation : function(list) {
var availableAccommodations = this._schoolAccommodationsContainer.getAvailableAccommodations();
var accommodationStartDates = this.createStartDatesList();
var accommodationEndDate = this._schoolAccommodationsContainer.getAccommodationEndDate();
list.getListItems().each(function(item, index) {
var available =  true;
// check the availability for this accommodation
if(accommodationStartDates[0] && accommodationEndDate && item.getValue().availabilities && item.getValue().availabilities.length){
var availabilities = item.getValue().availabilities;
var startDateVar = new Date(accommodationStartDates[0].getTime() + 86400 * 2 * 1000);
var endDateVar = new Date(accommodationEndDate.getTime() - 86400 *  2 * 1000);
var startWeek = startDateVar.getWeek();
var startYear = startDateVar.getFullYear();
var endWeek = endDateVar.getWeek();
var duration  = this._schoolAccommodationsContainer.getDurationInWeeks(accommodationEndDate, accommodationStartDates[0]);
available = false;
if (startWeek == endWeek) {
if (availabilities[startYear + '' + startWeek] == undefined) {
available = true;
}
} else {
var i = 0;
while (duration > 0 && startWeek != endWeek && !available) {
if (availabilities[startYear + '' + startWeek] == undefined) {
available = true;
}
if (startWeek == 52) {
startWeek = 1;
startYear++;
} else {
startWeek++;
}
duration--;
}
}
}
if (availableAccommodations.contains(item.getValue().parentId) && this._schoolAccommodationsContainer.getDurationInWeeks(accommodationEndDate, accommodationStartDates[0]) >= item.getValue().minimumDurationInWeeks
&& this._schoolAccommodationsContainer.getSchool().getParticipants() >= item.getValue().minimumNumberOfPeople) {
item.setIsValid(true);
item.setIsSelectionnable(available);
} else {
if (!availableAccommodations.contains(item.getValue().sectionId) || item.getValue().type != 'category' || this._schoolAccommodationsContainer.getSchool().getCompletedCourses().length == 0) {
item.setIsValid(false);
} else {
item.setIsValid(true);
}
}
}.bind(this));
if (this._schoolAccommodationsContainer.getSchool().getCompletedCourses().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* Replace an accommodation with another one
*
* @param Object accommodation The new accommodation DTO
* @param Object accommodationOption The new accommodation options DTO
*/
setAccommodation : function(accommodationSection, accommodationOption) {
// set the new accommodation informations
this._accommodationDetails = accommodationSection;
this._accommodationOptionDetails = accommodationOption;
if(this._additionalNightsBefore >  this._accommodationOptionDetails.additionalNightsBefore){
this._additionalNightsBefore = this._accommodationOptionDetails.additionalNightsBefore;
}
if(this._additionalNightsAfter >  this._accommodationOptionDetails._additionalNightsAfter){
this._additionalNightsAfter = this._accommodationOptionDetails._additionalNightsAfter;
}
// set the new title and subtitle
this._title.setHTML(this._accommodationDetails.name);
this._subTitle.setHTML(this._accommodationOptionDetails.name);
if(this._accommodationOptionDetails.noAccommodation){
this._subTitle.setStyle('display','none');
}else{
this._subTitle.removeAttribute('style');
}
this._title.removeEvents('click');
this._durationValue.removeEvents('click');
this._accommodationOptionsList.deleteList();
this._accommodationDurationsList.deleteList();
this.updateDescriptions();
this.updateStartDateLabel();
this._title.removeEvents();
this._durationValue.removeEvents();
this._accommodationOptionsList = new SchoolList(this._title, this._classNameBase);
this._accommodationDurationsList = new SchoolList(this._durationValue, this._classNameBase);
this.getVisualAccommodation(this._accommodationOptionsList);
this._accommodationOptionsList.getHtml().injectInside(this._listContainer);
this._accommodationOptionsList.initializeEvents();
this.refreshValidStartDates();
if(!this._accommodationOptionDetails.additionalNightsOnBounds && this._accommodationStartDate.getTime() != this._validStartDates[0].getTime()){
this._additionalNightsBefore = 0;
}
this.getVisualDurations(this._accommodationDurationsList);
this._accommodationDurationsList.getHtml().injectInside(this._listContainer);
this._accommodationDurationsList.initializeEvents();
if(!this._accommodationOptionDetails.additionalNightsOnBounds && this._accommodationDuration != this._validDurations.getLast()){
this._additionalNightsAfter = 0;
}
this.refreshAccommodationLists();
this.updateStartDateLabel();
this.updateEndDateLabel();
// we ask the parent to check if the other accommodations are ok
this._schoolAccommodationsContainer.checkAccommodations(this);
// and the fireAnEvent to the parent to refresh the accommodations
this._schoolAccommodationsContainer.fireEvent('refreshAccommodations');
},
/**
* Refresh the accommodation data and the visual of the accommodation
*
* @param Date startDate The new StartDate
* @param Number duration The new Duration
* @param Date endDate The new endDate
*
*/
refreshAccommodationData : function(startDate, duration, endDate) {
if(startDate && endDate && !duration){
this._accommodationStartDate = startDate;
this._accommodationEndDate = endDate;
this._accommodationDuration = this._schoolAccommodationsContainer.getDurationInWeeks( endDate , startDate);
} else {
// if the endDate is modified and the startDate has to be calculated
if (startDate == this._accommodationStartDate && endDate != this._accommodationEndDate) {
this._accommodationDuration = duration;
this._accommodationEndDate = endDate;
// calculation of the new startDate
var startDateIndex = 0;
var startDates = this.getStartDates();
startDates.filter(function(item, index) {
if (item.toString() == this._accommodationEndDate.toString()) {
startDateIndex = index;
return index;
}
}.bind(this));
startDateIndex = startDateIndex - this._accommodationDuration;
if (startDateIndex < 0) startDateIndex = 0;
this._accommodationStartDate = startDates[startDateIndex];
} else {
// If the startDate and the duration are modified, the endDate has to be calculated
if (startDate != this._accommodationStartDate && duration != this._accommodationDuration) {
this._accommodationStartDate = startDate;
this._accommodationDuration = duration;
this._accommodationEndDate = this.getCalculatedEndDate();
// else if there is only the startDate modified
} else {
if (startDate != this._accommodationStartDate) {
this._accommodationStartDate = startDate;
// if it is a new accommodation with no data, these are set based on the previous accommodation
if (this._accommodationDuration == null) {
var startDate = new Date(this._accommodationStartDate).setDate(this._accommodationStartDate.getDate() + this._accommodationOptionDetails.minimumDurationInWeeks * 7);
// if the accommodationstart + minimum weeks date is before the previous end date
if (startDate < this._schoolAccommodationsContainer.getPreviousEndDate(this)) {
this._accommodationEndDate = this._schoolAccommodationsContainer.getPreviousEndDate(this);
} else {
this._accommodationEndDate = this.getEndDate();
}
// the duration is calculated
this._accommodationDuration = this._schoolAccommodationsContainer.getDurationInWeeks(this._accommodationEndDate, this._accommodationStartDate);
} else {
// else (the course is already complete) the end date is calculated normally
this._accommodationEndDate = this.getCalculatedEndDate();
}
} else {
// or only the duration
if (duration != this._accommodationDuration) {
this._accommodationDuration = duration;
this._accommodationEndDate = this.getCalculatedEndDate();
}
}
}
}
}
if(this._accommodationStartDate){
this.updateStartDateLabel();
}
if (this._accommodationDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace('%0', this._accommodationDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._accommodationDuration));
}
if(this._accommodationEndDate){
this.updateEndDateLabel();
}
// the parent is asked to check if the other accommodations are ok
this._schoolAccommodationsContainer.checkAccommodations(this);
if(this._startDate)  this._startDateValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
if(this._duration)  this._durationValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
// and the fireAnEvent to the parent to refresh the accommodations
if(this._created)this._schoolAccommodationsContainer.fireEvent('refreshAccommodations');
},
/**
* Update the start date label
*/
updateStartDateLabel : function () {
if (this._additionalNightsBefore && !this.getAvailableDaysBefore()) {
this._additionalNightsBefore = 0;
}
if (this._accommodationStartDate) {
this._calculatedStartDate.setYear(this._accommodationStartDate.getFullYear());
this._calculatedStartDate.setMonth(this._accommodationStartDate.getMonth());
this._calculatedStartDate.setDate(this._accommodationStartDate.getDate());
this._calculatedStartDate.setDate(this._calculatedStartDate.getDate() - this._additionalNightsBefore);
this._startDateValue.setHTML(this._calculatedStartDate.format(this._dateFormat, this._monthsTranslations));
} else {
this._startDateValue.setHTML(this._translateDTO.dateSelect);
}
},
/**
* Update the end date label
*/
updateEndDateLabel : function () {
if (this._additionalNightsAfter && !this.getAvailableDaysAfter()) {
this._additionalNightsAfter = 0;
}
if (this._accommodationEndDate) {
this._calculatedEndDate.setYear(this._accommodationEndDate.getFullYear());
this._calculatedEndDate.setMonth(this._accommodationEndDate.getMonth());
this._calculatedEndDate.setDate(this._accommodationEndDate.getDate());
this._calculatedEndDate.setDate(this._accommodationEndDate.getDate() + this._additionalNightsAfter);
this._endDateValue.setHTML(this._calculatedEndDate.format(this._dateFormat, this._monthsTranslations));
}   else {
this._endDateValue.setHTML(this._translateDTO.endDateValue);
}
},
/**
* Refresh the lists for this accommodation
*/
refreshAccommodationLists : function() {
this.refreshVisualAccommodation(this._accommodationOptionsList);
this.refreshValidStartDates();
this.refreshVisualDurations(this._accommodationDurationsList);
if (this.getValidStartDates().length) {
// check if the buttons must be activated or not
if (this.getValidStartDates().length == 1 && this.getIsAttachedToCourse()) {
this._startDateValue.addClass(this._classNameBase + 'Section-Item-Info-ValueNotEditable');
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-Info-Value');
if (this._accommodationStartDate != this.getValidStartDates()[0]){
this.refreshAccommodationData(this.getValidStartDates()[0], null, this._accommodationEndDate);
}
} else {
this._startDateValue.addClass(this._classNameBase + 'Section-Item-Info-Value');
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-Info-ValueNotEditable');
}
if (this._accommodationDurationsList.getValidListItems().length == 1) {
this._durationValue.addClass(this._classNameBase + 'Section-Item-Info-ValueNotEditable');
this._durationValue.removeClass(this._classNameBase + 'Section-Item-Info-Value');
this._accommodationDurationsList.removeButtonEvent();
if (parseInt(this._accommodationDuration) != parseInt(this._accommodationDurationsList.getValidListItems()[0].getValue()))this._accommodationDurationsList.getValidListItems()[0].getHtml().fireEvent('click');
} else {
this._durationValue.addClass(this._classNameBase + 'Section-Item-Info-Value');
this._durationValue.removeClass(this._classNameBase + 'Section-Item-Info-ValueNotEditable');
this._accommodationDurationsList.addButtonEvent();
}
}else {
// there is no valid start date
this.removeAccommodation();
this.fireEvent('deleteAccommodation');
}
},
/**
* Delete and generate the lists for this accommodation
*
*/
reGenerateAccommodationLists : function() {
if (this._accommodationDurationsList._listItems.length) {
this._accommodationDurationsList.getHtml().remove();
this._accommodationDurationsList.clear();
}
if (this._accommodationOptionsList._listItems.length) {
this._accommodationOptionsList.getHtml().remove();
this._accommodationOptionsList.clear();
}
this.getVisualAccommodation(this._accommodationOptionsList);
this._accommodationOptionsList.getHtml().injectInside(this._listContainer);
this._accommodationOptionsList.initializeEvents();
this.refreshValidStartDates();
this.getVisualDurations(this._accommodationDurationsList);
this._accommodationDurationsList.getHtml().injectInside(this._listContainer);
if (!this.getIsAttachedToCourse()) {
this._accommodationDurationsList.initializeEvents();
}
},
/**
* Returns an array of startDates
*
* @return Array An array of Dates
*/
getStartDates : function() {
var startDates = this.createStartDatesList();
return startDates;
},
/**
* Generate the start dates list
*/
createStartDatesList : function() {
var startDatesList = new Array();
var startDate = this._schoolAccommodationsContainer.getSchool().getAccommodationStartDate();
var endDate = this._schoolAccommodationsContainer.getSchool().getAccommodationEndDate();
if(!startDate) return startDatesList;
// if the first course is not a fixed one
if (!this._schoolAccommodationsContainer.getSchool().getIsFixedDateCourse(0)) {
var day = startDate.getDay();
if (day == 0)day = 7;
if (this.getAccommodationOptionDetails().accommodationStartDay > 0) {
while (this.getAccommodationOptionDetails().accommodationStartDay != day) {
startDate.setDate(startDate.getDate() - 1);
day = startDate.getDay();
if (day == 0)day = 7;
}
}
}
// if the last course is not a fixed one
if (!this._schoolAccommodationsContainer.getSchool().getIsFixedDateCourse(-1)) {
var endDateDay = endDate.getDay();
if (endDateDay == 0) endDateDay = 7;
if (this.getAccommodationOptionDetails().accommodationEndDay > 0) {
while (endDateDay != this.getAccommodationOptionDetails().accommodationEndDay) {
endDate.setDate(endDate.getDate() + 1);
endDateDay = endDate.getDay();
if (endDateDay == 0) endDateDay = 7;
}
}
endDate.setDate(endDate.getDate() - 7* this.getAccommodationOptionDetails().minimumDurationInWeeks + 3);
}
while (startDate < endDate) {
startDatesList.push(new Date(startDate));
startDate.setDate(startDate.getDate() + 7);
}
return startDatesList;
},
/**
* Returns the endDate
*
* @return Date The end date
*/
getEndDate : function() {
var endDate = this._schoolAccommodationsContainer.getAccommodationEndDate(this);
var endDay = parseInt(this.getAccommodationOptionDetails().accommodationEndDay);
if(endDay == 7)endDay = 0;
while(endDay != endDate.getDay()){
endDate.setDate(endDate.getDate() + 1);
}
return endDate;
},
/**
* Returns the possible durations
*
* @return Array An array of possible durations
*/
getDurations : function() {
var durations = new Array();
var minDuration = parseInt(this.getAccommodationOptionDetails().minimumDurationInWeeks);
var maxDuration = this._schoolAccommodationsContainer.getDurationInWeeks(this.getEndDate(), this.getValidStartDates()[0]);
for (var i = minDuration; i <= maxDuration; i++) {
durations.push(i);
}
return durations;
},
/**
* Return the endDate for an accommodation with its startDate and duration
*
* @return Date The accommodation end date.
*/
getCalculatedEndDate : function() {
var endDate = new Date(this._accommodationStartDate);
endDate.setDate(endDate.getDate() - 3 + this._accommodationDuration * 7);
var endDay = parseInt(this.getAccommodationOptionDetails().accommodationEndDay);
if(endDay == 7)endDay = 0;
while(endDay != endDate.getDay()){
endDate.setDate(endDate.getDate() + 1);
}
if (endDate > this.getEndDate()) {
endDate = this.getEndDate();
this._accommodationEndDate = endDate;
this._accommodationDuration = this._schoolAccommodationsContainer.getDurationInWeeks(this._accommodationEndDate, this._accommodationStartDate);
if (this._accommodationDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace('%0', this._accommodationDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._accommodationDuration));
}
}
if(this._additionalNightsAfter && !this.getAvailableDaysAfter()){
this._additionalNightsAfter = 0;
}
return endDate;
},
/**
* Returns true if all the accommodation informations are complete
*
* @return Boolean Return true if all the accommodation informations are completed
*/
isComplete : function() {
if (this._accommodationDuration && this._accommodationStartDate && this._accommodationEndDate) {
return true;
} else {
return false;
}
},
/**
* Returns the accommodation Start date
*
* @return Date The accommodation start date
*/
getAccommodationStartDate : function() {
return this._accommodationStartDate;
},
/**
* Returns the accommodation end date
*
* @return Date The accommodation end date
*/
getAccommodationEndDate : function() {
return this._accommodationEndDate;
},
/**
* Returns the accommodation duration
*
* @return Number The accommodation duration
*/
getAccommodationDuration : function() {
return this._accommodationDuration;
},
/**
* Returns an object containing the accommodation option details
*
* @return object The accommodation option details
*/
getAccommodationOptionDetails : function() {
return this._accommodationOptionDetails;
},
/**
* set the accommodations attached to a course
*
* @param isAttached CourseDetailDTO The course to attach to
*/
setIsAttachedToCourse : function(isAttached) {
this._accommodationAttached = isAttached;
if (this._accommodationAttached) {
this._deleteButton.setStyle('display', 'none');
//            if (this._accommodationStartDatesList.getButtonEventInitialized()) {
//                this._accommodationStartDatesList.removeButtonEvent();
//            }
if (this._accommodationDurationsList.getButtonEventInitialized()) {
this._accommodationDurationsList.removeButtonEvent();
}
this._startDateValue.setAttribute('class', this._classNameBase + 'Section-Item-Info-ValueNotEditable');
this._durationValue.setAttribute('class', this._classNameBase + 'Section-Item-Info-ValueNotEditable');
} else {
this._deleteButton.setStyle('display', 'block');
//            if (!this._accommodationStartDatesList.getButtonEventInitialized()) {
//                this._accommodationStartDatesList.addButtonEvent();
//            }
if (!this._accommodationDurationsList.getButtonEventInitialized()) {
this._accommodationDurationsList.addButtonEvent();
}
this._startDateValue.setAttribute('class', this._classNameBase + 'Section-Item-Info-Value');
this._durationValue.setAttribute('class', this._classNameBase + 'Section-Item-Info-Value');
}
},
/**
* set the accommodations attached to a course
*
* @param course CourseDetailDTO The course to attach to
*/
setAttachedToCourse : function(course) {
this._accommodationAttachedToCourse = course;
},
/**
* set the accommodations attached to a course
*
* @return CourseDetailDTO The course details attached to this accommodation
*/
getAttachedToCourse : function() {
return this._accommodationAttachedToCourse;
},
/**
* set the accommodations attached to a course
*
* @return CourseDetailDTO The course details attached to this accommodation
*/
getIsAttachedToCourse : function() {
return this._accommodationAttached;
},
/**
* return the valid start dates for this accommodation
*
* @return Array of valid start dates
*/
getValidStartDates : function() {
return this._validStartDates;
},
/**
* return the valid start dates for this accommodation
*
* @return Array of valid start dates
*/
getValidEndDates : function() {
var validEndDates = new Array();
var endDate = new Date(this._accommodationStartDate);
endDate.setDate(endDate.getDate() - 3 + this._validDurations[0] * 7);
var endDay = parseInt(this.getAccommodationOptionDetails().accommodationEndDay);
if(endDay == 7)endDay = 0;
while(endDay != endDate.getDay()){
endDate.setDate(endDate.getDate() + 1);
}
validEndDates.push(endDate);
var endDateTime = endDate.getTime();
var week = 86000 * 1000 * 7;
this._validDurations.each(function(item, index) {
// we already added the first end date
if (index > 0) {
endDateTime += week;
var date = new Date(endDate);
date.setDate(date.getDate() + (7 * index));
validEndDates.push(date);
}
}.bind(this));
return validEndDates;
},
/**
* Returns the parent
*
* @return SchoolAccommodations The parent
*/
getParent : function() {
return this._schoolAccommodationsContainer;
},
/**
* Remove the accommodation from the list
*/
removeAccommodation : function() {
this._accommodationDurationsList.deleteList();
if(this._container.getParent())this._container.remove();
}
});/**
* This class is used for the price estimation functionnalities
*
* @author Yves-Andrï¿½ Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
*
* @param AccommodationListItemDTO schoolAccommodationsDTO The DTO containing all the accommodations informations
* @param Object translateDTO The DTO containing all the translations for this class
* @param Element eListContainer The list container
* @param School oSchool The school
**/
var SchoolAccommodations = Events.extend({
/**
* This is the initialization function
*/
initialize : function(schoolAccommodationsDTO, translateDTO, eListContainer, oSchool) {
this._schoolAccommodationsDTO = schoolAccommodationsDTO;
this._translateDTO = translateDTO;
this._accommodations = new Array();
this._school = oSchool;
this._listContainer = eListContainer;
this._classNameBase = this._school.getClassNameBase();
this._calendar = new BookingCalendar({
days: this._school._translateDTO.days, // days of the week starting at sunday
months: this._school._translateDTO.months,
offset: this._school._translateDTO.firstDayOfWeek
});
this._calendar.addEvent('dateselected', function(e){
this._calendar.getLinkedElement().fireEvent('dateselected', this._calendar.getSelectedDate());
this._calendar.hide();
}.bind(this));
this.addEvent('refreshAccommodations', function(item, index) {
this.refreshAccommodations();
}.bind(this));
},
getCalendar : function(){
return this._calendar;
},
/**
* Returns an object containing the informations for the calculation price
*
* @return Array The informations needed to calculate the price
*/
getDTO : function() {
var accommodationsDTO = new Array();
this._accommodations.each(function(item, index) {
if (item.isComplete()) {
accommodationsDTO.push(item.getDTO());
}
});
return accommodationsDTO;
},
/**
* Populate the accommodation from a dto
*
* @param Array toPopulateDTO The accommodations to add
*/
populateFromDTO : function(toPopulateDTO) {
var accommodations = new Array();
if (toPopulateDTO) {
toPopulateDTO.each(function(item, index) {
// check
this._schoolAccommodationsDTO.each(function(accommodationItem, accommodationIndex) {
var accommodationToAdd = accommodationItem.option.filter(function(optionItem, optionIndex) {
return optionItem.id == item.id;
});
if (accommodationToAdd[0]) {
accommodationToAdd[0].parentId = accommodationItem.id;
accommodationToAdd[0].dto = item;
accommodations.push(accommodationToAdd[0]);
}
}.bind(this));
}.bind(this));
}
if (accommodations.length) {
for (var i = 0; i < accommodations.length; i++) {
this.addAccommodation(accommodations[i].parentId, accommodations[i].id);
if (this._accommodations.length)this._accommodations.getLast().populateFromDTO(accommodations[i].dto);
}
}
},
/**
*  Return the classNameBase
*/
getClassNameBase : function() {
return this._classNameBase;
},
/**
* Returns the visual accommodation container
*/
getHtml : function() {
this._accommodationContainer = new Element('div', {'class': this._classNameBase + 'Section' + ' ' + this._classNameBase2 + 'Section'});
this._accommodationTitle = new Element('div', {'class': this._classNameBase + 'Section-Title' + ' ' + this._classNameBase2 + 'Section-Title'});
this._accommodationListContainer = new Element('div', {'class': this._classNameBase + 'Courses-CoursesList-Container' + ' ' + this._classNameBase2 + 'Courses-CoursesList-Container'});
this._accommodationUserAccommodationList = new Element('div', {'class': this._classNameBase + 'Courses-UserCoursesList' + ' ' + this._classNameBase2 + 'Courses-UserCoursesList'});
this._accommodationAddButton = new Element('div', {'class': this._classNameBase + 'AddButton' + ' ' + this._classNameBase2 + 'AddButton'});
this._accommodationTitle.injectInside(this._accommodationContainer);
this._accommodationListContainer.injectInside(this._accommodationContainer);
this._accommodationUserAccommodationList.injectInside(this._accommodationListContainer);
this._accommodationAddButton.injectInside(this._accommodationContainer);
this._accommodationTitle.setHTML(this._translateDTO.title);
this._accommodationAddButton.setHTML(this._translateDTO.add);
this.accommodationsList = new SchoolList(this._accommodationAddButton, this._classNameBase);
this.getVisualAccommodationList(this.accommodationsList, this.addAccommodationEventFunction);
this.refreshVisualAccommodationList(this.accommodationsList);
this.accommodationsList.getHtml().injectInside(this._listContainer);
this.accommodationsList.initializeEvents();
var displayAccommodations = false;
for(var i = 0; i < this._schoolAccommodationsDTO.length; i++){
if(this._schoolAccommodationsDTO[i].option.length){
displayAccommodations = true;
}
}
if(!displayAccommodations){
this._accommodationContainer.setStyle('display', 'none');
}
return this._accommodationContainer;
},
/**
* Generate the accommodation list
*
* @param SchoolList list The list to refresh
*
*/
getVisualAccommodationList : function(list, eventFunction, context) {
if(!context) context = this;
// clearing the list
list.clear();
this._schoolAccommodationsDTO.each(function(item, index) {
var sectionId = parseInt(item.id);
var value = new Object();
value.type = 'category';
value.sectionId = sectionId;
list.addItem(value, item.name);
list.getListItems().getLast().getHtml().addClass(this._classNameBase + 'List-Item-Category');
list.getListItems().getLast().getHtml().addClass(this._classNameBase2 + 'List-Item-Category');
item.option.each(function(item, index) {
item.parentId = sectionId;
var listItem = new SchoolListItem(item, item.name, this._classNameBase);
list.addListItem(listItem);
listItem.getHtml().addClass(this._classNameBase + 'List-Item-Accommodation');
listItem.getHtml().addClass(this._classNameBase2 + 'List-Item-Accommodation');
listItem.getHtml().addEvent('click', eventFunction.bind(context));
}.bind(this));
}.bind(this));
list.addItem('error', this._translateDTO.notAvailable);
if (this.getCompletedCourses().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
addAccommodationEventFunction : function(e){
e = new Event(e);
var listItem = e.target.listItemContainer;
if (listItem.getIsSelectionnable()) {
this.addAccommodation(listItem.getValue().parentId, listItem.getValue().id);
this._school.fireEvent('heightModified');
// refresh the accommodation, but not the shopping cart result price
this.refreshAccommodations(null, true);
}
},
/**
* Refresh the accommodation list
*
* @param SchoolList list The list to refresh
*
*/
refreshVisualAccommodationList : function(list) {
var availableAccommodations = this.getAvailableAccommodations();
var accommodationStartDate = this.getSchoolAccommodationStartDate();
var accommodationEndDate = this.getAccommodationEndDate();
list.getListItems().each(function(item, index) {
if (availableAccommodations.contains(item.getValue().parentId)) {
var startDate = new Date(accommodationStartDate);
var day = startDate.getDay();
if (day == 0)day = 7;
while (parseInt(item.getValue().accommodationStartDay) != day) {
startDate.setDate(startDate.getDate() - 1);
day = startDate.getDay();
if (day == 0)day = 7;
}
var endDate = new Date(accommodationEndDate);
var day = endDate.getDay();
if (day == 0)day = 7;
while (parseInt(item.getValue().accommodationEndDay) != day) {
endDate.setDate(endDate.getDate() + 1);
day = endDate.getDay();
if (day == 0)day = 7;
}
}
var available =  true;
// check the availability for this accommodation
if(accommodationStartDate && accommodationEndDate && item.getValue().availabilities && item.getValue().availabilities.length){
var availabilities = item.getValue().availabilities;
var startWeek = accommodationStartDate.getWeek();
var startYear = accommodationStartDate.getFullYear();
var endWeek = accommodationEndDate.getWeek();
var duration  = this.getDurationInWeeks(accommodationEndDate, accommodationStartDate);
available = false;
var i = 0;
if(startWeek == endWeek){
if(availabilities[startYear + '' + endWeek] == undefined){
available = true;
}
}else {
while (duration > 0 && startWeek != endWeek && !available){
if(availabilities[startYear + '' + startWeek] == undefined){
available = true;
}
if(startWeek == 52){
startWeek = 1;
startYear++;
}else {
startWeek++;
}
duration--;
}
}
}
// if the accommodation is available,
// the duration is longer than the minimum duration of the accommodation and the number of participant is big enough
if (availableAccommodations.contains(item.getValue().parentId)
&& this.getDurationInWeeks(endDate, startDate) >= item.getValue().minimumDurationInWeeks
&& this.getSchoolParticipants() >= item.getValue().minimumNumberOfPeople) {
item.setIsSelectionnable(available);
} else {
// if the item is not a category,
if (item.getValue().type != 'category') {
item.setIsSelectionnable(false);
}
}
}.bind(this));
if (this.getCompletedCourses().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* Add an accommodation
*
* @param Number id The accommodation ID
* @param Number optionID The accommodation Option ID
* @param Boolean attachedAccommodation True if the accommodation is attached (false by default)
*
* @return True if the accommodation is added
*/
addAccommodation : function(id, optionId, attachedAccommodation) {
var accommodationDetailsDTO = this._schoolAccommodationsDTO.copy();
// retrieve the course informations
accommodationDetailsDTO = accommodationDetailsDTO.filter(function(item, index) {
return item.id == id;
}.bind(this));
var accommodationOptionDetails = accommodationDetailsDTO[0].option.filter(function(item, index) {
return item.id == optionId;
}.bind(this));
var newAccommodation = new SchoolAccommodationObject(accommodationDetailsDTO[0], accommodationOptionDetails[0], this._translateDTO.accommodationObject, this._classNameBase ,this);
// if the accommodation has valid start dates it is added
if (newAccommodation.getStartDates().length) {
if(!attachedAccommodation)this._accommodations.push(newAccommodation);
newAccommodation.createVisualAccommodation(attachedAccommodation);
if(attachedAccommodation)this._accommodations.push(newAccommodation);
if(!newAccommodation.getHtml()){
return false;
}
newAccommodation.getHtml().injectInside(this._accommodationUserAccommodationList);
newAccommodation.addEvent('deleteAccommodation', function(e) {
this.deleteAccommodation(newAccommodation);
}.bind(this));
return true;
} else {
return false;
}
},
/**
* Refresh all the accommodations
*
* it is called when an accommodation or a course is modified
*
* @optionalparam String option The options - lists if the list have to be regenerated
* @optionalparam boolean noPriceRefresh True if the price should not be refreshed
*/
refreshAccommodations : function(option, noPriceRefresh) {
this.refreshVisualAccommodationList(this.accommodationsList);
// if an accomodation need more than the number of people selected, it's deleted
var accommodationModified = false;
for (var i = 0; i < this._accommodations.length; i++) {
if (this._accommodations[i].getAccommodationOptionDetails().minimumNumberOfPeople > this.getSchoolParticipants()) {
this._accommodations[i].removeAccommodation();
this._accommodations.remove(this._accommodations[i]);
accommodationModified = true;
i--;
}
}
if (accommodationModified) this._school.fireEvent('refreshPrice');
// if there are no more courses, all the accommodations are deleted
if (this.getCompletedCourses().length == 0) {
var accommodations = this._accommodations.length;
for (var i = 0; i < this._accommodations.length; i++) {
if (this._accommodations.length) {
this._accommodations[i].removeAccommodation();
this._accommodations.remove(this._accommodations[i]);
i--;
}
}
this.displayAddButton(false);
// and if there was any accommodations and there is no transfers, we send a refresh price (else the refresh price will be made by the school transfers)
if (accommodations && !this._school.getCompletedTransfers()) {
this._school.fireEvent('refreshPrice');
}
} else {
// getting the mandatory accommodations
var mandatoryAccommodations = this._school.getMandatoryAccommodations();
// checking if the there are no unavailable accommodation on the basket
var availableAccommodations = this.getAvailableAccommodations();
// remove the unauthorized accommodations
for (var i = 0; i < this._accommodations.length; i++) {
if (!availableAccommodations.contains(parseInt(this._accommodations[i]._accommodationDetails.id))) {
this._accommodations[i].removeAccommodation();
this._accommodations.remove(this._accommodations[i]);
i--;
}
}
for (var i = 0; i < this._accommodations.length; i++) {
this._accommodations[i].setIsAttachedToCourse(false);
}
// if there are mandatory accommodations
if (mandatoryAccommodations.length) {
this.checkMandatoryAccomodations(mandatoryAccommodations);
}
// retrieve the max start and end date value (based on the courses and acommodation start day and end day)
var startDate = this.getAccommodationStartDate();
var endDate = this.getAccommodationEndDate();
if (this._accommodations.length && endDate < this._accommodations.getLast().getAccommodationEndDate()) {
var endDay = parseInt(this._accommodations.getLast().getAccommodationOptionDetails().accommodationEndDay);
if (endDay == 7)endDay = 0;
while (endDay != endDate.getDay()) {
endDate.setDate(endDate.getDate() + 1);
}
if (endDate < this._accommodations.getLast().getAccommodationEndDate()) {
// delete the accommodations that are beyond the end date
for (var i = this._accommodations.length - 1; i > 0; i--) {
if (this._accommodations[i].getAccommodationEndDate() > endDate) {
this._accommodations[i].removeAccommodation();
this.deleteAccommodation(this._accommodations[i]);
}
}
// if there are still accommodations the last one is adapted to fit the new dates
if (this._accommodations.length) {
var duration = this.getDurationInWeeks(endDate, this._accommodations.getLast().getAccommodationStartDate());
// if the new duration is smaller than the minimum
if (duration < this._accommodations.getLast().getAccommodationOptionDetails().minimumDurationInWeeks) {
duration = this._accommodations.getLast().getAccommodationOptionDetails().minimumDurationInWeeks;
// if it can't be adapted, it is deleted
if (this.getDurationInWeeks(endDate, startDate) < duration) {
this._accommodations.getLast().removeAccommodation();
this.deleteAccommodation(this._accommodations.getLast());
} else {
this._accommodations.getLast().refreshAccommodationData(this._accommodations.getLast().getAccommodationStartDate(), duration, endDate);
}
} else {
this._accommodations.getLast().refreshAccommodationData(this._accommodations.getLast().getAccommodationStartDate(), duration, endDate);
}
}
}
}
// if the new accommodation startDate is smaller than the old one
if (this._accommodations.length && startDate > this._accommodations[0].getAccommodationStartDate()
&& !this._accommodations[0].getIsAttachedToCourse()) {
for (var i = 0; i < this._accommodations.length; i++) {
if (this._accommodations[i].getAccommodationStartDate() < startDate) {
this._accommodations[i].removeAccommodation();
this.deleteAccommodation(this._accommodations[i]);
i--;
}
}
if (this._accommodations.length) {
var duration = this.getDurationInWeeks(this._accommodations[0].getAccommodationEndDate(), startDate);
if (duration < this._accommodations[0].getAccommodationOptionDetails().minimumDurationInWeeks) duration = this._accommodations[0].getAccommodationOptionDetails().minimumDurationInWeeks;
this._accommodations[0].refreshAccommodationData(startDate, duration, this._accommodations[0].getAccommodationEndDate());
}
}
// if the lists have to be generated again
if (option == 'lists') {
this._accommodations.each(function(item, index) {
if (!this._accommodations[0].getIsAttachedToCourse()) {
item.reGenerateAccommodationLists();
this.checkAccommodations(item);
}
}.bind(this));
} else {
this._accommodations.each(function(item, index) {
if (!this._accommodations[0].getIsAttachedToCourse()) {
item.refreshAccommodationLists();
this.checkAccommodations(item);
}
}.bind(this));
}
var refreshPrice = false;
if (this._accommodations.length == 1) {
noPriceRefresh = false;
}
for (var i = 0; i < this._accommodations.length; i++) {
if (this._accommodations[i].isComplete()) {
refreshPrice = true;
break;
}
}
if (!noPriceRefresh && refreshPrice) {
this._school.fireEvent('refreshPrice');
}
// check if the add button must be displayed or not
if((this.getCompletedCourses().length == mandatoryAccommodations.length
&& mandatoryAccommodations.length <= this._accommodations.length)
|| (this._accommodations.length && this._accommodations.getLast().getIsAttachedToCourse() == true
&& this._accommodations.getLast().getAttachedToCourse().courseId == this._school.getCourses().getValidAddedCourses(true).getLast().getCourseDetails().id)){
this.displayAddButton(false);
}else{
this.displayAddButton(true);
}
}
},
/**
* check if the mandatory accommodations are correctly added and displayed
*
* @param Array mandatoryAccommodations The mandatory accommodations list
* @optionalparam Integer notToAdd The accommodationOption id to not add
*
*/
checkMandatoryAccomodations : function(mandatoryAccommodations) {
// check each mandatory accommodations
for (var i = 0; i < mandatoryAccommodations.length; i++) {
// getting the accommodations informations to add
var accommodationsToAdd = this._schoolAccommodationsDTO.filter(function(item, index) {
return mandatoryAccommodations[i].ids.contains(parseInt(item.id));
});
// if there is a valid accommodation to add
if (accommodationsToAdd.length) {
var accommodationsAlreadyAdded = new Array();
// checking if the accommodation is already present
if (this._accommodations.length) {
this._accommodations.each(function(item, index) {
for (var j = 0; j < accommodationsToAdd.length; j++) {
if (item._accommodationDetails.id == accommodationsToAdd[j].id && !(item.getIsAttachedToCourse())) {
accommodationsAlreadyAdded.push(item);
}
}
}.bind(this));
}
// if there are no accommodation added
if (!accommodationsAlreadyAdded.length) {
var added = false;
var j = 0;
var k = 0;
while (!added) {
// find a valid accommodation to add in the list
if (j < accommodationsToAdd.length) {
// find the first valid accommodation option
if (k < accommodationsToAdd[j].option.length) {
this.addAccommodation(accommodationsToAdd[j].id, accommodationsToAdd[j].option[k].id, true);
if (this._accommodations.length) {
this._accommodations[this._accommodations.length - 1].setIsAttachedToCourse(true);
this._accommodations[this._accommodations.length - 1].setAttachedToCourse(mandatoryAccommodations[i]);
// set the values
var startDate = this.getAccommodationValidStartDates(this._accommodations[this._accommodations.length - 1], this._accommodations[this._accommodations.length - 1]._accommodationStartDatesList);
if (startDate.length) {
this._accommodations[this._accommodations.length - 1].setAttachedAccommodationStartDate(startDate[0]);
var duration = this.getAccommodationValidDuration(this._accommodations[this._accommodations.length - 1], this._accommodations[this._accommodations.length - 1]._accommodationDurationsList);
if (duration.length) {
this._accommodations[this._accommodations.length - 1].setAttachedAccommodationDuration(duration[0]);
}
}
if (startDate.length && duration.length) {
added = true;
} else {
// remove the accommodation and try to add the next one
this._accommodations[this._accommodations.length - 1].removeAccommodation();
this._accommodations.remove(this._accommodations[this._accommodations.length - 1]);
k++;
}
}else{
j++;
}
} else {
j++;
}
} else {
added = true;
}
}
} else {
accommodationsAlreadyAdded[0].setIsAttachedToCourse(true);
accommodationsAlreadyAdded[0].setAttachedToCourse(mandatoryAccommodations[i]);
var startDate = this.getAccommodationValidStartDates(accommodationsAlreadyAdded[0], accommodationsAlreadyAdded[0]._accommodationStartDatesList);
if (startDate.length) {
accommodationsAlreadyAdded[0].setAttachedAccommodationStartDate(startDate[0]);
var duration = this.getAccommodationValidDuration(accommodationsAlreadyAdded[0], accommodationsAlreadyAdded[0]._accommodationDurationsList);
if (duration.length) {
accommodationsAlreadyAdded[0].setAttachedAccommodationDuration(duration[0]);
//                          accommodationsAlreadyAdded[0].refreshAccommodationLists();
this._accommodations[this._accommodations.length - 1].reGenerateAccommodationLists();
}
}
// if something was not valid, remove the accommodation and add another one
if (!startDate.length || !duration.length) {
this._accommodations.remove(accommodationsAlreadyAdded[0]);
accommodationsAlreadyAdded[0].removeAccommodation();
i--;
}
}
}
}
},
/**
* Check all the accommodations and modify them to fit the accommodation passed in parameter
*
* @param SchoolAccommodationsObject accommodation The accommodation to check
*
*/
checkAccommodations : function(accommodation) {
var index = this._accommodations.indexOf(accommodation);
// if it's the first accommodation and there are more than one accommodation
if (index == 0 && this._accommodations.length > 1) {
if (accommodation.getAccommodationEndDate() > this._accommodations[index + 1].getAccommodationStartDate() && this._accommodations[index + 1].isComplete() && accommodation.isComplete()) {
var duration = this.getDurationInWeeks(this._accommodations[index + 1].getAccommodationEndDate(), accommodation.getAccommodationEndDate());
if (duration < this._accommodations[index + 1].getAccommodationOptionDetails().minimumDurationInWeeks) duration = this._accommodations[index + 1].getAccommodationOptionDetails().minimumDurationInWeeks;
// set the new data for the next accommodation
if(this._accommodations[index+1].getIsAttachedToCourse() == false)this._accommodations[index + 1].refreshAccommodationData(accommodation.getAccommodationEndDate(), duration, this._accommodations[index + 1].getAccommodationEndDate());
}
}
// if it's not the first accommodation
if (index > 0) {
// set the previous valid accommodation with valid data (endDate is set with the actual accommodation startDate and duration is calculated)
// if the startDate is higher than the previous end Date
if (accommodation.getAccommodationStartDate() < this._accommodations[index - 1].getAccommodationEndDate() && this._accommodations[index - 1].isComplete() && accommodation.isComplete()) {
var duration = this.getDurationInWeeks(accommodation.getAccommodationStartDate(), this._accommodations[index - 1].getAccommodationStartDate());
if (duration < this._accommodations[index - 1].getAccommodationOptionDetails().minimumDurationInWeeks) {
duration = this._accommodations[index - 1].getAccommodationOptionDetails().minimumDurationInWeeks;
}
// set the new data for this accommodation
if(this._accommodations[index-1].getIsAttachedToCourse() == false)this._accommodations[index - 1].refreshAccommodationData(this._accommodations[index - 1].getAccommodationStartDate(), duration, accommodation.getAccommodationStartDate());
}
}
// if it's not the first and not the last one
if (index > 0 && this._accommodations.getLast() != accommodation) {
if (accommodation.getAccommodationEndDate() > this._accommodations[index + 1].getAccommodationStartDate() && this._accommodations[index + 1].isComplete() && accommodation.isComplete()) {
var duration = this.getDurationInWeeks(this._accommodations[index + 1].getAccommodationEndDate(), accommodation.getAccommodationEndDate());
if (duration < this._accommodations[index + 1].getAccommodationOptionDetails().minimumDurationInWeeks) {
duration = this._accommodations[index + 1].getAccommodationOptionDetails().minimumDurationInWeeks;
}
// set the new data for this accommodation
if(this._accommodations[index+1].getIsAttachedToCourse() == false)this._accommodations[index + 1].refreshAccommodationData(accommodation.getAccommodationEndDate(), duration, this._accommodations[index + 1].getAccommodationEndDate());
}
}
}
,
/**
* Return the school accommodation start date
*
* @return Date the school accommodations start date
*/
getSchoolAccommodationStartDate : function() {
return this._school.getAccommodationStartDate();
},
getSchoolParticipants : function() {
return this._school.getParticipants();
},
/**
* Returns the possible startDate for the accommodation given in parameter
*
* @param SchoolAccommodationObject accommodation The accommodation
*
* @return Date The possible startdates
*/
getAccommodationStartDate : function() {
var startDate = this.getSchoolAccommodationStartDate();
if(this._accommodations.length){
var day = startDate.getDay();
if (day == 0)day = 7;
if(this._accommodations[0] && this._accommodations[0].getAccommodationOptionDetails().accommodationStartDay > 0){
while (this._accommodations[0].getAccommodationOptionDetails().accommodationStartDay != day) {
startDate.setDate(startDate.getDate() - 1);
day = startDate.getDay();
if (day == 0)day = 7;
}
}
}
return startDate;
},
/**
* Returns the valid startDates for an accommodation given in parameter
*
* @param SchoolAccommodationObject accommodation The accommodation
* @param Array accommodationStartDates Array of number containing all the possible start dates
*
* @return Array An array of possible start dates
*/
getAccommodationValidStartDates : function(accommodation, accommodationStartDates) {
var validStartDates = new Array();
var startDates = accommodation.getStartDates();
/* var startDates = new Array();
for(var i = 0; i < accommodationStartDates.getListItems().length; i++ ){
startDates.push(accommodationStartDates.getListItems()[i].getValue());
}*/
var minimumDuration = accommodation.getAccommodationOptionDetails().minimumDurationInWeeks;
var availabilities = accommodation.getAccommodationOptionDetails().availabilities;
// if this accommodation is not the first, we remove the minimum durations of the previous one
if (this._accommodations.indexOf(accommodation) > 0) {
for (var i = 0; i < this._accommodations.indexOf(accommodation); i++) {
if (this._accommodations[i].isComplete()) {
if(this._accommodations[i].getIsAttachedToCourse() == true){
startDates.splice(0, this._accommodations[i]._accommodationDuration);
}else{
startDates.splice(0, this._accommodations[i].getAccommodationOptionDetails().minimumDurationInWeeks);
}
}
}
}
// if this accommodation is not the last, we remove the minimum durations of the next one
if (this._accommodations.getLast() != accommodation) {
for (var i = this._accommodations.length - 1; i > this._accommodations.indexOf(accommodation); i--) {
if (this._accommodations[i].isComplete()) {
if(this._accommodations[i].getIsAttachedToCourse() == true){
startDates.splice(startDates.length - this._accommodations[i]._accommodationDuration, this._accommodations[i]._accommodationDuration);
}else{
startDates.splice(startDates.length - this._accommodations[i].getAccommodationOptionDetails().minimumDurationInWeeks, this._accommodations[i].getAccommodationOptionDetails().minimumDurationInWeeks);
}
}
}
}
startDates.each(function(item, index) {
var date = item;
var year = date.getFullYear();
var week = date.getWeek();
if (accommodation.getAccommodationOptionDetails().accommodationStartDay == 7) {
if (week > 1)week = week + 1;
}
// check the availabilities for this start date
var toAdd = true;
if (availabilities) {
for (var i = 0; i < parseInt(minimumDuration); i++) {
if (week > 52) {
var lastWeek = (new Date(date.getFullYear(), 12, 31)).getWeek();
if (week < lastWeek) {
week = week - lastWeek;
year = year + 1;
}
}
if (availabilities[year + '' + week] == 0) {
toAdd = false;
}
week++;
}
}
if (toAdd) {
validStartDates.push(date);
}
}.bind(this));
// if the accommodation is attached to a course, we must find the only course start date available
if (accommodation.getIsAttachedToCourse()) {
var courseStartDate = (new Date()).fromIso(accommodation.getAttachedToCourse().startDate);
var courseStartTime = courseStartDate.getTime();
for (var i = 0; i < validStartDates.length; i++) {
var n = (i == 0? i : i + 1);
if(validStartDates.length > n) {
var validStartTime = validStartDates[n].getTime();
// if the start date is smaller that the course start time (minus 3 days) we remove it
if (validStartTime < (courseStartTime - (86400 * 3 * 1000))) {
validStartDates.splice(0, i + 1);
i--;
}
// if the start date is bigger that the course start time (+3 days) we remove it
if (validStartTime > (courseStartTime + (86400 * 3 * 1000))) {
validStartDates.splice(n, validStartDates.length - 1);
}
}
}
return validStartDates;
}
return validStartDates;
},
/**
* Return the added accommodations
*/
getAccommodations : function(){
return this._accommodations;
},
/**
* Returns the final endDate for a given accommodation
*
* @param SchoolAccommodationObject accommodation The accommodation
*
* @return Date the endDate
*/
getAccommodationEndDate : function(accommodation) {
return this._school.getAccommodationEndDate(accommodation);
},
/**
* Returns an array of valid durations calculated from the startdates of the accommodation and
* the endDate returned by the parent
*
* @return Array An Array of number containing the valid durations
*/
getAccommodationValidDuration : function(accommodation, durationList) {
// check if this accommodation is attached to a course
if (accommodation.getIsAttachedToCourse()) {
var accommodationEndDate = this._school.getCourseAccommodationEndDate(accommodation.getAttachedToCourse().courseId, (new Date()).fromIso(accommodation.getAttachedToCourse().startDate), accommodation);
// if there is an accommodation end date returned
if (accommodationEndDate) {
var duration = this.getDurationInWeeks(accommodationEndDate, accommodation._accommodationStartDate);
}else{
return [];
}
}
// if the accommodations is not attached
var validDurations = new Array();
var durations = durationList;
var durationsToRemove = 0;
// if the accommodation has a start date
if (accommodation.getAccommodationStartDate()) {
var difference = this.getDurationInWeeks(this.getAccommodationEndDate(accommodation), accommodation.getAccommodationStartDate());
durationsToRemove = durations.getListItems().length - 1 + parseInt(accommodation.getAccommodationOptionDetails().minimumDurationInWeeks) - Math.round(difference);
if(this._accommodations.indexOf(accommodation) >= 0){
for (var i = this._accommodations.indexOf(accommodation); i < this._accommodations.length; i++) {
if (accommodation != this._accommodations[i] && this._accommodations[i].isComplete()) {
if (this._accommodations[i].getIsAttachedToCourse() == true) {
durationsToRemove = parseInt(durationsToRemove + parseInt(this._accommodations[i]._accommodationDuration));
} else {
durationsToRemove = parseInt(durationsToRemove + parseInt(this._accommodations[i].getAccommodationOptionDetails().minimumDurationInWeeks));
}
}
}
}
} else {
for (var i = 0; i < this._accommodations.length; i++) {
if (accommodation != this._accommodations[i] && this._accommodations[i].isComplete()) {
durationsToRemove = parseInt(durationsToRemove + parseInt(this._accommodations[i].getAccommodationOptionDetails().minimumDurationInWeeks));
}
}
}
var week = -1;
var year = -1;
if (accommodation.getAccommodationStartDate()) {
week  = accommodation.getAccommodationStartDate().getWeek();
year  = accommodation.getAccommodationStartDate().getFullYear();
if(accommodation.getAccommodationOptionDetails().accommodationStartDay == 7){
if(week > 1)week = week+1;
}
}
// add the duration items
if(durationsToRemove < 0)durationsToRemove = 0;
for(var i = 0; i < (durations.getListItems().length - durationsToRemove); i++){
var value = durations.getListItems()[i].getValue();
if(week == -1 || !accommodation.getAccommodationOptionDetails().availabilities ||
accommodation.getAccommodationOptionDetails().availabilities[accommodation.getAccommodationStartDate().getFullYear() + '' + (week + parseInt(value)-1)] != 0){
validDurations.push(parseInt(value));
}else{
break;
}
}
if (accommodation.getIsAttachedToCourse()) {
if (duration && validDurations.contains(duration)) {
return [parseInt(duration)];
} else {
return [];
}
}
return validDurations;
}
,
/**
* Returns the end date of the previous accommodation
*
* @param SchoolAccommodationObject accommodation The accommodation
*/
getPreviousEndDate : function(accommodation) {
var previousEndDate = this.getAccommodationEndDate();
for (var i = 0; i < this._accommodations.indexOf(accommodation); i++) {
if (this._accommodations[i].isComplete()) previousEndDate = this._accommodations[i].getAccommodationEndDate();
}
return previousEndDate;
}
,
/**
* Returns the duration in weeks between a startDate and an end date
*
* @param Date endDate The end date
* @param Date starDate The startdate
* @return Number The duration in week
*/
getDurationInWeeks : function(endDate, startDate) {
var duration = endDate - startDate;
duration = Math.round(duration / (1000 * 60 * 60 * 24 * 7));
if(duration == 0 && startDate.getTime() < endDate.getTime() ){
duration = 1;
}
return duration;
},
/**
* Returns the completed accommodations
*
* @return SchoolAccommodationObject[] The completed accommodations
*/
getCompletedAccommodations : function() {
var accommodations = new Array();
this._accommodations.each(function(item, index) {
if (item.isComplete) {
accommodations.push(item);
}
});
return accommodations;
},
/**
* Return the completed courses for this school (if any)
*
*/
getCompletedCourses : function() {
return this._school.getCompletedCourses();
},
/**
* Delete the accommodation given in parameter
*
* @param Element accommodation The accommodation to delete
*/
deleteAccommodation : function(accommodation) {
this._accommodations.remove(accommodation);
this.refreshAccommodations();
this._school.fireEvent('heightModified');
//        if (!this._accommodations.length) {
this.fireEvent('refreshPrice');
//        }
},
/**
*  Returns the available accommodations
*
* @return Array of integer The Accommodation IDs
*/
getAvailableAccommodations : function() {
return this._school.getAvailableAccommodations();
},
/**
* Return an array containing the available transfers
*
* @return Array of transfers ID
*/
getAvailableTransfers : function() {
var availableTransfers = new Array();
for (var i = 0; i < this._accommodations.length; i++) {
availableTransfers = availableTransfers.merge(this._accommodations[i].getAccommodationDetails().availableTransfers);
}
return availableTransfers;
},
/**
* Return the max accommodation end date for a course
*
* @param integer courseId The Course ID
* @param Date startDate the course start date
*
* @return Date The course accommodation end date
*/
getCourseAccommodationEndDate : function(courseId, startDate, accommodation) {
return this._school.getCourseAccommodationEndDate(courseId, startDate, accommodation);
},
/**
* Display or hide the add button
*
* @param boolean isDisplayed True to display the hide button
*/
displayAddButton : function(isDisplayed){
if(isDisplayed){
this._accommodationAddButton.setStyle('display', '');
}else{
this._accommodationAddButton.setStyle('display', 'none');
}
},
/**
* Returns the parent of this object
*
* @return Object The parent object
*/
getSchool : function() {
return this._school;
}
,
/**
* Returns the school accommodations DTO
*
* @return Object The school accommodations DTO
*/
getSchoolAccommodationsDTO : function() {
return this._schoolAccommodationsDTO;
}
});/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @event Event refreshPrice This is fired when the price have to be recalculated
* @event Event refreshAccommodations This is fired when a course is modified and the accommodations have to be refreshed
* @event Event heightModified This is fired when a course is added or deleted
*
* @param FixedDatesCourseListItemDTO schoolFixedCoursesDTO The DTO containing all the fixed courses informations
* @param VariableDatesCourseListItemDTO schoolVariableCoursesDTO The DTO containing all the variable courses informations
* @param Object translateDTO The DTO containing all the translations for this class
* @param School parent The parent
**/
var SchoolCourses = Events.extend({
/**
* This is the initialization function
*
*/
initialize : function(schoolFixedCoursesDTO, schoolVariableCoursesDTO, schoolOptionalCoursesDTO, translateDTO, listContainer, parent) {
this._schoolFixedCoursesDTO = schoolFixedCoursesDTO;
this._schoolVariableCoursesDTO = schoolVariableCoursesDTO;
this._schoolOptionalCoursesDTO = schoolOptionalCoursesDTO;
this._listContainer = listContainer;
this._translateDTO = translateDTO;
this._courses = new Array();
this._parent = parent;
this._classNameBase = this.getParent().getClassNameBase();
this.addEvent('refreshCourses', function() {
this.refreshCourses();
}.bind(this));
},
/**
* Returns an object containing the informations for the calculation price
*
* @return Object The fixed course informations needed to calculate the price
*/
getFixedCoursesDTO : function() {
var schoolDTO = new Array();
this._courses.each(function(item, index) {
if (item.getCourseDetails().type == 'fixedDate' && item.isComplete()) {
schoolDTO.push(item.getDTO());
}
});
return schoolDTO;
},
/**
* Returns an object containing the informations for the calculation price
*
* @return Object the variable course informations needed to calculate the price
*/
getVariableCoursesDTO : function() {
var schoolDTO = new Array();
this._courses.each(function(item, index) {
if (item.getCourseDetails().type == 'variableDate' && item.isComplete()) {
schoolDTO.push(item.getDTO());
}
});
return schoolDTO;
},
/**
* Returns an object containing the informations for the calculation price
*
* @return Object the variable course informations needed to calculate the price
*/
getOptionalCoursesDTO : function() {
var schoolDTO = new Array();
this._courses.each(function(item, index) {
if (item.getCourseDetails().type == 'optional' && item.isComplete()) {
schoolDTO.push(item.getDTO());
}
});
return schoolDTO;
},
/**
*
* Populate the fixed courses from a dto
*
* @param Array The fixed course informations needed to populate
*/
populateCoursesFromDTO : function(fixedCoursesToPopulateDTO, variableCoursesToPopulateDTO, optionalCoursesToPopulateDTO) {
// push every courses into one array
var coursesDTO = new Array();
if (fixedCoursesToPopulateDTO) {
fixedCoursesToPopulateDTO.each(function(item, index) {
item.courseType = "fixed";
coursesDTO.push(item);
});
}
if (variableCoursesToPopulateDTO) {
variableCoursesToPopulateDTO.each(function(item, index) {
item.courseType = "variable";
coursesDTO.push(item);
});
}
if (optionalCoursesToPopulateDTO) {
optionalCoursesToPopulateDTO.each(function(item, index) {
item.courseType = "optional";
coursesDTO.push(item);
});
}
// sort the courses by startdates
coursesDTO.sort(function(x1, x2) {
return ((new Date()).fromIso(x1.startDate) - (new Date()).fromIso(x2.startDate));
});
coursesDTO.each(function(item, index) {
var course;
switch(item.courseType){
case 'variable':
course = this._schoolVariableCoursesDTO.filter(function(itemDTO, indexDTO) {
return itemDTO.id == item.id;
}.bind(this));
break;
case 'fixed':
course = this._schoolFixedCoursesDTO.filter(function(itemDTO, indexDTO) {
return itemDTO.id == item.id;
}.bind(this));
break;
case 'optional':
course = this._schoolOptionalCoursesDTO.filter(function(itemDTO, indexDTO) {
return itemDTO.id == item.id;
}.bind(this));
break;
}
// if a course has been found
if (course[0]) {
this.addCourse(course[0]);
this._courses[this._courses.length - 1].populateFromDTO(item);
}
}.bind(this));
},
/**
*  Return the classNameBase
*/
getClassNameBase : function() {
return this._classNameBase;
},
/**
* Refresh all the courses
*
*/
refreshCourses : function() {
var availableOptionalCourses = this.getAvailableOptionalCourses();
// remove the optionals course not allowed to be there
this._courses.each(function(item, index) {
if (item.getCourseDetails().type == 'optional' && !availableOptionalCourses.contains(parseInt(item.getCourseDetails().id))) {
this._courses.remove(item);
item.removeCourse();
}
}.bind(this));
// check the dates
this._courses.each(function(item, index) {
if (item.getCourseDetails().type == 'optional') {
var modified = false;
var validStartDates = this.getValidOptionalCourseStartDate(item);
if (validStartDates.length && !validStartDates.contains(item.getCourseStartDate())) {
item.setCourseStartDate(validStartDates[0]);
modified = true;
}
var validDurations = this.getValidOptionalCourseDuration(item);
if (!validDurations.contains(item.getCourseDuration()) && !item.getCourseDetails().oneDayCourse ) {
item.setCourseDuration(validDurations.getLast());
modified = true;
}
if(!validStartDates.length &&  !validDurations.length){
this._courses.remove(item);
item.removeCourse();
}
if (modified) item.refreshOptionalCourseData();
}
}.bind(this));
this.refreshVisualCoursesList(this.coursesList);
if(this.optionalCoursesList){
this.refreshVisualOptionalCoursesList(this.optionalCoursesList);
}
this._courses.each(function(item, index) {
item.refreshLists();
});
this.displayAddButton(this.getValidAddedCourses().length);
this._parent.fireEvent('refreshAccommodations');
},
/**
* Returns the visual course container
*
*/
getHtml : function() {
this._courseContainer = new Element('div', {'class': this._classNameBase + 'Section'});
this._mainCourseContainer = new Element('div', {'class': this._classNameBase + 'Section-Courses'});
this._courseTitle = new Element('div', {'class': this._classNameBase + 'Section-Title'});
this._courseListContainer = new Element('div', {'class': this._classNameBase + 'Courses-CoursesList-Container'});
this._courseUserCoursesList = new Element('div', {'class': this._classNameBase + 'Courses-UserCoursesList'});
this._courseAddButton = new Element('div', {'class': this._classNameBase + 'AddButton'});
this._courseTitle.injectInside(this._mainCourseContainer);
this._courseListContainer.injectInside(this._mainCourseContainer);
this._courseUserCoursesList.injectInside(this._mainCourseContainer);
this._courseAddButton.injectInside(this._mainCourseContainer);
this._mainCourseContainer.injectInside(this._courseContainer);
this._courseTitle.setHTML(this._translateDTO.title);
this._courseAddButton.setHTML(this._translateDTO.add);
// initialize the courses list
this.coursesList = new SchoolList(this._courseAddButton, this._classNameBase);
this.getVisualCoursesList(this.coursesList);
this.coursesList.getHtml().injectInside(this._listContainer);
this.coursesList.initializeEvents();
if(this._schoolOptionalCoursesDTO.length){
this._optionalCourseContainer = new Element('div', {'class': this._classNameBase + 'Section-Courses'});
this._optionalCourseTitle = new Element('div', {'class': this._classNameBase + 'Section-Title'});
this._optionalCourseListContainer = new Element('div', {'class': this._classNameBase + 'Courses-CoursesList-Container'});
this._optionalCourseUserCoursesList = new Element('div', {'class': this._classNameBase + 'Courses-UserCoursesList'});
this._optionalCourseAddButton = new Element('div', {'class': this._classNameBase + 'AddButton '});
this._optionalCourseTitle.injectInside(this._optionalCourseContainer);
this._optionalCourseListContainer.injectInside(this._optionalCourseContainer);
this._optionalCourseUserCoursesList.injectInside(this._optionalCourseContainer);
this._optionalCourseAddButton.injectInside(this._optionalCourseContainer);
this._optionalCourseTitle.setHTML(this._translateDTO.optionalCourseTitle);
this._optionalCourseAddButton.setHTML(this._translateDTO.optionalCourseAdd);
this._optionalCourseContainer.injectInside(this._courseContainer);
// initialize the optional courses list
this.optionalCoursesList = new SchoolList(this._optionalCourseAddButton, this._classNameBase);
this.getVisualOptionalCoursesList(this.optionalCoursesList);
this.optionalCoursesList.getHtml().injectInside(this._listContainer);
this.optionalCoursesList.initializeEvents();
}
return this._courseContainer;
},
/**
* Generate the courses list for the "add a course" button
*
* @param SchoolList list The list we want to populate
*
*/
getVisualCoursesList : function(list) {
var validCourses = this.getValidCourses();
// clearing the list
list.clear();
var section = '';
//        list.addItem('category', this._translateDTO.coursesCategory);
//        list.getListItems().getLast().getHtml().addClass(this._classNameBase + 'List-Item-Category');
validCourses.each(function(item, index) {
// Add each courses
var listItem = new SchoolListItem(item, item.name, this._classNameBase);
list.addListItem(listItem);
listItem.getHtml().addClass(this._classNameBase + 'List-Item');
listItem.getHtml().addEvent('click', function() {
if(listItem.getIsSelectionnable()){
this.addCourse(item);
this._parent.fireEvent('heightModified');
}
}.bind(this));
}, this);
list.addItem('error', this._translateDTO.notAvailable);
if (list.getValidListItems().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* Generate the optional courses list for the "add an optional course" button
*
* @param SchoolList list The list we want to populate
*
*/
getVisualOptionalCoursesList : function(list) {
var validCourses = this.getValidCourses(null, true);
// clearing the list
list.clear();
var section = '';
validCourses.each(function(item, index) {
// Add each courses
var listItem = new SchoolListItem(item, item.name, this._classNameBase);
list.addListItem(listItem);
listItem.getHtml().addClass(this._classNameBase + 'List-Item');
listItem.getHtml().addEvent('click', function() {
if(listItem.getIsSelectionnable()){
this.addCourse(item);
this._parent.fireEvent('heightModified');
}
}.bind(this));
}, this);
list.addItem('error', this._translateDTO.notAvailable);
if (list.getValidListItems().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* Refresh the courses list
*
* @param SchoolList list the list we want to populate
*
*/
refreshVisualCoursesList : function(list) {
var validCourses = this.getValidCourses();
// retrieving the id of the available optional course
var availableOptionalCourses = this.getAvailableOptionalCourses();
list.getListItems().each(function(item, index) {
if ((validCourses.indexOf(item.getValue()) != -1)) {
item.setIsValid(true);
item.setIsSelectionnable(true);
// if the course is optional, checking that it's allowed to be selectionned
if (item.getValue().type == 'optional') {
if (!availableOptionalCourses.contains(parseInt(item.getValue().id))) {
item.setIsSelectionnable(false);
}
}
} else {
if(item.getValue() != 'category') item.setIsSelectionnable(false);
}
}.bind(this));
if (list.getValidListItems().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* Refresh the optional courses list
*
* @param SchoolList list the list we want to populate
*
*/
refreshVisualOptionalCoursesList : function(list) {
var validCourses = this.getValidCourses(null, true);
// retrieving the id of the available optional course
var availableOptionalCourses = this.getAvailableOptionalCourses();
list.getListItems().each(function(item, index) {
if ((validCourses.indexOf(item.getValue()) != -1)) {
item.setIsValid(true);
item.setIsSelectionnable(availableOptionalCourses.contains(parseInt(item.getValue().id)));
} else {
if(item.getValue() != 'category') item.setIsSelectionnable(false);
}
}.bind(this));
if (list.getValidListItems().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* return the list of available optional course
*
* @return integer[] Array of optional course IDs
*/
getAvailableOptionalCourses : function() {
var completedCourses = this.getCompletedCourses();
var availableOptionalCourses = new Array();
for (var i = 0; i < completedCourses.length; i++) {
if (completedCourses[i].getCourseDetails().type != 'optional') {
for (var j = 0; j < completedCourses[i].getCourseDetails().availableOptionalCourses.length; j++) {
availableOptionalCourses.include(completedCourses[i].getCourseDetails().availableOptionalCourses[j]);
}
}
}
return availableOptionalCourses;
},
/**
* Add a selected course
*
* @param Object course The course DTO
*/
addCourse : function(course) {
var newCourse;
switch (course.type) {
case 'fixedDate' :
newCourse = new SchoolFixedCourseObject(course, this._translateDTO.courseObject, this._listContainer, this._classNameBase, this);
break;
case 'variableDate' :
newCourse = new SchoolVariableCourseObject(course, this._translateDTO.courseObject, this._listContainer, this._classNameBase, this);
break;
case 'optional' :
newCourse = new SchoolOptionalCourseObject(course, this._translateDTO.courseObject, this._listContainer, this._classNameBase, this);
break;
}
newCourse.addEvent('refreshPrice', this.refreshPrice.bind(this));
this._courses.push(newCourse);
newCourse.createVisualCourse();
newCourse.addEvent('deleteCourse', function(e) {
this.deleteCourse(newCourse);
}.bind(this));
// add the html course
switch (course.type) {
case 'optional' :
this._courses.getLast().getHtml().injectInside(this._optionalCourseListContainer);
break;
default:
this._courses.getLast().getHtml().injectInside(this._courseUserCoursesList);
break;
}
},
/**
* Delete the course given in parameter
*
* @param SchoolCourseObject course The course to delete
*/
deleteCourse : function(course) {
this._courses.remove(course);
if (this._parent.getCompletedAccommodations().length == 0 && this._parent.getCompletedTransfers() == 0) {
this.refreshCourses();
this._parent.fireEvent('heightModified');
this.fireEvent('refreshPrice');
} else {
this.refreshCourses();
this._parent.fireEvent('heightModified');
}
},
/**
* Replace a course with another one
*
* @param SchoolCourseObject oldCourse The course we want to replace
* @param Object newCourse The new Course DTO
* @param Object oldCourseValues The old course values
*/
replaceCourse : function(oldCourse, newCourse, oldCourseValues) {
var i = this._courses.indexOf(oldCourse);
switch (newCourse.type) {
case 'fixedDate' :
var replaceCourse = new SchoolFixedCourseObject(newCourse, this._translateDTO.courseObject, this._listContainer, this._classNameBase,  this);
this._courses[i] = replaceCourse;
replaceCourse.createVisualCourse();
oldCourse.getHtml().replaceWith(replaceCourse.getHtml());
replaceCourse.addEvent('deleteCourse', function(e) {
this.deleteCourse(replaceCourse);
}.bind(this));
if (oldCourseValues) {
this._courses[i].refreshFixedCourseData(this._courses[i].getNewFixedCourseDates(oldCourseValues));
} else {
this._courses[i].refreshLists();
}
break;
case 'variableDate' :
var replaceCourse = new SchoolVariableCourseObject(newCourse, this._translateDTO.courseObject, this._listContainer, this._classNameBase,  this);
this._courses[i] = replaceCourse;
replaceCourse.createVisualCourse();
oldCourse.getHtml().replaceWith(replaceCourse.getHtml());
replaceCourse.addEvent('deleteCourse', function(e) {
this.deleteCourse(replaceCourse);
}.bind(this));
if (oldCourseValues) {
this._courses[i].replaceVariableCourseDates(oldCourseValues.startDate, oldCourseValues.duration);
} else {
this._courses[i].refreshLists();
}
break;
case 'optional' :
var replaceCourse = new SchoolOptionalCourseObject(newCourse, this._translateDTO.courseObject, this._listContainer, this._classNameBase,  this);
this._courses[i] = replaceCourse;
replaceCourse.createVisualCourse();
oldCourse.getHtml().replaceWith(replaceCourse.getHtml());
replaceCourse.addEvent('deleteCourse', function(e) {
this.deleteCourse(replaceCourse);
}.bind(this));
if (oldCourseValues) {
this._courses[i].replaceOptionalCourseDates(oldCourseValues.startDate, oldCourseValues.duration);
} else {
this._courses[i].refreshLists();
}
break;
}
this._courses[i].addEvent('refreshPrice', this.refreshPrice.bind(this));
this._parent.fireEvent('heightModified');
},
refreshPrice : function(){
this.fireEvent('refreshPrice');
},
/**
* Returns True if the course given in parameter is a fixed course
*
* @param Object course The course DTO
*
* @return Boolean Returns true if the course given in parameter is a fixed course
*/
getIsFixedCourse : function(course) {
return course.type == 'fixedDate';
},
/**
* Returns all the courses stocked in the DTO
*
* @return Array An array containing all the courses
*/
getCourses : function() {
var validCourses = new Array();
// retrieving the valid fixed courses
this._schoolFixedCoursesDTO.each(function(item, index) {
validCourses.include(item);
});
// retrieving the variable courses
this._schoolVariableCoursesDTO.each(function(item, index) {
validCourses.include(item);
});
return validCourses;
},
/**
* Returns all the optional courses stocked in the DTO
*
* @return Array An array containing all the courses
*/
getOptionalCourses : function() {
var validCourses = new Array();
// retrieving the valid optional courses
this._schoolOptionalCoursesDTO.each(function(item, index) {
validCourses.include(item);
});
return validCourses;
},
/**
* This method returns the number of completed courses
*
* @return SchoolCourseObject The courses completed
*
*/
getCompletedCourses : function() {
var completedCourses = new Array();
if (this._courses.length) {
this._courses.each(function(item, index) {
if (item.isComplete()) {
completedCourses.push(item);
}
});
}
return completedCourses;
},
/**
* Returns all the courses added in the cart
*
* @return Array An array containing all the courses
*/
getAddedCourses : function() {
return this._courses;
},
/**
* Return all the valid courses added in the cart
*
* @param Array An array containing all the courses
*/
getValidAddedCourses : function(bIgnoreOptional) {
var validCourses = new Array();
for (var i = 0; i < this._courses.length; i++) {
if (this._courses[i].isComplete()) {
if(!bIgnoreOptional || this._courses[i].getCourseDetails().type != 'optional'){
validCourses.push(this._courses[i]);
}
}
}
return validCourses;
},
/**
* Returns the valid courses for a given period based on a courseObject
*
* @param SchoolCoursesObject course The course object, if empty we consider that we want to add a new course
*
* @return Array An array of course ID (by default the one that is given in parameter)
*/
getValidCourses : function(course, optionalCourse) {
var startDate = new Date();
var endDate = new Date(startDate.getFullYear() + 10, startDate.getMonth(), startDate.getDate());
var validCourses = new Array();
// initializing the start and end dates
// if we want to add a new course
if (!course) {
if (this._courses.length > 0 && this._courses.getLast()._courseEndDate) {
startDate = this._courses.getLast()._courseEndDate;
}
// if we want to replace a course
} else {
// if the course is not the last one and there are more than one course
if (course != this._courses.getLast() && this._courses.length > 1) {
if (this._courses[this._courses.indexOf(course) + 1]._courseStartDate)endDate = this._courses[this._courses.indexOf(course) + 1]._courseStartDate;
}
// if this courses is not the first
if (this._courses.indexOf(course) > 0) {
if (this._courses[this._courses.indexOf(course) - 1]._courseEndDate)startDate = this._courses[this._courses.indexOf(course) - 1]._courseEndDate;
}
}
if (!optionalCourse) {
// retrieving the valid fixed courses
this._schoolFixedCoursesDTO.each(function(item, index) {
var courseItem = item;
item.sessions.each(function(item, index) {
//alert(item.courseStartDate);
if (item.courseStartDate >= startDate && item.courseEndDate <= endDate) {
validCourses.include(courseItem);
}
});
});
// retrieving the valid variable courses
this._schoolVariableCoursesDTO.each(function(item, index) {
var itemDuration = item.duration[0];
var courseItem = item;
item.startDates.each(function(item, index) {
var itemEndDate = new Date(item.getFullYear(), item.getMonth(), item.getDate() + itemDuration * 7);
if (item >= startDate && itemEndDate <= endDate) {
validCourses.include(courseItem);
}
}.bind(this));
}, this);
} else {
// retrieving the valid optional courses
this._schoolOptionalCoursesDTO.each(function(item, index) {
// need to recalulcate the start date for the optional courses
var completedCourses = this.getCompletedCourses();
if (completedCourses.length) {
var startDate = completedCourses[0].getCourseStartDate();
} else {
var startDate = new Date();
}
for (var i = 0; i < completedCourses.length; i++) {
if (completedCourses[i].getCourseDetails().availableOptionalCourses && completedCourses[i].getCourseDetails().availableOptionalCourses.contains(parseInt(item.id))) {
startDate = completedCourses[i].getCourseStartDate();
break;
}
}
var itemDuration = parseInt(item.duration[0]);
var courseItem = item;
item.startDates.each(function(itemStartDate, index) {
var itemEndDate = new Date(itemStartDate.getFullYear(), itemStartDate.getMonth(), (itemStartDate.getDate() + itemDuration * 7));
if (itemStartDate >= startDate && itemEndDate <= endDate) {
validCourses.include(courseItem);
}
}.bind(this));
}, this);
}
// if there is no course available and we are not on the add course list,
//  we just add the one that is already there
if (!validCourses.length && course) {
var courseItem = this._schoolVariableCoursesDTO.filter(function(item, index) {
return item.id == course._courseDetails.id;
}.bind(this));
if (!courseItem.length) {
courseItem = this._schoolFixedCoursesDTO.filter(function(item, index) {
return  item.id == course._courseDetails.id;
}.bind(this));
}
validCourses.include(courseItem[0]);
}
// sort the list
validCourses = validCourses.sort(this.sortFunction);
return validCourses;
},
/**
* function called to sort an array of valid courses
*
* @param courseDTO a The first course to compare
* @param courseDTO b The second course to compare
*/
sortFunction : function(a, b) {
return a.position - b.position;
},
/**
* Returns the valid courses date session for a given period based on a courseObject
*
* @param SchoolCoursesObject course The course object, if empty we consider that we want to add a new course
*
* @return Array An array of validSessions
*/
getValidFixedCourseSession : function(course) {
var validSessions = new Array();
var startDate = new Date();
var endDate = new Date(startDate.getFullYear() + 10, startDate.getMonth(), startDate.getDate());
// if the course is not the last one and there are more than one course
if (course != this._courses.getLast() && this._courses.length > 1) {
for (var i = this._courses.indexOf(course) + 1; i < this._courses.length; i++) {
if (this._courses[i]._courseStartDate)endDate = this._courses[i]._courseStartDate;
}
}
// if this courses is not the first
if (this._courses.indexOf(course) > 0) {
for (var i = this._courses.indexOf(course) - 1; i >= 0; i--) {
if (this._courses[i].getCourseDetails().type != 'optional' && this._courses[i]._courseEndDate)startDate = this._courses[i]._courseEndDate;
}
}
// retrieve the valid sessions
course._courseDetails.sessions.each(function(item, index) {
if (item.courseStartDate >= startDate && item.courseEndDate <= endDate) {
validSessions.include(item);
}
}.bind(this));
return validSessions;
},
/**
* Returns the valid courses date session for a given period based on a courseObject
*
* @param SchoolCoursesObject course The course object, if empty we consider that we want to add a new course
*
* @return Array An Array of valid start date
*/
getValidVariableCourseStartDate : function(course) {
var validStartDates = new Array();
var startDate = new Date();
var endDate = new Date(startDate.getFullYear() + 10, startDate.getMonth(), startDate.getDate());
var minimalEndDate = '';
var duration = course._courseDuration;
var availabilities = course.getCourseDetails().availabilities;
if (!duration) {
duration = course._courseDetails.duration[0];
}
// if the course is not the last one and there are more than one course
if (course != this._courses.getLast() && this._courses.length > 1) {
for (var i = this._courses.indexOf(course) + 1; i < this._courses.length; i++) {
if (this._courses[i].getCourseDetails().type != 'optional' && this._courses[i]._courseStartDate)endDate = this._courses[i]._courseStartDate;
}
}
// if this courses is not the first
if (this._courses.indexOf(course) > 0) {
for (var i = 0; i < this._courses.indexOf(course); i++) {
if (this._courses[i].getCourseDetails().type != 'optional' && this._courses[i]._courseEndDate)startDate = this._courses[i]._courseEndDate;
}
}
course._courseDetails.startDates.each(function(item, index) {
// the minimal end date is the date minus the minimal course duration
minimalEndDate = new Date(item.getFullYear(), item.getMonth(), item.getDate() + 7 * duration);
if (item >= startDate && minimalEndDate <= endDate) {
var year = item.getFullYear();
var week = item.getWeek();
if (course.getCourseDetails().courseStartDay == 7) {
if (week > 1)week = week + 1;
}
// check the availabilities for this start date
var toAdd = true;
if (availabilities) {
for (var i = 0; i < duration; i++) {
if (week > 52) {
var lastWeek = (new Date(item.getFullYear(), 12, 31)).getWeek();
if (week < lastWeek) {
week = week - lastWeek;
year = year + 1;
}
}
if (availabilities[year + '' + week] == 0) {
toAdd = false;
}
week++;
}
}
if (toAdd) {
validStartDates.push(item);
}
}
}.bind(this));
return validStartDates;
},
/**
* Returns the valid courses date session for a given period based on a courseObject
*
* @param SchoolCoursesObject course The course object, if empty we consider that we want to add a new course
*
* @return Array An Array of valid start date
*/
getValidOptionalCourseStartDate : function(course) {
var validStartDates = new Array();
var periods = new Array();
var sameCoursesPeriods = new Array();
var addedCourses = this.getValidAddedCourses();
var sameCourses = new Array();
var availabilities =  course.getCourseDetails().availabilities;
var additionalDays = course.getCourseDetails().additionalDays;
// check every course to calculate the start date and end date validity
for (var i = 0; i < addedCourses.length; i++) {
if (addedCourses[i].getCourseDetails().type != 'optional' && addedCourses[i].getCourseDetails().availableOptionalCourses.contains(parseInt(course.getCourseDetails().id))) {
var period = new Object();
period.startDate = (new Date()).fromIso(addedCourses[i].getDTO().startDate);
period.endDate = (new Date()).fromIso(addedCourses[i].getDTO().endDate);
if(additionalDays){
period.endDate.setDate(period.endDate.getDate() + additionalDays);
}
periods.push(period);
}
if (addedCourses[i].getCourseDetails().type == 'optional' && addedCourses[i].getCourseDetails().id == course.getCourseDetails().id && addedCourses[i] != course) {
sameCourses.push(addedCourses[i]);
}
}
if (sameCourses.length) {
for (var i = 0; i < sameCourses.length; i++) {
var period = new Object();
period.startDate = sameCourses[i]._courseStartDate;
period.endDate = sameCourses[i]._courseEndDate;
sameCoursesPeriods.push(period);
}
}
var minimalEndDate = '';
var duration = course._courseDuration;
if (!duration) {
duration = course._courseDetails.duration[0];
}
course._courseDetails.startDates.each(function(item, index) {
// check if the same courses is already added
var toAdd = true;
if (sameCoursesPeriods.length) {
for (var j = 0; j < sameCoursesPeriods.length; j++) {
if ((item >= sameCoursesPeriods[j].startDate && item <= sameCoursesPeriods[j].endDate)) {
toAdd = false;
}
}
}
if (toAdd) {
// the minimal end date is the date minus the minimal course duration
if(course.getCourseDetails().oneDayCourse){
minimalEndDate = new Date(item.getFullYear(), item.getMonth(), item.getDate());
} else {
minimalEndDate = new Date(item.getFullYear(), item.getMonth(), item.getDate() + 7 * duration);
}
minimalEndDate = course.getOptionalCourseEndDate(minimalEndDate);
for (var i = 0; i < periods.length; i++) {
if (item >= periods[i].startDate && minimalEndDate <= periods[i].endDate) {
var year = item.getFullYear();
var week = item.getWeek();
if (course.getCourseDetails().courseStartDay == 7) {
if (week > 1)week = week + 1;
}
// check the availabilities for this start date
var toAdd = true;
if (availabilities) {
for (var i = 0; i < duration; i++) {
if (week > 52) {
var lastWeek = (new Date(item.getFullYear(), 12, 31)).getWeek();
if (week < lastWeek) {
week = week - lastWeek;
year = year + 1;
}
}
if (availabilities[year + '' + week] == 0) {
toAdd = false;
}
week++;
}
}
// if the item can be added
if (toAdd) {
validStartDates.include(item);
break;
}
}
}
}
}.bind(this));
return validStartDates;
},
/**
* Returns the valid courses date session for a given period based on a courseObject
*
* @param SchoolCoursesObject course The course object, if empty we consider that we want to add a new course
*
* @return Array An array of valid durations
*/
getValidOptionalCourseDuration : function(course) {
var validDurations = new Array();
var sameCoursesPeriods = new Array();
var addedCourses = this.getValidAddedCourses();
var sameCourses = new Array();
var periods = new Array();
var availabilities = course.getCourseDetails().availabilities;
var additionalDays = course.getCourseDetails().additionalDays;
if(addedCourses.length){
for (var i = 0; i < addedCourses.length; i++) {
if (addedCourses[i].getCourseDetails().type != 'optional' && addedCourses[i].getCourseDetails().availableOptionalCourses.contains(parseInt(course.getCourseDetails().id))) {
var period = new Object();
period.startDate = (new Date()).fromIso(addedCourses[i].getDTO().startDate);
period.endDate = (new Date()).fromIso(addedCourses[i].getDTO().endDate);
if(additionalDays){
period.endDate.setDate(period.endDate.getDate() + additionalDays);
}
periods.push(period);
}
if (addedCourses[i].getCourseDetails().type == 'optional' && addedCourses[i].getCourseDetails().id == course.getCourseDetails().id && addedCourses[i] != course) {
sameCourses.push(addedCourses[i]);
}
}
if (sameCourses.length) {
for (var i = 0; i < sameCourses.length; i++) {
var period = new Object();
period.startDate = sameCourses[i]._courseStartDate;
period.endDate = sameCourses[i]._courseEndDate;
sameCoursesPeriods.push(period);
}
}
var optionEndDate = '';
var week = -1;
var year = -1;
if (course.getCourseStartDate()) {
week = course.getCourseStartDate().getWeek();
year = course.getCourseStartDate().getFullYear();
if(course.getCourseDetails().courseStartDay== 7){
if(week > 1)week = week+1;
}
}
// for each duration
for (var i = 0; i < (course.getCourseDetails().duration.length); i++) {
var value = course.getCourseDetails().duration[i];
// check if there is an availability
if (week == -1 || !availabilities ||
availabilities[year + '' + (week + parseInt(value) - 1)] != 0) {
var toAdd = true;
// the minimal end date is the date minus the minimal course duration
if (course._courseStartDate) {
optionEndDate = new Date(course._courseStartDate.getFullYear(), course._courseStartDate.getMonth(), course._courseStartDate.getDate() + 7 * value);
optionEndDate = course.getOptionalCourseEndDate(optionEndDate);
} else {
optionEndDate = new Date(periods[0].startDate.getFullYear(), periods[0].startDate.getMonth(), periods[0].startDate.getDate() + 7 * value);
}
// check each periods of courses it can be attached
for (var j = 0; j < periods.length; j++) {
if (course._courseStartDate >= periods[j].startDate && optionEndDate <= periods[j].endDate || !course._courseStartDate) {
// and check the end date meets the right range.
for (var k = 0; k < sameCoursesPeriods.length; k++) {
if (optionEndDate >= sameCoursesPeriods[k].startDate && optionEndDate < sameCoursesPeriods[k].endDate) {
toAdd = false;
}
}
if (toAdd) {
validDurations.include(value);
break;
}
}
}
// if there is no more availability, the valid durations stops here
}else{
break;
}
}
}
return validDurations;
},
/**
* Returns the valid courses date session for a given period based on a courseObject
*
* @param SchoolCoursesObject course The course object, if empty we consider that we want to add a new course
*
* @return Array An array of valid durations
*/
getValidVariableCourseDuration : function(course) {
var validDurations = new Array();
var startDate = new Date();
var endDate = new Date(startDate.getFullYear() + 10, startDate.getMonth(), startDate.getDate());
var calculatedEndDate;
var availabilities = course.getCourseDetails().availabilities;
// if the course is not the last one and there are more than one course
if (course != this._courses.getLast() && this._courses.length > 1) {
for (var i = this._courses.indexOf(course) + 1; i < this._courses.length; i++) {
if (this._courses[i].getCourseDetails().type != 'optional' && this._courses[i]._courseStartDate)endDate = this._courses[i]._courseStartDate;
}
}
// if this courses is not the first
if (this._courses.indexOf(course) > 0) {
for (var i = this._courses.indexOf(course) - 1; i >= 0; i--) {
if (this._courses[i]._courseEndDate)startDate = this._courses[i]._courseEndDate;
}
}
var week = -1;
var year = -1;
if (course.getCourseStartDate()) {
week = course.getCourseStartDate().getWeek();
year = course.getCourseStartDate().getFullYear();
if(course.getCourseDetails().courseStartDay == 7){
if(week > 1)week = week+1;
}
}
// find the default start date, usefull when the start date is not the same as the course information one
if(course.getCourseStartDate()){
var defaultCourseStartDate = new Date(course.getCourseStartDate());
// if the course start day is not the same as the given in the course informations
if (defaultCourseStartDate && course.getCourseDetails().courseStartDay && course.getCourseDetails().courseStartDay !=  defaultCourseStartDate.getDay()) {
var courseStartDayUp = (defaultCourseStartDate.getDay() == 0 ? 7 : defaultCourseStartDate.getDay());
var courseStartDayDown = courseStartDayUp;
var iter = 0;
while (course.getCourseDetails().courseStartDay != courseStartDayDown && course.getCourseDetails().courseStartDay != courseStartDayUp) {
if (courseStartDayDown == 0)courseStartDayDown = 7;
if (courseStartDayUp == 8)courseStartDayUp = 1;
courseStartDayDown--;
courseStartDayUp++;
iter++;
}
if (courseStartDayDown == course.getCourseDetails().courseStartDay) {
defaultCourseStartDate.setDate(defaultCourseStartDate.getDate() - iter);
} else {
defaultCourseStartDate.setDate(defaultCourseStartDate.getDate() + iter);
}
}
}
for (var i = 0; i < (course.getCourseDetails().duration.length); i++) {
var value = course.getCourseDetails().duration[i];
// the minimal end date is the date minus the minimal course duration
if (defaultCourseStartDate) {
calculatedEndDate = new Date(defaultCourseStartDate.getFullYear(), defaultCourseStartDate.getMonth(), defaultCourseStartDate.getDate() + 7 * value);
} else {
calculatedEndDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate() + 7 * value);
}
if (defaultCourseStartDate >= startDate && calculatedEndDate <= endDate || !defaultCourseStartDate) {
var currentYear = year;
var currentWeek = week;
if(currentWeek > 52){
currentWeek = currentWeek - 52;
currentYear = currentYear + 1;
}
if (currentWeek == -1 || !availabilities ||
availabilities[currentYear + '' + (currentWeek + parseInt(value) - 1)] != 0) {
validDurations.push(value);
} else {
break;
}
}
}
return validDurations;
},
/**
* Returns the accommodation start date
*
* @optionalparam AccommodationDTO accommodation The Accommodation DTO
*
* @return Date The  possible start date
*/
getAccommodationStartDate : function() {
var newDate = null;
this._courses.each(function(item, index) {
// check if the course is complete
if (item.isComplete()) {
// if it is a fixed Course
if (item.getIsFixedCourse()) {
// if this accommodation is available with this course
if (newDate > item._courseDetails.sessions[item._session].accommodationStartDate || newDate == null) {
newDate = new Date(item._courseDetails.sessions[item._session].accommodationStartDate);
}
// if it's a variable course
} else {
// if this accommodation is available with this course
// the new date is set
if (newDate > item._courseStartDate || newDate == null) {
newDate = new Date(item._courseStartDate);
}
}
}
}.bind(this));
return newDate;
},
/**
* Returns the maximal final date
*
* @return Date The end date for the accommodations
*/
getAccommodationEndDate : function() {
var endDate = new Date();
if (this._courses.length) {
for (var i = 0; i < this._courses.length; i++) {
if (this._courses[i].getCourseDetails().type != 'optional' && this._courses[i].isComplete()) {
if (this._courses[i].getIsFixedCourse()) {
endDate = new Date(this._courses[i]._courseDetails.sessions[this._courses[i]._session].accommodationEndDate);
} else {
endDate = new Date(this._courses[i]._courseEndDate);
}
}
}
}
return endDate;
},
/**
*  Returns the available accommodations
*
* @return Array of integer The Accommodation IDs
*/
getAvailableAccommodations : function() {
var availableAccommodations = new Array();
for (var i = 0; i < this._courses.length; i++) {
if (this._courses[i].getCourseDetails().type != 'optional') {
availableAccommodations = availableAccommodations.merge(this._courses[i].getAvailableAccommodations());
}
}
return availableAccommodations;
},
/**
* Return an array containing the mandatory accommodations with their start and end date
*
* @return Array of MandatoryAccommodationsDTO
*/
getMandatoryAccommodations : function() {
var mandatoryAccommodations = new Array();
for (var i = 0; i < this._courses.length; i++) {
if (this._courses[i].getCourseDetails().type != 'optional' && this._courses[i].getCourseDetails().accommodationMandatory == true) {
var mandatoryAccommodation = new Object();
mandatoryAccommodation.courseId = this._courses[i].getCourseDetails().id;
mandatoryAccommodation.ids = this._courses[i].getCourseDetails().availableAccommodations;
mandatoryAccommodation.startDate = this._courses[i].getDTO().startDate;
mandatoryAccommodation.endDate = this._courses[i].getDTO().endDate;
mandatoryAccommodations.push(mandatoryAccommodation);
}
}
return mandatoryAccommodations;
},
/**
* Return true if the transfer is mandatory
*
* @return boolean true if the transfers are mandatory
*/
getIsTransferMandatory : function() {
var mandatory = false;
for (var i = 0; i < this._courses.length; i++) {
if (this._courses[i].getCourseDetails().type != 'optional' && this._courses[i].getCourseDetails().transferMandatory == true) {
mandatory = true;
}
}
return mandatory;
},
/**
* Display or hide the optional course add button
*
* @param boolean isDisplayed True to display the hide button
*/
displayAddButton : function(isDisplayed){
if (this._optionalCourseAddButton) {
if (isDisplayed) {
this._optionalCourseAddButton.setStyle('display', 'block');
} else {
this._optionalCourseAddButton.setStyle('display', 'none');
}
}
},
/**
* Returns the parent of this object
*
* @return SchoolPriceEstimation The parent object
*/
getParent : function() {
return this._parent;
}
});/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @param TransferListItemDTO schoolTransfersDTO the transfers informations
* @param SchoolPriceEstimation parent the parent
**/
var SchoolCurrencySelector = Events.extend({
/**
* This is the initialization function
* @param TranslateDTO translateDTO The DTO containing the translations
* @param String defaultCurrency The default currency
* @param Array currenciesList An array containing all the currencies
* @param Object parent The parent
*/
initialize : function(translateDTO, defaultCurrency, currenciesList,parent) {
this._translateDTO = translateDTO;
this._parent = parent;
this._classNameBase = this._parent.getClassNameBase();
this._currencyAvailableList = currenciesList;
this._currency = defaultCurrency;
},
/**
* return the visual transfer container
*/
getHtml : function() {
this._currencyContainer = new Element('div', {'class': this._classNameBase + 'Currency-Section'});
this._currencyTitle = new Element('div', {'class': this._classNameBase + 'Currency-Section-Title'});
this._currencyTitleText = new Element('div', {'class': this._classNameBase + 'Participants-Section-Title-Text'});
this._currencyTitleText.injectInside(this._currencyTitle);
this._currencyButtons = new Element('div', {'class': this._classNameBase + 'AddButton'});
this._currencyButtons.addClass( this._classNameBase + 'CurrencyButton');
this._currencyTitle.injectInside(this._currencyContainer);
//        this._currencyButtons.injectInside(this._currencyContainer);
this._currencyTitleText.setHTML(this._translateDTO.title);
this._currencyButtons.setHTML(this._currency);
this._currencyButtons.injectInside(this._currencyTitle);
this._currencyList = new SchoolList(this._currencyButtons, this._classNameBase);
this.createVisualList(this._currencyList);
this._currencyList.getHtml().injectInside(this._parent.getListContainer());
this._currencyList.initializeEvents();
return this._currencyContainer;
},
/**
* Generate the list of currency
*
* @param SchoolList list The list to update
*/
createVisualList : function(list) {
for (var i = 0; i < this._currencyAvailableList.length; i++) {
list.addItem(this._currencyAvailableList[i].currencyCode, this._currencyAvailableList[i].currencyName + " (" + this._currencyAvailableList[i].currencyCode  + ")");
}
list.getListItems().each(function(item, index) {
item.setIsValid(true);
item.setIsSelectionnable(true);
if (item.getValue() == this._currency) {
this._currencyButtons.setHTML(item.getHtmlValue());
list.setSelectedItem(item);
}
item.getHtml().addEvent('click', function(event) {
this._currencyButtons.setHTML(item.getHtmlValue());
this._currency = item.getValue();
this._parent.fireEvent('refreshPrice');
list.setSelectedItem(item);
}.bind(this));
}.bind(this));
},
/**
* Returns the number of currency
*
* @return number The number of currency
*/
getCurrency : function() {
return this._currency;
},
/**
* Set the currency
*
* @param String currency the currency code to use
*/
setCurrency : function(currency){
this._currency  = currency;
this._currencyButtons.setHTML(currency);
}
});/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @event Event deleteCourse This event is fired when a course is deleted
*
* @param FixedDatesCourseListItemDTO courseDetails The object containing the course informations
* @param Object translateDTO The object containing all the translations for this class
* @param SchoolCourses parent The parent
*
**/
var SchoolFixedCourseObject = Events.extend({
/**
* This is the initialization function
*/
initialize : function(courseDetails, translateDTO, listContainer, classNamePrefix ,parent) {
this._translateDTO = translateDTO;
this._courseDetails = courseDetails;
this._parent = parent;
this._listContainer = listContainer;
this._classNameBase = classNamePrefix;
this._dateFormat = this._parent.getParent().getDateFormat();
this._monthsTranslations = this._parent.getParent().getMonthTranslations();
this._courseStartDate = null;
this._courseEndDate = null;
this._courseDuration = null;
this._manager = this._parent.getParent().getParent();
this._manager.addEvent('descriptionsUpdated', function(){
this.updateDescriptions();
}.bind(this));
},
/**
* Return the course details DTO
*
* @return CourseDetailsDTO The course Details DTO
*/
getCourseDetails : function() {
return this._courseDetails;
},
/**
* Returns true if the course is complete
*
* @return boolean true if the course is complete
*/
isComplete : function() {
if (this._courseStartDate && this._courseEndDate && this._courseDuration) {
return true;
} else {
return false;
}
},
/**
* Generate the html structure of the course
* and add an event on the delete button
*
*/
createVisualCourse : function() {
this._container = new Element('div', {'class': this._classNameBase + 'ItemAdded'});
this._title = new Element('div', {'class': this._classNameBase + 'Section-Item-Title'});
this._subTitle = new Element('div', {'class': this._classNameBase + 'Section-Item-SubTitle'});
this._moreInfo = new Element('div', {'class': this._classNameBase + 'Section-Item-SubTitle MoreInfos'});
this._moreInfo.setStyle('display','none');
this._startDateContainer = new Element('div', {'class': this._classNameBase + 'Section-Item-StartDate-Container'});
this._endDateContainer = new Element('div', {'class': this._classNameBase + 'Section-Item-EndDate-Container'});
this._startDate = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._startDateValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Value ' + this._classNameBase + 'Section-Item-ToUpdate'});
this._endDate = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._endDateValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-ValueNotEditable'});
this._durationDateContainer = new Element('div', {'class': this._classNameBase + 'Section-Item-Duration-Container'});
this._duration = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._durationValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-ValueNotEditable'});
this._deleteButton = new Element('div', {'class': this._classNameBase + 'Section-Item-DeleteButton'});
this._duration.injectInside(this._durationDateContainer);
this._durationValue.injectInside(this._durationDateContainer);
this._startDate.injectInside(this._startDateContainer);
this._startDateValue.injectInside(this._startDateContainer);
this._endDate.injectInside(this._endDateContainer);
this._endDateValue.injectInside(this._endDateContainer);
this._title.injectInside(this._container);
this._subTitle.injectInside(this._container);
this._moreInfo.injectInside(this._container);
new Element('div',{'style':'clear:both'}).injectInside(this._container);
this._startDateContainer.injectInside(this._container);
this._endDateContainer.injectInside(this._container);
this._durationDateContainer.injectInside(this._container);
this._deleteButton.injectInside(this._container);
new Element('div',{'style':'clear:both'}).injectInside(this._container);
this._title.setHTML(this._courseDetails.name);
this._subTitle.setHTML(this._courseDetails.subtitle);
this._moreInfo.setHTML(this._translateDTO.moreInfos);
this._startDate.setHTML(this._translateDTO.startDate);
this._startDateValue.setHTML(this._translateDTO.dateSelect);
this._endDate.setHTML(this._translateDTO.endDate);
this._endDateValue.setHTML(this._translateDTO.endDateValue);
this._duration.setHTML(this._translateDTO.duration);
this._durationValue.setHTML(this._translateDTO.durationSelect);
this._deleteButton.setHTML(this._translateDTO.deleteButton);
// add event listener
this._deleteButton.addEvent('click', function(e) {
this.removeCourse();
this.fireEvent('deleteCourse');
}.bind(this));
this.updateDescriptions();
this._coursesValidList = new SchoolList(this._title, this._classNameBase);
this.getVisualValidCoursesList(this._coursesValidList);
this._coursesValidList.getHtml().injectInside(this._listContainer);
this._coursesValidList.initializeEvents();
this._schoolSessionsList = new SchoolList(this._startDateValue, this._classNameBase);
this.getVisualFixedCourseStartDates(this._courseDetails.sessions, this._schoolSessionsList);
this._schoolSessionsList.getHtml().injectInside(this._listContainer);
this._schoolSessionsList.initializeEvents();
this.refreshLists();
},
/**
* Returns the html Element of this course
*
* @return Element The Html view of this course
*/
getHtml : function() {
return this._container;
},
updateDescriptions : function(){
if (this._manager.getDescription && this._manager.getDescription('course', this._courseDetails.courseTypeId) && this._manager.getDescription('course', this._courseDetails.courseTypeId) != '') {
this._moreInfo.setAttribute('title', this._courseDetails.name + ' :: ' + this._manager.getDescription('course', this._courseDetails.courseTypeId));
this._moreInfo.setStyle('display','');
if(!this._descriptionToolTip ){
this._descriptionToolTip = new SynergeeTips(this._moreInfo, {'className':'PriceEstimationToolTip', 'hideDelay':1000, 'fixed':true, 'closeButton':true, 'maxHeight':280});
}else {
this._descriptionToolTip.build(this._moreInfo);
}
}else {
this._moreInfo.setStyle('display','none');
}
},
/**
* return the course start date
*
* @return Date The course start date
*/
getCourseStartDate : function() {
return this._courseStartDate;
},
/**
* return the course start date
*
* @return Date The course start date
*/
getCourseEndDate : function() {
return this._courseEndDate;
},
/**
* return the accommodation end date for this course
*
* @return Date The accommodation end date date
*/
getAccommodationEndDate : function() {
return this._courseDetails.sessions[this._session].accommodationEndDate;
},
/**
* Returns an object containing the informations for the calculation price
*
* @return Object The informations needed to calculate the price
*/
getDTO : function() {
var courseDTO = new Object();
courseDTO.id = this._courseDetails.id;
courseDTO.startDate = this._courseStartDate.toIso();
courseDTO.endDate = this._courseEndDate.toIso();
return courseDTO;
},
/**
* Populate the fixed course from a dto
*
* @param Object The fixed course informations needed to populate
*/
populateFromDTO : function(toPopulateDTO) {
var courseInfos = new Object();
courseInfos.courseStartDate = (new Date()).fromIso(toPopulateDTO.startDate);
courseInfos.courseEndDate = (new Date()).fromIso(toPopulateDTO.endDate);
// Set the variables for this course
this._courseStartDate = courseInfos.courseStartDate;
this._courseEndDate = courseInfos.courseEndDate;
this._courseDuration = this.getCalculatedDuration(courseInfos.courseStartDate, courseInfos.courseEndDate);
// set the visual data of this course
this._startDateValue.setHTML(courseInfos.courseStartDate.format(this._dateFormat, this._monthsTranslations));
this._endDateValue.setHTML(courseInfos.courseEndDate.format(this._dateFormat, this._monthsTranslations));
if (this._courseDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace("%0", this._courseDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._courseDuration));
}
// if the session hasn't been found (when the course is populated)
this._courseDetails.sessions.each(function(item, index) {
if (item.courseStartDate.format(this._dateFormat, this._monthsTranslations) == courseInfos.courseStartDate.format(this._dateFormat, this._monthsTranslations)) {
this._session = index;
}
}.bind(this));
},
/**
* Refresh all the lists of this course
*
*/
refreshLists : function() {
this.refreshVisualValidCoursesList(this._coursesValidList);
this.refreshVisualFixedCourseStartDates(this._parent.getValidFixedCourseSession(this), this._schoolSessionsList);
if(this._schoolSessionsList.getValidListItems().length == 1 ){
this._startDateValue.addClass(this._classNameBase + 'Section-Item-Info-ValueNotEditable');
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-Info-Value');
this._schoolSessionsList.removeButtonEvent();
if(this._courseStartDate != this._schoolSessionsList.getValidListItems()[0].getValue().courseStartDate
|| this._courseEndDate != this._schoolSessionsList.getValidListItems()[0].getValue().courseEndDate)this._schoolSessionsList.getValidListItems()[0].getHtml().fireEvent('click');
}else{
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-Info-ValueNotEditable');
this._startDateValue.addClass(this._classNameBase + 'Section-Item-Info-Value');
this._schoolSessionsList.addButtonEvent();
}
},
/**
* Regenerate all the lists of this course
*
*/
reGenerateLists : function() {
// remove old list if exists
if (this._coursesValidList.getListItems().length) {
this._coursesValidList.getHtml().remove();
this._coursesValidList.clear();
}
if (this._schoolSessionsList.getListItems().length) {
this._schoolSessionsList.getHtml().remove();
this._schoolSessionsList.clear();
}
// add the list of courses that fit the start and end Date
this.getVisualValidCoursesList(this._coursesValidList);
this._coursesValidList.getHtml().injectInside(this._listContainer);
this._coursesValidList.initializeEvents();
this.getVisualFixedCourseStartDates(this._courseDetails.sessions, this._schoolSessionsList);
this.refreshVisualFixedCourseStartDates(this._parent.getValidFixedCourseSession(this), this._schoolSessionsList);
this._schoolSessionsList.getHtml().injectInside(this._listContainer);
this._schoolSessionsList.initializeEvents();
},
/**
* Refresh the values when the user change a course information
*
* @param Object values The new values
*/
refreshFixedCourseData : function(values) {
// Set the variables for this course
this._courseStartDate = values.courseStartDate;
this._courseEndDate = values.courseEndDate;
this._courseDuration = this.getCalculatedDuration(values.courseStartDate, values.courseEndDate);
// set the visual data of this course
this._startDateValue.setHTML(values.courseStartDate.format(this._dateFormat, this._monthsTranslations));
this._endDateValue.setHTML(values.courseEndDate.format(this._dateFormat, this._monthsTranslations));
if (this._courseDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace("%0", this._courseDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._courseDuration));
}
// set the session number
this._session = this._courseDetails.sessions.indexOf(values);
// if the session hasn't been found (when the course is populated)
if (this._session == -1) {
this._courseDetails.sessions.each(function(item, index) {
if (item.courseStartDate.format(this._dateFormat, this._monthsTranslations) == values.courseStartDate.format(this._dateFormat, this._monthsTranslations)) {
this._session = index;
}
}.bind(this));
}
// refresh the valid course list for this period
if (this.isComplete()) {
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
this._parent.fireEvent('refreshCourses');
this._parent.fireEvent('refreshPrice');
}
},
/**
* Replace the courses and find the best possible dates
*
* @param Number newCourseId  The new course ID
*/
replaceCourse : function(newCourse) {
this._durationValue.removeClass(this._classNameBase + 'Section-Item-Info-ValueNotEditable');
if (this._parent.getIsFixedCourse(newCourse)) {
if (this.isComplete()) {
this._courseDetails = newCourse;
this._durationValue.addClass(this._classNameBase + 'Section-Item-Info-ValueNotEditable');
this.refreshFixedCourseData(this.getNewFixedCourseDates(this._courseStartDate));
this._title.setHTML(this._courseDetails.name);
this._subTitle.setHTML(this._courseDetails.subtitle);
this.reGenerateLists();
this._parent.fireEvent('refreshCourses');
} else {
this._schoolSessionsList.getHtml().remove();
this._coursesValidList.getHtml().remove();
this._parent.replaceCourse(this, newCourse);
}
} else {
this._schoolSessionsList.getHtml().remove();
this._coursesValidList.getHtml().remove();
if (this.isComplete()) {
var values = new Object();
values.startDate = this._courseStartDate;
values.duration = this._courseDuration;
this._parent.replaceCourse(this, newCourse, values);
} else {
this._parent.replaceCourse(this, newCourse);
}
}
},
/**
* Returns the best dates for the new fixed courses based on the old one
*
* @param Date oldStartDate The date of the replaced course
*
* @return Object The new dates session.
*/
getNewFixedCourseDates : function(oldStartDate) {
if (oldStartDate) {
var dateDifference;
var newDates;
this._courseDetails.sessions.each(function(item, index) {
if (dateDifference > Math.abs(oldStartDate - item.courseStartDate) || !dateDifference) {
dateDifference = Math.abs(oldStartDate - item.courseStartDate);
newDates = item;
}
}.bind(this));
return newDates;
}
},
/**
* Set a list of valid courses
*
* @param SchoolList list The valid courses list
*
*/
getVisualValidCoursesList : function(list) {
var validCourses = this._parent.getCourses();
// clearing the list
list.clear();
validCourses.each(function(item, index) {
list.addItem(item, item.name);
list.getListItems().getLast().getHtml().addClass(this._classNameBase + 'List-Item');
list.getListItems().getLast().getHtml().addEvent('click', function() {
this.replaceCourse(item);
}.bind(this));
}, this);
this.refreshVisualValidCoursesList(list);
},
/**
* Refresh a list of course that have possible dates between this courseStartDate and courseEndDate
*
* @param SchoolList list The valid courses list
*
*/
refreshVisualValidCoursesList : function(list) {
var validCourses = this._parent.getValidCourses(this);
list.getListItems().each(function(item, index) {
if (validCourses.indexOf(item.getValue()) != -1) {
item.setIsValid(true);
} else {
item.setIsValid(false);
}
}.bind(this));
},
/**
* Generate a formated list from an array of a fixed course start dates
*
* @param Array startDates An array of Date containing all the possible startDates
* @param SchoolList list The valid courses list
*/
getVisualFixedCourseStartDates : function(startDates, list) {
var firstValid = true;
var index = 0;
// clearing the list
list.clear();
startDates.each(function(item, index) {
list.addItem(item, item.courseStartDate.format(this._dateFormat, this._monthsTranslations));
index = list.getListItems().indexOf(list.getListItems().getLast());
list.getListItems().getLast().getHtml().addEvent('click', function() {
if (list.getListItems()[index].getIsSelectionnable())this.refreshFixedCourseData(item);
}.bind(this));
}.bind(this));
list.addItem('error', this._translateDTO.noValidStartDates);
if (list.getValidListItems().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* Refresh a list from an array of a fixed course start dates
*
* @param Array validStartDates An array of Date containing the validated startDates
* @param SchoolList list The valid courses list
*/
refreshVisualFixedCourseStartDates : function(validStartDate, list) {
var firstValid = true;
list.getListItems().each(function(item, index) {
if (validStartDate.indexOf(item.getValue()) != -1) {
item.setIsValid(true);
item.setIsSelectionnable(true);
if (firstValid)list.setSelectedItem(item);
if (this._courseStartDate == item.getValue().courseStartDate) list.setSelectedItem(item);
firstValid = false;
} else {
if (item.getValue == 'error')item.setIsValid(false);
item.setIsSelectionnable(false);
}
}.bind(this));
},
/**
* Return the duration in weeks.
* To perform the calculation we count the number of time the week day of the start date
* can be repeated between the start date and the end date.
*
* @param date startDate The start date
* @param date endDate The end date
* @return integer the number of weeks
*/
getCalculatedDuration : function(startDate, endDate) {
startDate = startDate.getTime();
endDate = endDate.getTime() - (86400 * 3 *1000) ;
var numberOfWeeks = 0;
while (startDate <= endDate) {
numberOfWeeks++;
startDate += (86400 * 7 * 1000);
}
return numberOfWeeks;
},
/**
*  Returns the available accommodations for this course
*
* @return Array of integer The Accommodation IDs
*/
getAvailableAccommodations : function() {
return this._courseDetails.availableAccommodations;
},
/**
*  return the course duration
*
* @return integer The course duration
*/
getCourseDuration : function() {
return this._courseDuration;
},
/**
* Returns true if it's a fixed course
*
* @return Boolean Return true because it's a fixed course
*/
getIsFixedCourse : function() {
return true;
},
/**
* This function remove the course from the list
*
*/
removeCourse : function() {
this._schoolSessionsList.getHtml().remove();
this._coursesValidList.getHtml().remove();
this._container.remove();
}
});
/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @param number id the insurance ID
* @param char name the insurance name
* @param SchoolInsurances parent
**/
var SchoolInsuranceObject = Events.extend({
/**
* This is the initialization function
*/
initialize : function(id, insuranceDTO, translateDTO, parent) {
this._translateDTO = translateDTO;
this._insuranceDTO = insuranceDTO;
this._insuranceName = this._insuranceDTO.name;
this._type = this._insuranceDTO.type;
this._insuranceId = id;
this._parent = parent;
this._classNameBase = this._parent.getClassNameBase();
this._isMandatory = false;
this._insuranceStartDate = null;
this._insuranceEndDate = null;
this._insuranceDuration = null;
this._manager = this._parent.getParent();
this._manager.addEvent('descriptionsUpdated', function() {
this.updateDescriptions();
}.bind(this));
},
/**
* Generate the Html structure of this insurance
*/
createVisualInsurance : function() {
this._container = new Element('div', {'class': this._classNameBase + 'ItemAdded'});
this._title = new Element('div', {'class': this._classNameBase + 'Section-Item-Title'});
this._moreInfo = new Element('div', {'class': this._classNameBase + 'Section-Item-SubTitle MoreInfos'});
this._moreInfo.setStyle('display', 'none');
this._startDateContainer = new Element('div', {'class': this._classNameBase + 'Section-Item-StartDate-Container'});
this._endDateContainer = new Element('div', {'class': this._classNameBase + 'Section-Item-EndDate-Container'});
this._startDate = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._startDateValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-ValueNotEditable'});
this._endDate = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._endDateValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-ValueNotEditable'});
this._durationContainer = new Element('div', {'class': this._classNameBase + 'Section-Item-Duration-Container'});
this._duration = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._durationValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-ValueNotEditable'});
this._deleteButton = new Element('div', {'class': this._classNameBase + 'Section-Item-DeleteButton'});
this._duration.injectInside(this._durationContainer);
this._durationValue.injectInside(this._durationContainer);
this._startDate.injectInside(this._startDateContainer);
this._startDateValue.injectInside(this._startDateContainer);
this._endDate.injectInside(this._endDateContainer);
this._endDateValue.injectInside(this._endDateContainer);
this._title.injectInside(this._container);
this._moreInfo.injectInside(this._container);
new Element('div', {'style':'clear:both'}).injectInside(this._container);
this._startDateContainer.injectInside(this._container);
this._endDateContainer.injectInside(this._container);
this._durationContainer.injectInside(this._container);
this._deleteButton.injectInside(this._container);
new Element('div', {'style':'clear:both'}).injectInside(this._container);
this._title.setHTML(this._insuranceName);
this._startDate.setHTML(this._translateDTO.startDate);
this._moreInfo.setHTML(this._translateDTO.moreInfos);
this._startDateValue.setHTML(this._translateDTO.dateSelect);
this._endDate.setHTML(this._translateDTO.endDate);
this._endDateValue.setHTML(this._translateDTO.endDateValue);
this._duration.setHTML(this._translateDTO.duration);
this._durationValue.setHTML(this._translateDTO.durationSelect);
this._deleteButton.setHTML(this._translateDTO.deleteButton);
// add event listener
this._deleteButton.addEvent('click', function(e) {
this.removeInsurance();
this.fireEvent('deleteInsurance');
}.bind(this));
this.updateDescriptions();
this._insuranceList = new SchoolList(this._title, this._classNameBase);
this.getVisualInsuranceList(this._insuranceList);
this._insuranceList.getHtml().injectInside(this._parent.getParent().getListContainer());
this._insuranceList.initializeEvents();
},
getInsuranceInformations : function() {
return this._insuranceDTO;
},
updateDescriptions : function() {
if (this._manager.getDescription && this._manager.getDescription('insurance', this._insuranceId) && this._manager.getDescription('insurance', this._insuranceId) != '') {
this._moreInfo.setAttribute('title', this._insuranceName + ' :: ' + this._manager.getDescription('insurance', this._insuranceId));
this._moreInfo.setStyle('display', '');
if (!this._descriptionToolTip) {
this._descriptionToolTip = new SynergeeTips(this._moreInfo, {'className':'PriceEstimationToolTip', 'hideDelay':1000, 'fixed':true, 'closeButton':true, 'maxHeight':280});
} else {
this._descriptionToolTip.build(this._moreInfo);
}
} else {
this._moreInfo.setStyle('display', 'none');
}
},
/**
* Returns an object containing the informations for the calculation price
*
* @return object The informations needed to calculate the price
*/
getDTO : function() {
var insuranceDTO = new Object();
insuranceDTO.id = this._insuranceId;
return insuranceDTO;
},
/**
* Return the insurance ID
*
* @return integer The Insurance ID
*/
getInsuranceId : function() {
return parseInt(this._insuranceId);
},
/**
* Populate the insurance from a dto
*/
populateFromDTO : function(toPopulateDTO) {
// there is nothing to populate in fact
},
setMandatory : function(mandatory) {
this._isMandatory = mandatory;
if (this._isMandatory) {
this._deleteButton.setStyle('display', 'none');
} else {
this._deleteButton.setStyle('display', '');
}
},
/**
* Set the dates of the insurance
* @param Date startDate The Start Date
* @param Date endDate The End Date
*/
setDates : function(startDate, endDate, duration) {
this._insuranceStartDate = startDate;
if (endDate)endDate.setDate(endDate.getDate() + this._insuranceDTO.additionalMandatoryDays);
this._insuranceEndDate = endDate;
this._insuranceDuration = duration + this._insuranceDTO.additionalMandatoryDays;
this.refreshInsuranceInterface();
},
/**
* Return true if the insurance is complete
*
* @return Boolean Return true if complete
*/
isComplete : function() {
if (this._insuranceStartDate && this._insuranceEndDate && this._insuranceDuration)return true;
return false;
},
/**
* Returns the HTML structure of this course
*
* @return Element the insurance element
*/
getHtml : function() {
return this._container;
},
/**
* Generate the list of insurances for this school
*
* @param schoolList list The list to update
*/
getVisualInsuranceList : function(list) {
list.clear();
this._parent._schoolInsurancesDTO.each(function(item, index) {
list.addItem(item.id, item.name);
list.getListItems().getLast().getHtml().addEvent('click', function() {
this.setInsurance(item);
}.bind(this));
}.bind(this));
if (!this._parent._schoolInsurancesDTO || this._parent.getParent().getCompletedCourses().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
this.refreshVisualInsuranceList();
},
/**
* refresh the list of insurances for this school
*
*/
refreshVisualInsuranceList : function() {
this._parent.refreshVisualInsuranceList(this._insuranceList);
},
/**
* Refresh the visual interface of this insurance
*
*/
refreshInsuranceInterface : function() {
if (this._insuranceStartDate && this._insuranceEndDate) {
this._startDateValue.setHTML(this._insuranceStartDate.format(this._parent.getParent().getDateFormat(), this._parent.getParent().getMonthTranslations()));
this._endDateValue.setHTML(this._insuranceEndDate.format(this._parent.getParent().getDateFormat(), this._parent.getParent().getMonthTranslations()));
if (this._insuranceDuration > 1) {
this._durationValue.setHTML(this._translateDTO.days.replace("%0", this._insuranceDuration));
} else {
this._durationValue.setHTML(this._translateDTO.day.replace("%0", this._insuranceDuration));
}
}
},
/**
* Replace the insurance with the one given in parameter
*
* @param Object insurance The insurance DTO
*/
setInsurance : function(insurance) {
this._insuranceName = insurance.name;
this._insuranceId = insurance.id;
this._type = insurance.type;
this._insuranceDTO = insurance;
this._title.setHTML(this._insuranceName);
this.updateDescriptions();
// the check will be done again by the insurances container
this.setMandatory(false);
this.fireEvent('refreshPrice');
},
/**
* Generate the options list for a insurance
* and set an event on each option
*
* @param SchoolList The list to update
*/
getVisualInsuranceOptionsList : function(list) {
list.clear();
list.getListItems().each(function(item, index) {
item.getHtml().addClass(this._classNameBase + 'List-Item');
item.getHtml().addEvent('click', function() {
this._parent.getParent().fireEvent('refreshPrice');
}.bind(this));
}.bind(this));
},
/**
* Remove the insurance from the list
*
*/
removeInsurance : function() {
this._container.remove();
}
});
/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @param InsuranceListItemDTO schoolInsurancesDTO the insurances informations
* @param Object translateDTO The DTO containing the translations for this class
* @param SchoolPriceEstimation parent the parent
**/
var SchoolInsurances = Events.extend({
/**
* This is the initialization function
*/
initialize : function(schoolInsurancesDTO, translateDTO, parent) {
this._schoolInsurancesDTO = schoolInsurancesDTO;
this._schoolInsurancesDTO = new Hash();
if (schoolInsurancesDTO) {
for (var i = 0; i < schoolInsurancesDTO.length; i++) {
this._schoolInsurancesDTO.set(schoolInsurancesDTO[i].id, schoolInsurancesDTO[i]);
}
}
this._translateDTO = translateDTO;
this._parent = parent;
this._classNameBase = this.getParent().getClassNameBase();
this._insurances = new Array();
this._mandatoryInsurances = new Array();
this._defaultCheckedInsurances = new Array();
this._schoolInsurancesDTO.each(function(item, index) {
if (item.mandatory) {
this._mandatoryInsurances.push(item);
}
if (item.defaultChecked) {
this._defaultCheckedInsurances.push(item);
}
}.bind(this));
},
/**
* Returns the visual insurance container
*/
getHtml : function() {
this._insuranceContainer = new Element('div', {'class': this._classNameBase + 'Section'});
this._insuranceTitle = new Element('div', {'class': this._classNameBase + 'Section-Title'});
this._insuranceListContainer = new Element('div', {'class': this._classNameBase + 'Courses-CoursesList-Container'});
this._insuranceUserAccommodationList = new Element('div', {'class': this._classNameBase + 'Courses-UserCoursesList'});
this._insuranceAddButton = new Element('div', {'class': this._classNameBase + 'AddButton'});
this._insuranceTitle.injectInside(this._insuranceContainer);
this._insuranceListContainer.injectInside(this._insuranceContainer);
this._insuranceUserAccommodationList.injectInside(this._insuranceListContainer);
this._insuranceAddButton.injectInside(this._insuranceContainer);
if (this._translateDTO) {
this._insuranceTitle.setHTML(this._translateDTO.title);
this._insuranceAddButton.setHTML(this._translateDTO.add);
}
this._insurancesList = new SchoolList(this._insuranceAddButton, this._classNameBase);
this.getVisualInsuranceList(this._insurancesList);
this._insurancesList.getHtml().injectInside(this._parent.getListContainer());
this._insurancesList.initializeEvents();
return this._insuranceContainer;
},
/**
*  Return the classNameBase
*/
getClassNameBase : function() {
return this._classNameBase;
},
/**
* Returns an array containing the informations for the calculation price
*
* @return Array The informations needed to calculate the price
*/
getDTO : function() {
var insurancesDTO = new Array();
this._insurances.each(function(item, index) {
if (item.isComplete()) {
insurancesDTO.push(item.getDTO());
}
}.bind(this));
return insurancesDTO;
},
/**
* Populate the insurances from a dto
*/
populateFromDTO : function(toPopulateDTO) {
if (toPopulateDTO) {
toPopulateDTO.each(function(item, index) {
this.addInsurance(item.id, true);
}.bind(this));
}
},
/**
* Retrieve the list of insurances for this school
*
* @param schoolList list The list to update
*/
getVisualInsuranceList : function(list) {
list.clear();
this._schoolInsurancesDTO.each(function(item, index) {
list.addItem(item.id, item.name);
list.getListItems().getLast().setIsValid(true);
list.getListItems().getLast().setIsSelectionnable(true)
list.getListItems().getLast().getHtml().addEvent('click', function() {
this.addInsurance(item.id);
}.bind(this));
}.bind(this));
this.refreshVisualInsuranceList(list);
},
/**
* Refresh the list of insurances for this school
*
* @param schoolList list The list to update
* @param availabilityItem boolean True if there is a last item to be used
*/
refreshVisualInsuranceList : function(list) {
var validListItem = 0;
list.getListItems().each(function(item, index) {
if (this._duration && (this._schoolInsurancesDTO.get(item.getValue()).availableFrom <= this._duration) &&  !this.isAdded(parseInt(item.getValue()))) {
item.setIsValid(true);
item.setIsSelectionnable(true);
validListItem++;
} else {
item.setIsValid(false);
}
}.bind(this));
if(validListItem){
this._insuranceAddButton.setStyle('display','');
}else {
this._insuranceAddButton.setStyle('display','none');
}
},
/**
* Refresh the value of the insurances (all insurances have the same duration)
*/
refreshValues : function() {
this._startDate = this.getInsuranceStartDate();
this._endDate = this.getInsuranceEndDate();
this._courseStartDate = this.getInsuranceStartDate(true);
this._courseEndDate = this.getInsuranceEndDate(true);
this._duration = this.getCalculatedDuration(this._startDate, this._endDate);
this._courseDuration = this.getCalculatedDuration(this._courseStartDate, this._courseEndDate);
if (this._insurances) {
for (var i = 0; i < this._insurances.length; i++) {
// Check if the insurance is calculated from the duration of the course
if(this._insurances[i].getInsuranceInformations().durationCalculationMethod == 1){
this._insurances[i].setDates(new Date(this._courseStartDate), new Date(this._courseEndDate), this._courseDuration);
} else {
this._insurances[i].setDates(new Date(this._startDate), new Date(this._endDate), this._duration);
}
}
}
},
/**
* Return the insurance start date calculated from the course and accommodation
*/
getInsuranceStartDate : function(courseOnly) {
if(!courseOnly)courseOnly = false;
return this._parent.getStartDate(courseOnly);
},
/**
* Return the insurance start date calculated from the course and accommodation
*/
getInsuranceCourseStartDate : function(courseOnly) {
if(!courseOnly)courseOnly = false;
return this._parent.getCourseStartDate(courseOnly);
},
/**
* Return the insurance end date calculated from the course and accommodation
*/
getInsuranceEndDate : function() {
return this._parent.getEndDate();
},
/**
* Return the durationof the insurance
*/
getInsuranceDuration : function() {
return this._duration;
},
/**
* Return the duration in days.
* To perform the calculation we count the number of time the week day of the start date
* can be repeated between the start date and the end date.
*
* @param date startDate The start date
* @param date endDate The end date
* @return integer the number of Days
*/
getCalculatedDuration : function(startDate, endDate) {
var numberOfDays = 0;
// The number of milliseconds in one day
var oneDay = 1000 * 60 * 60 * 24;
if (startDate && endDate && startDate.getTime && endDate.getTime) {
startDate = startDate.getTime();
endDate = endDate.getTime() + 1000;
var differenceMs = Math.abs(startDate - endDate)
numberOfDays = (Math.round(differenceMs/oneDay)) + 1;
}
return numberOfDays;
},
/**
* Refresh the insurances lists
*
*/
refreshInsurances : function() {
this.refreshValues();
var transfNb = this._insurances.length;
this.refreshVisualInsuranceList(this._insurancesList);
// refresh every insurance list for the added insurances
this._mandatoryInsurances.each(function(item, index) {
if (!this.isAdded(item.id)) {
var minDuration = (parseInt(item.mandatoryFrom) ? parseInt(item.mandatoryFrom) : 0);
var addedInsurance = null;
if (this._duration > 0 && minDuration <= this._duration) {
this.addInsurance(item.id);
if (addedInsurance = this.getAddedInsurance(item.id)) {
addedInsurance.setMandatory(true);
}
}
} else {
var minDuration = (parseInt(item.mandatoryFrom) ? parseInt(item.mandatoryFrom) : 0);
if (minDuration > this._duration) {
if (addedInsurance = this.getAddedInsurance(item.id)) {
addedInsurance.setMandatory(false);
}
}
}
}.bind(this));
// removing the insurances that are not meeting the min weeks
this._insurances.each(function(item, index){
if(this._schoolInsurancesDTO.get(item.getInsuranceId()).availableFrom > this._duration){
item.removeInsurance();
this._insurances.remove(item);
}
}.bind(this));
// remove all the insurance if there are no more course on the quote
if (this._parent.getCompletedCourses().length == 0) {
for (var i = this._insurances.length - 1; i >= 0; i--) {
this._insurances[i].removeInsurance();
this._insurances.remove(this._insurances[i]);
}
this._parent.fireEvent('heightModified');
if (transfNb > 0)this._parent.fireEvent('refreshPrice');
}else {
this._defaultCheckedInsurances.each(function(item, index) {
if (!this.isAdded(item.id)) {
this.addInsurance(item.id);
}
this._defaultCheckedInsurances.remove(item);
}.bind(this))
}
// refresh every insurance list for the added insurances
if (this._insurances) {
for (var i = 0; i < this._insurances.length; i++) {
this._insurances[i].refreshVisualInsuranceList();
}
}
},
/**
* Add a insurance from its ID
*
* @param Number id The insurance id
*/
addInsurance : function(id, noTest) {
if (this._schoolInsurancesDTO.hasKey(id) && (this._schoolInsurancesDTO.get(id).availableFrom <= this._duration  || noTest)  && !this.isAdded(id)) {
var schoolInsurance = this._schoolInsurancesDTO.get(id);
var newInsurance = new SchoolInsuranceObject(schoolInsurance.id, schoolInsurance, this._translateDTO.insuranceObject, this);
newInsurance.addEvent('refreshPrice', this.refreshPrice.bind(this));
this._insurances.push(newInsurance);
newInsurance.createVisualInsurance();
this._insurances.getLast().getHtml().injectInside(this._insuranceUserAccommodationList);
newInsurance.addEvent('deleteInsurance', function(e) {
this.deleteInsurance(newInsurance);
}.bind(this));
this.refreshPrice();
}
},
refreshPrice: function() {
this.fireEvent('refreshPrice');
},
/**
* Returns the parent of this object
*
* @return SchoolPriceEstimation The parent
*/
getParent : function() {
return this._parent;
},
/**
* Display or hide the add button
*
* @param boolean isDisplayed True to display the hide button
*/
displayAddButton : function(isDisplayed) {
if (isDisplayed) {
this._insuranceAddButton.setStyle('display', 'block');
} else {
this._insuranceAddButton.setStyle('display', 'none');
}
},
/**
* Returns the number of completed insurances
*
* @return Number The number of completed insurances
*/
getCompletedInsurances : function() {
return this._insurances;
},
/**
* Test if the insurance is added
*
* @param insuranceId The insurance id
*
* @return Boolean True if the insurance is added
*/
isAdded : function (insuranceId) {
insuranceId  = parseInt(insuranceId);
if (this._insurances) {
for (var i = 0; i < this._insurances.length; i++) {
if (this._insurances[i].getInsuranceId() == insuranceId)return true;
}
}
return false;
},
/**
* Return the added insurance from its id
* @param insuranceId integer The insurance ID
*
* @return SchoolInsuranceObject The insurance object
*
*/
getAddedInsurance : function (insuranceId) {
if (this._insurances) {
for (var i = 0; i < this._insurances.length; i++) {
if (this._insurances[i].getInsuranceId() == parseInt(insuranceId))return this._insurances[i];
}
}
return false;
},
/**
* Delete the given insurance
*
* @param SchoolInsuranceObject insurance The insurance to delete
*/
deleteInsurance : function(insurance) {
this._insurances.remove(insurance);
this._parent.fireEvent('heightModified');
this._parent.fireEvent('refreshPrice');
}
});/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @param Element button the button attached to the list
*
**/
var SchoolList = Events.extend({
/**
* This is the initialization function
*/
initialize : function(button, classNameBase) {
this._classNameBase = classNameBase;
this._listItems = new Array();
this._button = button;
this._list = this.setHtml();
this._list.setStyle('display', 'none');
this._selectedItem = -1;
this._buttonEventInitialized = false;
},
/**
* return true if the event on the list button is initialized
*
* @return boolean True if initialized
*/
getButtonEventInitialized : function() {
return this._buttonEventInitialized;
},
/**
*  Create the HTML structure
*
* @return Element The div container
*/
setHtml : function() {
return new Element('div', {'class': this._classNameBase + 'List', 'style':'display:none'});
},
/**
* This method add an element to the list
*
* @param Object value The value of the item
* @param String html The html value of the item
*/
addItem : function(value, html) {
var newItem = new SchoolListItem(value, html, this._classNameBase);
this._listItems.push(newItem);
newItem._listItem.injectInside(this._list);
},
/**
* This method add an element to the list
*
* @param SchoolListItem listItem The school list item
*/
addListItem : function(schooListItem) {
this._listItems.push(schooListItem);
schooListItem._listItem.injectInside(this._list);
},
/**
* this method clear the list
*/
clear : function() {
this._listItems = new Array();
this._list = this.setHtml();
},
/**
* This method return the list html formatted
*
* @return Element The list element
*/
getHtml : function() {
return this._list;
},
/**
* This method return the listItem Array
*
* @return Array The array containing all the list items
*/
getListItems : function() {
return this._listItems;
},
/**
* Returns the valid list items
*
* @return SchoolListItem[] The valid list items
*/
getValidListItems : function() {
var listItems = new Array();
this._listItems.each(function(item, index) {
if (item.getIsValid()) {
listItems.push(item);
}
});
return listItems;
},
/**
* Returns the height of a valid Item
*
* @return Number The height of a valid Item
*/
getItemHeight : function() {
var test = false;
var height = 0;
var i = 0;
while (!test) {
height = this._listItems[i].getHtml().getCoordinates().height;
test = this._listItems[i].getIsValid();
i++;
}
return height;
},
/**
* Returns the height of a list
*
* @return Number The height of this school list
*/
getListHeight : function() {
var height = 0;
this._listItems.each(function(item, index) {
if (item.getIsValid()) {
height = height + item.getHtml().getCoordinates().height;
}
});
return height;
},
/**
* This method set the item the list has to scroll to
*
* @param SchoolListItem item The item the list has to scroll to
*/
setSelectedItem : function(item) {
if (this._selectedItem != -1){
if(this._listItems[this._selectedItem])this._listItems[this._selectedItem].getHtml().removeProperty('id');
}
this._selectedItem = this._listItems.indexOf(item);
if(this._listItems[this._selectedItem])this._listItems[this._selectedItem].getHtml().setProperty('id', 'firstValid');
},
/**
* This method return the selected item
*
* @return SchoolListItem item The selected item
*/
getSelectedItem : function() {
if (this._selectedItem != -1){
if(this._listItems[this._selectedItem])
return this._listItems[this._selectedItem];
}
return null;
},
/**
*  Initialize the main events for this list
*/
initializeEvents : function() {
//        if (this.getValidListItems().length) {
var myTimer = -1;
// add the mouseleave event on the list
this.getHtml().addEvent('mouseleave', function() {
myTimer = this.getHtml().setStyles.delay(500, this.getHtml(), {'visibility':'hidden','display':'none', 'z-index':0});
}.bind(this));
this.getHtml().addEvent('mouseover', function() {
$clear(myTimer);
});
this._listItems.each(function(item, index) {
item.getHtml().addEvent('click', function() {
if (!(item.getValue() == 'category' || item.getValue() == 'error' )) {
this.getHtml().setStyle('visibility', 'hidden');
this.getHtml().setStyle('display', 'none');
this.getHtml().setStyle('height', '0px');
}
}.bind(this));
}.bind(this));
// add an event on the button to appear the list
this.addButtonEvent();
//        }
},
/**
* Return the list button
*/
getButton : function(){
return this._button;
},
/**
* add the event on the list button
*/
addButtonEvent : function(){
if(!this._buttonEventInitialized)this._button.addEvent('click', this.buttonClickEvent.bind(this));
this._buttonEventInitialized = true;
},
/**
*  remove the button event for this button
*/
removeButtonEvent : function() {
if(this._buttonEventInitialized)this._button.removeEvent('click', this.buttonClickEvent.bind(this));
if(this._buttonEventInitialized)this._button.removeEvents();
this._buttonEventInitialized = false;
},
/**
* method to call when the button is clicked
*/
buttonClickEvent : function() {
// add an event on the button to appear the list
var scroll = new Fx.Scroll(this._list);
var listHeight = parseInt(this.getHtml().getStyle('max-height'));
if (!listHeight) listHeight = 165;
this.getHtml().setStyle('height', '0px');
if(window.ie6){
this.getHtml().setStyle('width', this._button.getCoordinates().width + 'px');
}else{
this.getHtml().setStyle('min-width', this._button.getCoordinates().width + 'px');
}
this.setPosition();
this.getHtml().setStyle('display', 'block');
// the list is scrolled to the first valid element
if (this.getHtml().getElements('div[id=firstValid]')[0]) {
scroll.toElement(this.getHtml().getElements('div[id=firstValid]')[0]);
}
// set the overflow-y auto if the list is taller than the list
if (this.getListHeight() > listHeight) {
this.getHtml().setStyle('overflow-y', 'auto');
if(window.ie6){
this.getHtml().setStyle('width', (parseInt(this.getHtml().getStyle('width')) + 15) + 'px');
}else{
this.getHtml().setStyle('min-width', (parseInt(this.getHtml().getStyle('width')) + 15) + 'px');
}
new Fx.Style(this.getHtml(), 'height', {transition : Fx.Transitions.Quart.easeOut}).start('0', (listHeight) + 'px');
} else {
new Fx.Style(this.getHtml(), 'height', {transition : Fx.Transitions.Quart.easeOut}).start('0', this.getListHeight() + 'px');
}
this.getHtml().setStyle('visibility', 'visible');
this.getHtml().setStyle('z-index', 1000);
},
deleteList : function(){
this.removeButtonEvent();
if(this.getHtml().getParent())this.getHtml().remove();
},
/**
* This function Set the list position relative to its button
*
*/
setPosition : function() {
this._list.setStyle('left', this._button.getCoordinates().left);
this._list.setStyle('top', this._button.getCoordinates().top);
}
});/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @param Object value The value of the item
* @param String html The visual value of the item
*
**/
var SchoolListItem = Events.extend({
/**
* This is the initialization function
*/
initialize : function(value, html, classNameBase) {
this._classNameBase = classNameBase;
this._value = value;
this._html = html;
this.setVisualHtml();
this._isValid = true;
this._isSelectionnable = true;
},
/**
* Create the HTHML part of the item
*/
setVisualHtml : function() {
this._listItem = new Element('div');
this._listItem.setHTML(this._html);
this._listItem.listItemContainer = this;
},
/**
* set the new html value
*
* @param html String the new html value
*/
setHtml : function(html){
this._html = html;
this._listItem.setHTML(this._html);
},
/**
* Returns the element
*
* @return Element The list item
*/
getHtml : function() {
return this._listItem;
},
/**
* Returns the html value of the item
*
* @return Element The Html view of the item
*/
getHtmlValue : function() {
return this._html;
},
/**
* Returns the element value
*
* @return Object The item value
*/
getValue : function() {
return this._value;
},
/**
*  Set the validity of a list item
*
* @param Boolean validity The new validity of the list item
*/
setIsValid : function(validity) {
if (validity) {
this.getHtml().setStyle('display', 'block');
} else {
this.getHtml().setStyle('display', 'none');
}
this._isValid = validity;
},
/**
* Returns true if the item is valid
*
* @return Boolean Return true if the item is valid
*/
getIsValid : function() {
return this._isValid;
},
/**
* This method set if an item is selectionnable or not
*
* @param Boolean value Set true if the item is selectionnable
*/
setIsSelectionnable : function(value) {
if (value) {
this.getHtml().addClass(this._classNameBase + 'List-Item');
this.getHtml().removeClass(this._classNameBase + 'NotSelectionable');
} else {
this.getHtml().addClass(this._classNameBase + 'NotSelectionable');
this.getHtml().removeClass(this._classNameBase + 'List-Item');
}
this._isSelectionnable = value;
},
/**
* Returns true if the item is selectionnable
*
* @return Boolean Returns true if the item is selectionnable
*/
getIsSelectionnable : function() {
return this._isSelectionnable;
}
});/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @event Event deleteCourse This event is fired when a course is deleted
*
* @param FixedDatesCourseListItemDTO courseDetails courseDetails The object containing the course informations
* @param Object translateDTO The object containing all the translations for this class
* @param SchoolCourses parent The parent
*
**/
var SchoolOptionalCourseObject = Events.extend({
/**
* This is the initialization function
*
*/
initialize : function(courseDetails, translateDTO, listContainer, classNamePrefix, parent) {
this._translateDTO = translateDTO;
this._courseDetails = courseDetails;
this._parent = parent;
this._listContainer = listContainer;
this._classNameBase = classNamePrefix;
this._dateFormat = this._parent.getParent().getDateFormat();
this._monthsTranslations = this._parent.getParent().getMonthTranslations();
this._courseStartDate = null;
this._courseEndDate = null;
this._courseDuration = null;
this._manager = this.getParent().getParent().getParent();
this._manager.addEvent('descriptionsUpdated', function(){
this.updateDescriptions();
}.bind(this));
},
/**
* Return the course details DTO
*
* @return CourseDetailsDTO The course Details DTO
*/
getCourseDetails : function() {
return this._courseDetails;
},
/**
* Return true if the course is complete
*
* @return Boolean Return true if the course is complete
*/
isComplete : function() {
if (this._courseStartDate && this._courseEndDate && this._courseDuration) {
return true;
} else {
return false;
}
},
/**
* Generate the html structure of the course
* and add an event on the delete button
*
*/
createVisualCourse : function() {
this._container = new Element('div', {'class': this._classNameBase + 'ItemAdded'});
this._title = new Element('div', {'class': this._classNameBase + 'Section-Item-Title'});
this._subTitle = new Element('div', {'class': this._classNameBase + 'Section-Item-SubTitle'});
this._moreInfo = new Element('div', {'class': this._classNameBase + 'Section-Item-SubTitle MoreInfos'});
this._moreInfo.setStyle('display','none');
this._startDateContainer = new Element('div',{'class': this._classNameBase + 'Section-Item-StartDate-Container'});
this._endDateContainer = new Element('div',{'class': this._classNameBase + 'Section-Item-EndDate-Container'});
this._startDate = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._startDateValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Value ' + this._classNameBase + 'Section-Item-ToUpdate'});
this._endDate = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._endDateValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-ValueNotEditable'});
this._durationContainer = new Element('div',{'class': this._classNameBase + 'Section-Item-Duration-Container'});
this._duration = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._durationValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Value ' + this._classNameBase + 'Section-Item-ToUpdate'});
this._deleteButton = new Element('div', {'class': this._classNameBase + 'Section-Item-DeleteButton'});
this._duration.injectInside(this._durationContainer);
this._durationValue.injectInside(this._durationContainer);
this._startDate.injectInside(this._startDateContainer);
this._startDateValue.injectInside(this._startDateContainer);
this._endDate.injectInside(this._endDateContainer);
this._endDateValue.injectInside(this._endDateContainer);
this._title.injectInside(this._container);
this._subTitle.injectInside(this._container);
this._moreInfo.injectInside(this._container);
new Element('div',{'style':'clear:both'}).injectInside(this._container);
this._startDateContainer.injectInside(this._container);
this._endDateContainer.injectInside(this._container);
this._durationContainer.injectInside(this._container);
this._deleteButton.injectInside(this._container);
new Element('div',{'style':'clear:both'}).injectInside(this._container);
this._title.setHTML(this._courseDetails.name);
this._subTitle.setHTML(this._courseDetails.subtitle);
this._moreInfo.setHTML(this._translateDTO.moreInfos);
this._startDate.setHTML(this._translateDTO.startDateOptional);
this._startDateValue.setHTML(this._translateDTO.dateSelectOptional);
this._endDate.setHTML(this._translateDTO.endDateOptional);
this._endDateValue.setHTML(this._translateDTO.endDateValueOptional);
this._duration.setHTML(this._translateDTO.durationOptional);
this._durationValue.setHTML(this._translateDTO.durationSelectOptional);
this._deleteButton.setHTML(this._translateDTO.deleteButtonOptional);
// add event listener
this._deleteButton.addEvent('click', function(e) {
this.removeCourse();
this.fireEvent('deleteCourse');
}.bind(this));
this.updateDescriptions();
this._coursesValidList = new SchoolList(this._title, this._classNameBase);
this.getVisualValidCoursesList(this._coursesValidList);
this._coursesValidList.getHtml().injectInside(this._listContainer);
this._coursesValidList.initializeEvents();
this._schoolStartList = new SchoolList(this._startDateValue, this._classNameBase);
this.getVisualOptionalCourseStartDates(this._courseDetails.startDates, this._schoolStartList);
this.refreshVisualOptionalCourseStartDates(this._parent.getValidOptionalCourseStartDate(this), this._schoolStartList);
this._schoolStartList.getHtml().injectInside(this._listContainer);
this._schoolStartList.initializeEvents();
this._schoolDurationList = new SchoolList(this._durationValue, this._classNameBase);
this.getVisualOptionalCourseDurationList(this._courseDetails.duration, this._schoolDurationList);
this.refreshVisualOptionalCourseDurationList(this._parent.getValidOptionalCourseDuration(this), this._schoolDurationList);
this._schoolDurationList.getHtml().injectInside(this._listContainer);
this._schoolDurationList.initializeEvents();
if(this._courseDetails.oneDayCourse){
this._duration.setStyle('display','none');
this._durationValue.setStyle('display','none');
}
},
/**
* Returns the html Element of this course
*
* @return Element The HTML view of this course
*/
getHtml : function() {
return this._container;
},
updateDescriptions : function(){
if (this._manager.getDescription && this._manager.getDescription('course', this._courseDetails.courseTypeId) && this._manager.getDescription('course', this._courseDetails.courseTypeId) != '') {
this._moreInfo.setAttribute('title', this._courseDetails.name + ' :: ' + this._manager.getDescription('course', this._courseDetails.courseTypeId));
this._moreInfo.setStyle('display','');
if(!this._descriptionToolTip ){
this._descriptionToolTip = new SynergeeTips(this._moreInfo, {'className':'PriceEstimationToolTip', 'hideDelay':1000, 'fixed':true, 'closeButton':true, 'maxHeight':280});
}else {
this._descriptionToolTip.build(this._moreInfo);
}
}else {
this._moreInfo.setStyle('display','none');
}
},
/**
* Return an object containing the informations for the calculation price
*
* @return Object The informations needed to calculate the price
*/
getDTO : function() {
var courseDTO = new Object();
courseDTO.id = this._courseDetails.id;
courseDTO.startDate = this._courseStartDate.toIso();
courseDTO.endDate = this._courseEndDate.toIso();
return courseDTO;
},
/**
* Populate the variable course from a dto
*
* @param Object The fixed course informations needed to populate
*/
populateFromDTO : function(toPopulateDTO) {
this._courseStartDate = (new Date()).fromIso(toPopulateDTO.startDate);
this._startDateValue.setHTML(this._courseStartDate.format(this._dateFormat, this._parent.getParent().getMonthTranslations()));
this._courseEndDate = (new Date()).fromIso(toPopulateDTO.endDate);
this._courseDuration = this.getCalculatedDuration(this._courseStartDate, this._courseEndDate );
if(this._courseDetails.duration.length && this._courseDuration < parseInt(this._courseDetails.duration[0])) this._courseDuration = parseInt(this._courseDetails.duration[0]);
if (this._courseDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace("%0", this._courseDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._courseDuration));
}
// If the start and the duration are set,  the end date is calculated
if (this._courseStartDate && this._courseDuration) {
this._courseEndDate = this.getOptionalCourseEndDate();
this._endDateValue.setHTML(this._courseEndDate.format(this._dateFormat, this._parent.getParent().getMonthTranslations()));
}
// when the user selects only the start date, the duration is set with the minimal value
if (this._courseStartDate && !this._courseDuration) {
this._courseDuration = this._courseDetails.duration[0];
if (this._courseDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace("%0", this._courseDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._courseDuration));
}
this._courseEndDate = this.getOptionalCourseEndDate();
this._endDateValue.setHTML(this._courseEndDate.format(this._dateFormat, this._parent.getParent().getMonthTranslations()));
}
},
/**
* Refresh all the lists of this course
*
*/
refreshLists : function() {
// add the list of courses that fit the start and end Date
this.refreshVisualValidCoursesList(this._coursesValidList);
// initialize the start date list and its event
this.refreshVisualOptionalCourseStartDates(this._parent.getValidOptionalCourseStartDate(this), this._schoolStartList);
// initialize the duration list and its event
this.refreshVisualOptionalCourseDurationList(this._parent.getValidOptionalCourseDuration(this), this._schoolDurationList);
},
/**
* Generate all the lists of this course
*
*/
reGenerateLists : function() {
// remove old list if exists
if (this._coursesValidList._listItems.length) {
this._coursesValidList.getHtml().remove();
this._coursesValidList.clear();
}
if (this._schoolStartList._listItems.length) {
this._schoolStartList.getHtml().remove();
this._schoolStartList.clear();
}
if (this._schoolDurationList._listItems.length) {
this._schoolDurationList.getHtml().remove();
this._schoolDurationList.clear();
}
this.getVisualValidCoursesList(this._coursesValidList);
this._coursesValidList.getHtml().injectInside(this._listContainer);
this._coursesValidList.initializeEvents();
this.getVisualOptionalCourseStartDates(this._courseDetails.startDates, this._schoolStartList);
this.refreshVisualOptionalCourseStartDates(this._parent.getValidOptionalCourseStartDate(this), this._schoolStartList);
this._schoolStartList.getHtml().injectInside(this._listContainer);
this._schoolStartList.initializeEvents();
this.getVisualOptionalCourseDurationList(this._courseDetails.duration, this._schoolDurationList);
this.refreshVisualOptionalCourseDurationList(this._parent.getValidOptionalCourseDuration(this), this._schoolDurationList);
this._schoolDurationList.getHtml().injectInside(this._listContainer);
this._schoolDurationList.initializeEvents();
},
/**
* Refresh the course data
*
*/
refreshOptionalCourseData : function() {
// If the start and the duration are set,  the end date is calculated
if (this._courseStartDate && this._courseDuration) {
this._courseEndDate = this.getOptionalCourseEndDate();
this._endDateValue.setHTML(this._courseEndDate.format(this._dateFormat, this._parent.getParent().getMonthTranslations()));
this._durationValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
}
// when the user selects only the start date, the duration is set with the minimal value
if (this._courseStartDate && !this._courseDuration) {
this._courseDuration = this._courseDetails.duration[0];
this._durationValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
if (this._courseDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace("%0", this._courseDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._courseDuration));
}
this._courseEndDate = this.getOptionalCourseEndDate();
this._endDateValue.setHTML(this._courseEndDate.format(this._dateFormat, this._parent.getParent().getMonthTranslations()));
}
if (this.isComplete()) {
this._durationValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
// refresh the course list
this._parent.fireEvent('refreshCourses');
this._parent.fireEvent('refreshPrice');
}
},
/**
*  Returns the endDate of a variable course
*
* @param Date endDate The enddate to calculate
* @return Date The variable course end date
*/
getOptionalCourseEndDate : function(endDate) {
if ((this._courseDetails.courseStartDay == this._courseDetails.courseEndDay && this._courseDetails.oneDayCourse)) {
if (!endDate)endDate = new Date(this._courseStartDate);
} else {
if (!endDate)endDate = new Date(this._courseStartDate.getFullYear(), this._courseStartDate.getMonth(), this._courseStartDate.getDate() + this._courseDuration * 7);
var endDateDay = endDate.getDay();
if (endDateDay == 0) endDateDay = 7;
while (endDateDay != this._courseDetails.courseEndDay) {
endDate.setDate(endDate.getDate() - 1);
endDateDay = endDate.getDay();
if (endDateDay == 0) endDateDay = 7;
}
}
return endDate;
},
/**
* Replace the courses and find the best possible dates
*
* @param Object The new course DTO
*/
replaceCourse : function(newCourse) {
this._durationValue.removeClass(this._classNameBase + 'Section-Item-Info-Value');
this._schoolStartList.getHtml().remove();
this._schoolDurationList.getHtml().remove();
this._coursesValidList.getHtml().remove();
if (this.isComplete()) {
this._parent.replaceCourse(this, newCourse, this._courseStartDate);
} else {
this._parent.replaceCourse(this, newCourse);
}
this.updateDescriptions();
},
/**
* this method find the best dates and duration for the new variable course based on the old one
*
* @param Date oldStartDate the date of the replaced course
* @param number oldDuration the duration of the replaced course
*/
replaceOptionalCourseDates : function(oldStartDate, oldDuration) {
// if the start date is already set
if (oldStartDate) {
var dateDifference = null;
var newDate;
this._courseDetails.startDates.each(function(item, index) {
if (dateDifference > Math.abs(oldStartDate.getTime() - item.getTime()) || dateDifference == null) {
dateDifference = Math.abs(oldStartDate.getTime() - item.getTime());
newDate = item;
}
});
// if there is already a duration set
if (oldDuration) {
var durationDifference = null;
var newDuration;
this._courseDetails.duration.each(function(item, index) {
if (durationDifference > Math.abs(oldDuration - item) || durationDifference == null) {
durationDifference = Math.abs(oldDuration - item);
newDuration = item;
}
});
this._courseDuration = newDuration;
if (this._courseDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace("%0", this._courseDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._courseDuration));
}
}
this._courseStartDate = newDate;
this._startDateValue.setHTML(newDate.format(this._dateFormat, this._parent.getParent().getMonthTranslations()));
this.refreshOptionalCourseData();
}
},
/**
* Generate a list of valid course
*
* @param SchoolList list The valid courses list
*
*/
getVisualValidCoursesList : function(list) {
var validCourses = this._parent.getOptionalCourses();
// clearing the list
list.clear();
validCourses.each(function(item, index) {
list.addItem(item, item.name);
list.getListItems().getLast().getHtml().addClass(this._classNameBase + 'List-Item');
list.getListItems().getLast().getHtml().addEvent('click', function() {
this.replaceCourse(item);
}.bind(this));
}, this);
this.refreshVisualValidCoursesList(list);
},
/**
* Refresh a list of course that have possible dates between this courseStartDate and courseEndDate
*
* @param SchoolList list The courses list
*
*/
refreshVisualValidCoursesList : function(list) {
var validCourses = this._parent.getValidCourses(this, true);
list.getListItems().each(function(item, index) {
if (validCourses.indexOf(item.getValue()) != -1) {
item.setIsValid(true);
} else {
item.setIsValid(false);
}
}.bind(this));
},
/**
* This function set a formated list from an array of a course start dates
*
* @param Array startDates An array of Date containing all the possible startDates
* @param SchoolList list The valid courses list
*/
getVisualOptionalCourseStartDates : function(startDates, list) {
// clearing the list
list.clear();
startDates.each(function(item, index) {
list.addItem(item, item.format(this._dateFormat, this._parent.getParent().getMonthTranslations()));
index = list.getListItems().indexOf(list.getListItems().getLast());
list.getListItems().getLast().getHtml().addEvent('click', function() {
if (list.getListItems()[index].getIsSelectionnable()) {
// Set the variables for this course
this._courseStartDate = item;
// set the visual data of this course
this._startDateValue.setHTML(item.format(this._dateFormat, this._parent.getParent().getMonthTranslations()));
this.refreshOptionalCourseData();
}
}.bind(this));
}.bind(this));
list.addItem('error', this._translateDTO.noValidStartDates);
if (list.getValidListItems().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* this function refresh a list from an array of a course start dates
*
* @param Array validStartDates an array of Date containing the validated startDates
* @param SchoolList list the valid courses list
*/
refreshVisualOptionalCourseStartDates : function(validStartDate, list) {
var firstValid = true;
list.getListItems().each(function(item, index) {
if (validStartDate.indexOf(item.getValue()) != -1) {
item.setIsValid(true);
item.setIsSelectionnable(true);
if (firstValid) {
list.setSelectedItem(item);
}
if (this._courseStartDate == item.getValue()) {
list.setSelectedItem(item);
}
firstValid = false;
} else {
if (item.getValue == 'error') {
item.setIsValid(false);
}
item.setIsSelectionnable(false);
}
}.bind(this));
if (list.getValidListItems().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* This function return a formated list from an array of duration
*
* @param Array durations An array of Date containing the startDates
* @param Array validDurations An array of number containing the validated durations
*/
getVisualOptionalCourseDurationList : function(durations, list) {
// clearing the list
list.clear();
durations.each(function(item, index) {
if (item > 1) {
list.addItem(item, this._translateDTO.weeks.replace('%0', item));
} else {
list.addItem(item, this._translateDTO.week.replace('%0', item));
}
index = list.getListItems().indexOf(list.getListItems().getLast());
// adding the event on the valid courses
list.getListItems().getLast().getHtml().addEvent('click', function() {
if (list.getListItems()[index].getIsSelectionnable()) {
this._courseDuration = item;
if (this._courseDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace("%0", this._courseDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._courseDuration));
}
this.refreshOptionalCourseData();
}
}.bind(this));
}.bind(this));
list.addItem('error', this._translateDTO.noValidDuration);
if (list.getValidListItems().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* This function return a formated list from an array of duration
*
* @param Array validDurations An array of number containing the validated durations
* @param SchoolList list The list to refresh
*/
refreshVisualOptionalCourseDurationList : function(validDurations, list) {
var firstValid = true;
list.getListItems().each(function(item, index) {
if (validDurations.indexOf(item.getValue()) != -1) {
item.setIsValid(true);
item.setIsSelectionnable(true);
if (firstValid)list.setSelectedItem(item);
if (this._courseDuration == item.getValue()) list.setSelectedItem(item);
firstValid = false;
} else {
if (item.getValue == 'error')item.setIsValid(false);
item.setIsSelectionnable(false);
}
}.bind(this));
if (list.getValidListItems().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* Return the duration in weeks.
* To perform the calculation we count the number of time the week day of the start date
* can be repeated between the start date and the end date.
*
* @param date startDate The start date
* @param date endDate The end date
* @return integer the number of weeks
*/
getCalculatedDuration : function(startDate, endDate) {
startDate = startDate.getTime();
endDate = endDate.getTime() - (86400 * 3 *1000) ;
var numberOfWeeks = 0;
while(startDate <= endDate) {
numberOfWeeks++;
startDate += (86400 * 7 * 1000);
}
return numberOfWeeks;
},
/**
*  Returns the available accommodations for this course
*
* @return Array of integer The Accommodation IDs
*/
getAvailableAccommodations : function() {
return this._courseDetails.availableAccommodations;
},
/**
*  return the course duration
*
* @return integer The course duration
*/
getCourseDuration : function() {
return this._courseDuration;
},
/**
*  set the course duration
*
* @param integer duration The course duration
*/
setCourseDuration : function(duration) {
this._courseDuration = duration;
this._durationValue.setHTML(this._translateDTO.weeks.replace("%0", this._courseDuration));
},
/**
* return the course start date
*
* @return Date The course start date
*/
getCourseStartDate : function() {
return this._courseStartDate;
},
/**
* return the course start date
*
* @return Date The course start date
*/
getCourseEndDate : function() {
return this._courseEndDate;
},
/**
*  set the course duration
*
* @param integer duration The course duration
*/
setCourseStartDate : function(startDate) {
this._courseStartDate = startDate;
this._startDateValue.setHTML(this._courseStartDate.format(this._dateFormat, this._parent.getParent().getMonthTranslations()));
},
/**
* Returns false is it's not a fixed course
*
* @return Boolean Return false because it's a variable course
*/
getIsFixedCourse : function() {
return false;
},
/**
* return the parent
*
* @return SchoolCourses The parent
*/
getParent : function() {
return this._parent;
},
/**
* Remove the course from the list
*
*/
removeCourse : function() {
this._schoolStartList.getHtml().remove();
this._schoolDurationList.getHtml().remove();
this._coursesValidList.getHtml().remove();
this._container.remove();
}
});
/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @param TransferListItemDTO schoolTransfersDTO the transfers informations
* @param SchoolPriceEstimation parent the parent
**/
var SchoolParticipants = Events.extend({
/**
* This is the initialization function
*/
initialize : function(translateDTO, enabled, parent) {
this._translateDTO = translateDTO;
this._enabled = enabled;
this._parent = parent;
this._classNameBase = this._parent.getClassNameBase();
this._participant = 1;
},
/**
* return the visual transfer container
*/
getHtml : function() {
this._participantContainer = new Element('div', {'class': this._classNameBase + 'Participants-Section'});
this._participantTitle = new Element('div', {'class': this._classNameBase + 'Participants-Section-Title'});
this._participantTitleText = new Element('div', {'class': this._classNameBase + 'Participants-Section-Title-Text'});
this._participantTitleText.injectInside(this._participantTitle);
this._participantButtons = new Element('div', {'class': this._classNameBase + 'AddButton'});
this._participantButtons.addClass( this._classNameBase + 'ParticipantsButton');
this._participantTitle.injectInside(this._participantContainer);
this._participantTitleText.setHTML(this._translateDTO.title);
this._participantButtons.setHTML('1');
this._participantButtons.injectInside(this._participantTitle);
this._participantsList = new SchoolList(this._participantButtons, this._classNameBase);
this.createVisualList(this._participantsList);
this._participantsList.getHtml().injectInside(this._parent.getListContainer());
this._participantsList.initializeEvents();
if(!this._enabled){
this._participantContainer.setStyle('display', 'none');
}
return this._participantContainer;
},
/**
* Generate the list of participants
*
* @param SchoolList list The list to update
*/
createVisualList : function(list) {
for (var i = 1; i < 50; i++) {
if(i > 1){
list.addItem(i, i);
} else{
list.addItem(i, i);
}
}
list.getListItems().each(function(item, index) {
item.setIsValid(true);
item.setIsSelectionnable(true);
if (item.getValue() == this._participant) {
list.setSelectedItem(item);
}
item.getHtml().addEvent('click', function(event) {
this._participantButtons.setHTML(item.getHtmlValue());
this._participant = item.getValue();
this._parent.refreshAccommodations();
this._parent.fireEvent('refreshPrice');
list.setSelectedItem(item);
}.bind(this));
}.bind(this));
},
/**
* Returns the number of participant
*
* @return number The number of participants
*/
getParticipant : function() {
if(!this._participant)this._participant = 1;
return this._participant;
},
setParticipant : function(participants){
this._participant  = participants;
this._participantButtons.setHTML(participants);
//        this._participantButtons.setHTML(participants + (participants > 1? " "+this._translateDTO.participants : " "+this._translateDTO.participant));
}
});/**
* This class is used for the price calculation functionnalities DTO
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
**/
var SchoolPriceCalculatorDTO = Events.extend({
/**
* This is the initialization function
*/
initialize : function() {
this.dateFormat = '';
this.schoolInformations = '';
this.schoolFixedDatesCourses = new Array();
this.schoolVariableDatesCourses = new Array();
this.schoolOptionalCourses = new Array();
this.schoolAccommodations = new Array();
this.schoolTransfers = new Array();
}
});
/**
* This class is used for the price calculation functionnalities
*
**/
var SchoolInformationDTO = Events.extend({
/**
* This is the initialization function
*/
initialize : function(schoolGroupID, vacationAndHolidays) {
this.schoolGroupID = schoolGroupID;
this.vacationAndHolidays = vacationAndHolidays;
}
});
/**
* This class is used for the price calculation functionnalities
*
**/
var FixedDatesCourseListItemDTO = Events.extend({
/**
* This is the initialization function
*/
initialize : function(id, name, sessions, subtitle, accommodationMandatory, transferMandatory, availableAccommodations, position, availableOptionalCourses, courseTypeId) {
this.id = id;
this.type = 'fixedDate';
this.name = name;
this.sessions = sessions;
this.subtitle = subtitle;
this.accommodationMandatory = accommodationMandatory;
this.transferMandatory = transferMandatory;
this.availableAccommodations = availableAccommodations;
this.position = position;
this.availableOptionalCourses = availableOptionalCourses;
this.courseTypeId = courseTypeId;
}
});
/**
* This class is used for the price calculation functionnalities
*
**/
var FixedDatesCourseSessionListItemDTO = Events.extend({
/**
* This is the initialization function
*/
initialize : function(courseStartDate, courseEndDate, accommodationStartDate, accommodationEndDate) {
this.courseStartDate = courseStartDate;
this.courseEndDate = courseEndDate;
this.accommodationStartDate = accommodationStartDate;
this.accommodationEndDate = accommodationEndDate;
}
});
/**
* This class is used for the price calculation functionnalities
*
**/
var VariableDatesCourseListItemDTO = Events.extend({
/**
* This is the initialization function
*/
initialize : function(id, name, startDates, duration, courseStartDay, courseEndDay, subtitle,  accommodationMandatory, transferMandatory, availableAccommodations, position, availableOptionalCourses, availabilities, courseTypeId) {
this.id = id;
this.type = 'variableDate';
this.name = name;
this.startDates = startDates;
this.duration = duration;
this.courseStartDay = courseStartDay;
this.courseEndDay = courseEndDay;
this.subtitle = subtitle;
this.accommodationMandatory = accommodationMandatory;
this.transferMandatory = transferMandatory;
this.availableAccommodations = availableAccommodations;
this.position = position;
this.availableOptionalCourses = availableOptionalCourses;
this.availabilities = availabilities;
this.courseTypeId = courseTypeId;
}
});
/**
* This class is used for the price calculation functionnalities
*
**/
var OptionalCourseListItemDTO = Events.extend({
/**
* This is the initialization function
*/
initialize : function(id, name, startDates, duration, courseStartDay, courseEndDay, subtitle, position, availabilities, oneDayCourse, courseTypeId, additionalDays) {
this.id = id;
this.type = 'optional';
this.name = name;
this.startDates = startDates;
this.duration = duration;
this.courseStartDay = courseStartDay;
this.courseEndDay = courseEndDay;
this.subtitle = subtitle;
this.position = position;
this.availabilities = availabilities;
this.oneDayCourse = oneDayCourse;
this.courseTypeId = courseTypeId;
this.additionalDays = (additionalDays ? parseInt(additionalDays) : 0);
}
});
/**
* This class is used for the price calculation functionnalities
*
**/
var AccommodationOptionListItemDTO = Events.extend({
/**
* This is the initialization function
*/
initialize : function(id, name, minimumDurationInWeeks, minimumNumberOfPeople, accommodationStartDay, accommodationEndDay, availabilities, noAccommodation, additionalNightsBefore, additionalNightsAfter, additionalNightsOnBounds) {
this.id = id;
this.name = name;
this.minimumDurationInWeeks = minimumDurationInWeeks;
this.minimumNumberOfPeople = minimumNumberOfPeople;
this.accommodationStartDay = accommodationStartDay;
this.accommodationEndDay = accommodationEndDay;
this.availabilities = availabilities;
this.noAccommodation = noAccommodation;
this.additionalNightsBefore = parseInt(additionalNightsBefore);
this.additionalNightsAfter = parseInt(additionalNightsAfter);
this.additionalNightsOnBounds = parseInt(additionalNightsOnBounds);
}
});
/**
* This class is used for the price calculation functionnalities
*
**/
var AccommodationListItemDTO = Events.extend({
/**
* This is the initialization function
*/
initialize : function(id, name, option, availableTransfers, accommodationType ) {
this.id = id;
this.name = name;
this.option = option;
this.availableTransfers = availableTransfers;
this.accommodationType = accommodationType ? parseInt(accommodationType): 0;
}
});
/**
* This class is used for the price calculation functionnalities
*
**/
var TransferListItemDTO = Events.extend({
/**
* This is the initialization function
*/
initialize : function(id, name, type) {
this.id = id;
this.name = name;
this.type = type;
}
});
/**
* This class is used for the price calculation functionalities
*
**/
var InsuranceListItemDTO = Events.extend({
/**
* This is the initialization function
*/
initialize : function(id, name,defaultChecked, mandatory, availableFrom, mandatoryFrom, additionalMandatoryDays, durationCalculationMethod) {
this.id = parseInt(id);
this.name = name;
this.defaultChecked = (defaultChecked ? parseInt(defaultChecked) : 0);
this.mandatory =  (mandatory ? parseInt(mandatory) : 0);
this.availableFrom = (availableFrom ? parseInt(availableFrom) : 0);
this.mandatoryFrom = (mandatoryFrom ? parseInt(mandatoryFrom) : 0);
this.additionalMandatoryDays = (additionalMandatoryDays ? parseInt(additionalMandatoryDays) : 0);
this.durationCalculationMethod = (durationCalculationMethod ? parseInt(durationCalculationMethod) : 0);
}
});
/**
* This class is used for the price calculation functionalities
*
**/
var PromotionListItemDTO = Events.extend({
/**
* This is the initialization function
*/
initialize : function(id, name, triggers) {
this.id = parseInt(id);
this.name = name;
this.triggers = triggers;
}
});
ï»¿/**
* This class is used for the price estimation functionnalities
*
* @author Yves-AndrÃ© Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @param TransferListItemDTO schoolTransfersDTO the transfers informations
* @param Object translateDTO The DTO containing the translations for this class
* @param SchoolPriceEstimation parent the parent
**/
var SchoolSection = Events.extend({
/**
* This is the initialization function
*/
initialize : function(schoolItemsDTO, translateDTO, parent) {
this._schoolItemsDTO = schoolItemsDTO;
this._translateDTO = translateDTO;
this._parent = parent;
this._classNameBase = this.getParent().getClassNameBase();
this._items = new Array();
},
/**
* Returns the visual transfer container
*/
getHtml : function() {
this._container = new Element('div', {'class': this._classNameBase + 'Section'});
this._title = new Element('div', {'class': this._classNameBase + 'Section-Title'});
this._listContainer = new Element('div', {'class': this._classNameBase + 'Section-List-Container'});
this._addedItemsList = new Element('div', {'class': this._classNameBase + 'Section-List'});
this._addButton = new Element('div', {'class': this._classNameBase + 'Button' + ' ' + this._classNameBase + 'AddButton'});
this._title.injectInside(this._container);
this._listContainer.injectInside(this._container);
this._addedItemsList.injectInside(this._listContainer);
this._addButton.injectInside(this._container);
this._title.setHTML(this._translateDTO.title);
this._addButton.setHTML(this._translateDTO.add);
this._itemsList = new SchoolList(this._addButton, this._classNameBase);
this.getVisualItemsList(this._itemsList);
this._itemsList.getHtml().injectInside(this._parent.getListContainer());
this._itemsList.initializeEvents();
if(!this._schoolItemsDTO.length){
this._container.setStyle('display','none');
}
return this._container;
},
/**
*  Return the classNameBase
*/
getClassNameBase : function() {
return this._classNameBase;
},
/**
* Returns an array containing the informations for the calculation price
*
* @return Array The informations needed to calculate the price
*/
getDTO : function() {
var dto = new Array();
this._items.each(function(item, index) {
if (item.isComplete()) {
dto.push(item.getDTO());
}
});
return dto;
},
/**
* Retrieve the list of transfers for this school
*
* @param schoolList list The list to update
*/
getVisualItemsList : function(list) {
list.clear();
this._schoolItemsDTO.each(function(item, index) {
list.addItem(item.id, item.name);
list.getListItems().getLast().getHtml().addEvent('click', function() {
this.addItem(item.id);
}.bind(this));
}.bind(this));
list.addItem('error', this._translateDTO.notAvailable);
if (this._parent.getCompletedCourses().length > 0) {
if (this._schoolTransfersDTO.length) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setHtml(this._translateDTO.noTransfers);
list.getListItems().getLast().setIsValid(true);
}
} else {
list.getListItems().getLast().setHtml(this._translateDTO.notAvailable);
list.getListItems().getLast().setIsValid(true);
}
this.refreshVisualTransferList(list);
},
/**
* Returns the parent of this object
*
* @return SchoolPriceEstimation The parent
*/
getParent : function() {
return this._parent;
},
addItem : function(id){
var schoolItemsDTO = this._schoolItemsDTO.copy();
var schoolItem = schoolItemsDTO.filter(function(item, index) {
return item.id == id;
}.bind(this));
/*   var newItem = new SchoolItemObject(schoolItem[0].id, schoolItem[0].name, schoolItem[0].type, this._translateDTO.itemObject, this);
this._items.push(newItem);
newItem.createVisualItem();
this._items.getLast().getHtml().injectInside(this._addedItemsList);
newItem.addEvent('deleteItem', function(e) {
this.deleteItem(newItem);
}.bind(this));
this._parent.fireEvent('heightModified');
this._parent.fireEvent('refreshPrice');
*/
},
/**
* Display or hide the add button
*
* @param boolean isDisplayed True to display the hide button
*/
displayAddButton : function(isDisplayed) {
if (isDisplayed) {
this._addButton.setStyle('display', '');
} else {
this._addButton.setStyle('display', 'none');
}
},
/**
* Returns the number of completed transfers
*
* @return Number The number of completed transfers
*/
getCompletedItems : function() {
return this._items.length;
},
/**
* Delete the given transfer
*
* @param SchoolItemObject transfer The transfer to delete
*/
deleteItem : function(item) {
this._items.remove(item);
this._parent.fireEvent('heightModified');
this._parent.fireEvent('refreshPrice');
}
});/**
* This class is used for the price estimation functionnalities
*
* @author Yves-Andrï¿½ Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @param TransferListItemDTO schoolTransfersDTO the transfers informations
* @param Object translateDTO The DTO containing the translations for this class
* @param SchoolPriceEstimation parent the parent
**/
var SchoolPromotions = SchoolSection.extend({
/**
* This is the initialization function
*/
initialize : function(schoolItemsDTO, translateDTO, parent) {
this.parent(schoolItemsDTO, translateDTO, parent);
this.promotions = new Array();
this._xhrValidate = new XHR();
this._xhrValidate.addEvent('onSuccess', function(e)
{
if(parseInt(e)){
// we can add the promotion
for(var i = 0; i < this.promotions.length; i++){
if(this.promotions[i] == parseInt(e)){
this.displayMessage(this._translateDTO.promotionAlreadyAdded);
this._parent.fireEvent('refreshPrice');
return 0;
}
}
this.promotions.push(parseInt(e));
this._parent.fireEvent('refreshPrice');
}else {
this.displayMessage(this._translateDTO.invalidCode);
}
}.bind(this));
},
/**
* Returns the visual transfer container
*/
getHtml : function() {
this._codeDefaultText = this._translateDTO.enterYourCode;
this._container = new Element('div', {'class': this._classNameBase + 'Section'});
this._title = new Element('div', {'class': this._classNameBase + 'Section-Title'});
this._listContainer = new Element('div', {'class': this._classNameBase + 'Section-List-Container'});
this._addedItemsList = new Element('div', {'class': this._classNameBase + 'Section-List'});
this._addButton = new Element('div', {'class': this._classNameBase + 'Button' + ' ' + this._classNameBase + 'AddButton PromotionAddButton'});
this._codeInput = new Element('input').setProperties({'type' : 'text', 'value' : this._codeDefaultText, 'class' : 'Synergee-Web-Page-Form-Text', 'id':'promotionInput'});
this._title.injectInside(this._container);
this._listContainer.injectInside(this._container);
this._addedItemsList.injectInside(this._listContainer);
this._codeInput.injectInside(this._container);
this._addButton.injectInside(this._container);
this._title.setHTML(this._translateDTO.title);
this._addButton.setHTML(this._translateDTO.add);
this._codeInput.addEvent('focus', function() {
if (this._codeInput.getProperty('value') == this._codeDefaultText)
this._codeInput.setProperty('value', '');
}.bind(this));
this._codeInput.addEvent('blur', function() {
if (this._codeInput.getProperty('value') == '')
this._codeInput.setProperty('value', this._codeDefaultText);
}.bind(this));
this._codeInput.addEvent('change', function(){
if(this._codeInput.getProperty('value') == '' || this._codeInput.getProperty('value') == this._codeDefaultText){
this._addButton.addClass('Disabled');
}else {
this._addButton.removeClass('Disabled');
}
}.bind(this));
this._addButton.addEvent('click', this.validateCode.bind(this));
if(!this._schoolItemsDTO.length){
this._container.setStyle('display','none');
}
return this._container;
},
displayMessage : function(message){
this._parent.displayMessage(message);
},
validateCode : function(){
if(this._codeInput.getProperty('value') != '' && this._codeInput.getProperty('value') != this._codeDefaultText){
this._xhrValidate.send(window.getCurrentJsonUrl(this._container), 'step=validateCode&code=' + this._codeInput.getProperty('value'));
}
},
getDTO : function(){
return this.promotions;
},
/**
* Populate the transfers from a dto
*/
populateFromDTO : function(toPopulateDTO) {
if (toPopulateDTO) {
this.promotions = toPopulateDTO;
}
}
});/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @param TransferListItemDTO schoolTransfersDTO the transfers informations
* @param SchoolPriceEstimation parent the parent
**/
var SchoolSelector = Events.extend({
/**
* This is the initialization function
*
* @param Object translateDTO the object containing the translations for this class
* @param SchoolsListDTO schoolsList The Schools list
* @param Objec parent The class that calls this class
*/
initialize : function(translateDTO, schoolsList, parent, advancedSchoolSelector) {
this._translateDTO = translateDTO;
this._parent = parent;
this._schoolsList = schoolsList;
this._schoolsHash = new Hash();
this._cityCountryHash = new Hash();
if (advancedSchoolSelector) {
this._advancedSchoolSelector = true;
} else {
this._advancedSchoolSelector = false;
}
this._classNameBase = this._parent.getClassNameBase();
if (this._schoolsList.length == 1 && (!this._parent.getType || this._parent.getType() == 'PriceEstimation')) {
this._selectedSchoolId = this._schoolsList[0].schoolId;
} else {
this._selectedSchoolId = null;
}
},
/**
* return the visual transfer container
*/
getHtml : function() {
this._schoolSelectorContainer = new Element('div', {'class': this._classNameBase + 'Participants-Section ' + this._classNameBase + 'SchoolsSelector-Section'});
this._schoolSelectorTitle = new Element('div', {'class': this._classNameBase + 'Participants-Section-Title ' + this._classNameBase + 'SchoolsSelector-Section-Title'});
this._schoolSelectorTitleText = new Element('div', {'class': this._classNameBase + 'Participants-Section-Title-Text ' + this._classNameBase + 'SchoolsSelector-Section-Title-Text'});
this._schoolSelectorTitleText.injectInside(this._schoolSelectorTitle);
this._schoolSelectorButtonsContainer = new Element('ul', {'class': this._classNameBase + 'AddSchoolMenu'});
this._schoolSelectorTitle.injectInside(this._schoolSelectorContainer);
this._schoolSelectorTitleText.setHTML(this._translateDTO.school);
if (this._schoolsList.length > 0) {
if (this._advancedSchoolSelector) {
this.programs = new Hash();
for (var i = 0; i < this._schoolsList.length; i++) {
var programId = this._schoolsList[i].schoolProgramId;
var countryCode = this._schoolsList[i].schoolCountryCode;
var cityId = this._schoolsList[i].schoolCityId;
if (!this.programs.hasKey(programId)) {
var program = new Object();
program.name = this._schoolsList[i].schoolProgramName;
program.id = this._schoolsList[i].schoolProgramId;
program.countries = new Hash();
this.programs.set(this._schoolsList[i].schoolProgramId, program);
}
if (!this.programs.get(programId).countries.hasKey(countryCode)) {
var country = new Object();
country.name = this._schoolsList[i].schoolCountryName;
country.id = countryCode;
country.cities = new Hash();
this.programs.get(programId).countries.set(countryCode, country);
}
if (!this.programs.get(programId).countries.get(countryCode).cities.hasKey(cityId)) {
var city = new Object();
city.name = this._schoolsList[i].schoolCityName;
city.id = cityId;
city.schools = new Hash();
this.programs.get(programId).countries.get(countryCode).cities.set(cityId, city);
}
if (!this._cityCountryHash.hasKey(cityId)) {
this._cityCountryHash.set(cityId, countryCode)
}
if (!this.programs.get(programId).countries.get(countryCode).cities.get(cityId).schools.hasKey(this._schoolsList[i].schoolId)) {
var school = new Object();
school.name = this._schoolsList[i].schoolName;
school.id = this._schoolsList[i].schoolId;
if (!this._schoolsHash.hasKey(school.id)) {
this._schoolsHash.set(school.id, this._schoolsList[i]);
}
this.programs.get(programId).countries.get(countryCode).cities.get(cityId).schools.set(this._schoolsList[i].schoolId, school);
}
}
this._advancedSchoolSelectorContainer = new Element('div', {'class': this._classNameBase + 'SchoolsSelector-Section-Container AdvancedSchoolSelector'});
this._programSelectorContainer = new Element('div', {'class': this._classNameBase + 'Participants-Section ' + this._classNameBase + 'SchoolsSelector-Section AdvancedSchoolSelector SchoolSelectorProgram'});
this._programSelectorTitle = new Element('div', {'class': this._classNameBase + 'Participants-Section-Title ' + this._classNameBase + 'SchoolsSelector-Section-Title AdvancedSchoolSelector SchoolSelectorProgram'});
this._programSelectorTitleText = new Element('div', {'class': this._classNameBase + 'Participants-Section-Title-Text ' + this._classNameBase + 'SchoolsSelector-Section-Title-Text SchoolSelectorProgram'});
this._programSelectorTitleText.injectInside(this._programSelectorTitle);
this._programSelectorTitle.injectInside(this._programSelectorContainer);
this._programSelectorTitleText.setHTML(this._translateDTO.program);
this._programSelectorContainer.injectInside(this._advancedSchoolSelectorContainer);
this._programSelectorButtons = new Element('div', {'class': this._classNameBase + 'AddButton'});
this._programSelectorButtons.addClass(this._classNameBase + 'SchoolSelectorButton ' + this._classNameBase + 'Section-Item-ToUpdate');
this._programSelectorButtons.setHTML(this._translateDTO.addProgram);
this._programSelectorButtons.defaultText = this._translateDTO.addProgram;
this._programSelectorButtons.injectInside(this._programSelectorTitle);
this._programSelectorsList = new SchoolList(this._programSelectorButtons, this._classNameBase);
this.createAdvancedList(this._programSelectorsList, this.programs, 'program');
this._programSelectorsList.getHtml().injectInside(this._parent.getListContainer());
this._programSelectorsList.initializeEvents();
this._countrySelectorContainer = new Element('div', {'class': this._classNameBase + 'Participants-Section ' + this._classNameBase + 'SchoolsSelector-Section AdvancedSchoolSelector SchoolSelectorCountry'});
this._countrySelectorTitle = new Element('div', {'class': this._classNameBase + 'Participants-Section-Title ' + this._classNameBase + 'SchoolsSelector-Section-Title AdvancedSchoolSelector SchoolSelectorCountry'});
this._countrySelectorTitleText = new Element('div', {'class': this._classNameBase + 'Participants-Section-Title-Text ' + this._classNameBase + 'SchoolsSelector-Section-Title-Text SchoolSelectorCountry'});
this._countrySelectorTitleText.injectInside(this._countrySelectorTitle);
this._countrySelectorTitle.injectInside(this._countrySelectorContainer);
this._countrySelectorTitleText.setHTML(this._translateDTO.country);
this._countrySelectorContainer.injectInside(this._advancedSchoolSelectorContainer);
this._countrySelectorButtons = new Element('div', {'class': this._classNameBase + 'AddButton'});
this._countrySelectorButtons.addClass(this._classNameBase + 'SchoolSelectorButton ' + this._classNameBase + 'Section-Item-ToUpdate');
this._countrySelectorButtons.setHTML(this._translateDTO.addCountry);
this._countrySelectorButtons.defaultText = this._translateDTO.addCountry;
this._countrySelectorButtons.injectInside(this._countrySelectorTitle);
this._countrySelectorsList = new SchoolList(this._countrySelectorButtons, this._classNameBase);
this._citySelectorContainer = new Element('div', {'class': this._classNameBase + 'Participants-Section ' + this._classNameBase + 'SchoolsSelector-Section AdvancedSchoolSelector SchoolSelectorCity'});
this._citySelectorTitle = new Element('div', {'class': this._classNameBase + 'Participants-Section-Title ' + this._classNameBase + 'SchoolsSelector-Section-Title AdvancedSchoolSelector SchoolSelectorCity'});
this._citySelectorTitleText = new Element('div', {'class': this._classNameBase + 'Participants-Section-Title-Text ' + this._classNameBase + 'SchoolsSelector-Section-Title-Text SchoolSelectorCity'});
this._citySelectorTitleText.injectInside(this._citySelectorTitle);
this._citySelectorTitle.injectInside(this._citySelectorContainer);
this._citySelectorTitleText.setHTML(this._translateDTO.city);
this._citySelectorContainer.injectInside(this._advancedSchoolSelectorContainer);
this._citySelectorButtons = new Element('div', {'class': this._classNameBase + 'AddButton'});
this._citySelectorButtons.addClass(this._classNameBase + 'SchoolSelectorButton ' + this._classNameBase + 'Section-Item-ToUpdate');
this._citySelectorButtons.setHTML(this._translateDTO.addCity);
this._citySelectorButtons.defaultText = this._translateDTO.addCity;
this._citySelectorButtons.injectInside(this._citySelectorTitle);
this._citySelectorsList = new SchoolList(this._citySelectorButtons, this._classNameBase);
this._schoolSelectorContainer = new Element('div', {'class': this._classNameBase + 'Participants-Section ' + this._classNameBase + 'SchoolsSelector-Section AdvancedSchoolSelector SchoolSelectorSchool'});
this._schoolSelectorTitle = new Element('div', {'class': this._classNameBase + 'Participants-Section-Title ' + this._classNameBase + 'SchoolsSelector-Section-Title AdvancedSchoolSelector SchoolSelectorSchool'});
this._schoolSelectorTitleText = new Element('div', {'class': this._classNameBase + 'Participants-Section-Title-Text ' + this._classNameBase + 'SchoolsSelector-Section-Title-Text SchoolSelectorSchool'});
this._schoolSelectorTitleText.injectInside(this._schoolSelectorTitle);
this._schoolSelectorTitle.injectInside(this._schoolSelectorContainer);
this._schoolSelectorTitleText.setHTML(this._translateDTO.school);
this._schoolSelectorContainer.injectInside(this._advancedSchoolSelectorContainer);
this._schoolSelectorButtons = new Element('div', {'class': this._classNameBase + 'AddButton'});
this._schoolSelectorButtons.addClass(this._classNameBase + 'SchoolSelectorButton ' + this._classNameBase + 'Section-Item-ToUpdate');
this._schoolSelectorButtons.setHTML(this._translateDTO.addSchool);
this._schoolSelectorButtons.defaultText = this._translateDTO.addSchool;
this._schoolSelectorButtons.injectInside(this._schoolSelectorTitle);
new Element('div', {'style': 'clear:both'}).injectInside(this._advancedSchoolSelectorContainer);
this._schoolSelectorsList = new SchoolList(this._schoolSelectorButtons, this._classNameBase);
// set to inactive the inactive menu
this.setActive(this._countrySelectorButtons, false);
this.setActive(this._citySelectorButtons, false);
this.setActive(this._schoolSelectorButtons, false);
if(this._programSelectorsList.getListItems().length == 1){
this._programSelectorsList.getListItems()[0].getHtml().fireEvent('click');
this._programSelectorContainer.addClass('Component-Booking-OneOption');
}
return this._advancedSchoolSelectorContainer;
} else {
this._schoolSelectorButtons = new Element('div', {'class': this._classNameBase + 'AddButton'});
this._schoolSelectorButtons.addClass(this._classNameBase + 'SchoolSelectorButton ' + this._classNameBase + 'Section-Item-ToUpdate');
this._schoolSelectorButtons.setHTML(this._translateDTO.add);
this._schoolSelectorButtons.injectInside(this._schoolSelectorTitle);
this._schoolSelectorsList = new SchoolList(this._schoolSelectorButtons, this._classNameBase);
this.createVisualList(this._schoolSelectorsList);
if (this._schoolsList.length == 1) {
this._schoolSelectorContainer.setStyle('display', 'none');
}
this._schoolSelectorsList.getHtml().injectInside(this._parent.getListContainer());
this._schoolSelectorsList.initializeEvents();
}
} else {
this._schoolSelectorButtons.setHTML(this._translateDTO.noSchools);
this._schoolSelectorButtons.injectInside(this._schoolSelectorTitle);
}
return this._schoolSelectorContainer;
},
/**
* Generate the list of schoolSelectors
*
* @param SchoolList list The list to update
*/
createVisualList : function(list) {
for (var i = 0; i < this._schoolsList.length; i++) {
list.addItem(this._schoolsList[i].schoolId, this._schoolsList[i].schoolName + ' - ' + this._schoolsList[i].schoolCityName + ' - ' + this._schoolsList[i].schoolCountryName);
}
list.getListItems().each(function(item, index) {
item.setIsValid(true);
item.setIsSelectionnable(true);
if (item.getValue() == this._selectedSchoolId) {
list.setSelectedItem(item);
this._schoolSelectorButtons.setHTML(item.getHtmlValue());
}
item.getHtml().addEvent('click', function(event) {
this._schoolSelectorButtons.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
if (this._selectedSchoolId != item.getValue()) {
this._schoolSelectorButtons.setHTML(item.getHtmlValue());
this._selectedSchoolId = item.getValue();
this.fireEvent('changeSchool');
list.setSelectedItem(item);
}
}.bind(this));
}.bind(this));
},
sortFunction : function(a,b){
var a = a.name.toLowerCase();
var b = b.name.toLowerCase();
if (a < b) {
return -1;
} else if (a > b) {
return  1;
} else {
return 0;
}
},
/**
* Create the list for the advanced school selector
* @param list
* @param listItems
* @param eventFunction
*/
createAdvancedList : function(list, listItems, eventFunction) {
list.clear();
var orderedListItems = new Array();
listItems.each(function(item, index) {
orderedListItems.push(item);
}.bind(this));
orderedListItems.sort(this.sortFunction);
orderedListItems.each(function(item, index) {
list.addItem(item.id, item.name);
}.bind(this));
list.getListItems().each(function(item, index) {
item.setIsValid(true);
item.setIsSelectionnable(true);
if (item.getValue() == this._selectedSchoolId) {
list.setSelectedItem(item);
this._schoolSelectorButtons.setHTML(item.getHtmlValue());
}
item.getHtml().addEvent('click', function(e) {
if (eventFunction == 'program') {
this.programEventFunction(item);
}
if (eventFunction == 'country') {
this.countryEventFunction(item);
}
if (eventFunction == 'city') {
this.cityEventFunction(item);
}
if (eventFunction == 'school') {
this.schoolEventFunction(item);
}
}.bind(this));
}.bind(this));
},
/**
* Function called when program is changed
*
* @param SchoolListItem item The new item
*/
programEventFunction : function(item) {
if (this._selectedProgramId != item.getValue()) {
this._programSelectorButtons.setHTML(item.getHtmlValue());
this._selectedProgramId = item.getValue();
this._selectedCityId = null;
this._selectedCountryId = null;
this._selectedSchoolId = null;
this.setActive(this._countrySelectorButtons, false);
this.setActive(this._citySelectorButtons, false);
this.setActive(this._schoolSelectorButtons, false);
this.updateCountryList(this._selectedProgramId);
this.fireEvent('changeSchool');
}
},
/**
* Function called when the country change
* @param SchoolListItem item The new item
*/
countryEventFunction : function(item) {
if(this._selectedCountryId != item.getValue()){
this._countrySelectorButtons.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
this._countrySelectorButtons.setHTML(item.getHtmlValue());
this._selectedCountryId = item.getValue();
this._selectedCityId = null;
this._selectedSchoolId = null;
this.setActive(this._citySelectorButtons, false);
this.setActive(this._schoolSelectorButtons, false);
this.updateCityList(this._selectedProgramId, this._selectedCountryId);
this.fireEvent('changeSchool');
}
},
/**
* Function called when the city change
* @param SchoolListItem item The new item
*/
cityEventFunction : function(item) {
if(this._selectedCityId != item.getValue()){
this._citySelectorButtons.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
this._citySelectorButtons.setHTML(item.getHtmlValue());
this._selectedCityId = item.getValue();
this._selectedSchoolId = null;
this.setActive(this._schoolSelectorButtons, false);
this.updateSchoolList(this._selectedProgramId, this._selectedCountryId, this._selectedCityId);
this.fireEvent('changeSchool');
}
},
/**
* Function called when the school change
* @param SchoolListItem item The new item
*/
schoolEventFunction : function(item) {
if(this._selectedSchoolId != item.getValue()){
this._schoolSelectorButtons.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
this._schoolSelectorButtons.setHTML(item.getHtmlValue());
this._selectedSchoolId = item.getValue();
this.fireEvent('changeSchool');
}
},
/**
* Update the country list
*
* @param programId
*/
updateCountryList : function(programId) {
this.createAdvancedList(this._countrySelectorsList, this.programs.get(programId).countries, 'country');
this._countrySelectorsList.getHtml().injectInside(this._parent.getListContainer());
this._countrySelectorsList.initializeEvents();
this.setActive(this._countrySelectorButtons, true);
if(this._countrySelectorsList.getListItems().length == 1){
this._countrySelectorsList.getListItems()[0].getHtml().fireEvent('click');
this._countrySelectorContainer.addClass('Component-Booking-OneOption');
}
},
/**
* Update the city list
* @param programId
* @param country
*/
updateCityList : function(programId, country) {
this.createAdvancedList(this._citySelectorsList, this.programs.get(programId).countries.get(country).cities, 'city');
this._citySelectorsList.getHtml().injectInside(this._parent.getListContainer());
this._citySelectorsList.initializeEvents();
this.setActive(this._citySelectorButtons, true);
if(this._citySelectorsList.getListItems().length == 1){
this._citySelectorsList.getListItems()[0].getHtml().fireEvent('click');
this._citySelectorContainer.addClass('Component-Booking-OneOption');
}
},
/**
* Update the school list
*
* @param programId
* @param country
* @param city
*/
updateSchoolList : function(programId, country, city) {
this.createAdvancedList(this._schoolSelectorsList, this.programs.get(programId).countries.get(country).cities.get(city).schools, 'school');
this._schoolSelectorsList.getHtml().injectInside(this._parent.getListContainer());
this._schoolSelectorsList.initializeEvents();
this.setActive(this._schoolSelectorButtons, true);
if(this._schoolSelectorsList.getListItems().length == 1){
this._schoolSelectorsList.getListItems()[0].getHtml().fireEvent('click');
this._schoolSelectorContainer.addClass('Component-Booking-OneOption');
}
},
/**
* Update the selector with the given parameter
*
*
* @param integer school The School Id
* @param integer program The program Id
* @param string country The country code
* @param integer city The city Id
*/
updateSelector : function(school, program, country, city) {
if (school.toInt()) {
if (this._schoolsHash.hasKey(school)) {
var schoolObject = this._schoolsHash.get(school);
this.updateProgramSelector(schoolObject.schoolProgramId);
this.updateCountrySelector(schoolObject.schoolCountryCode);
this.updateCitySelector(schoolObject.schoolCityId);
this.updateSchoolSelector(school);
}
} else {
if (program.toInt()) {
this.updateProgramSelector(program);
if (country) {
this.updateCountrySelector(country);
}
if (city) {
if (!country) {
this.updateCountrySelector(this._cityCountryHash.get(city));
}
this.updateCitySelector(city);
}
}
}
},
/**
* Update the program selector
*
* @param integer program The program Id
*/
updateProgramSelector : function(program) {
this._programSelectorsList.getListItems().each(function(item, index) {
if (item.getValue().toInt() == program.toInt()) {
item.getHtml().fireEvent('click');
}
}.bind(this));
},
/**
* Update the Country selector
*
* @param string country The Country code
*/
updateCountrySelector : function(country) {
this._countrySelectorsList.getListItems().each(function(item, index) {
if (item.getValue() == country) {
item.getHtml().fireEvent('click');
}
}.bind(this));
},
/**
* Update the city selector
*
* @param integer city The city Id
*/
updateCitySelector : function(city) {
this._citySelectorsList.getListItems().each(function(item, index) {
if (item.getValue().toInt() == city.toInt()) {
item.getHtml().fireEvent('click');
}
}.bind(this));
},
/**
* Update the school selector
*
* @param integer school The school Id
*/
updateSchoolSelector : function(school) {
this._schoolSelectorsList.getListItems().each(function(item, index) {
if (item.getValue() == school) {
item.getHtml().fireEvent('click');
}
}.bind(this));
},
/**
* Set active the button given
* @param button
* @param boolean
*/
setActive : function(button, active) {
if (active) {
button.removeClass(this._classNameBase + 'SchoolSelectorButtonInactive');
button.getParent().getParent().setStyle('display','');
} else {
button.addClass(this._classNameBase + 'SchoolSelectorButtonInactive');
button.getParent().getParent().setStyle('display','none');
if(button.defaultText){
button.setHTML(button.defaultText);
}
}
},
/**
* Returns the number of schoolSelector
*
* @return number The number of schoolSelectors
*/
getSelectedSchoolId : function() {
return this._selectedSchoolId;
}
});/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @param number id the transfer ID
* @param char name the transfer name
* @param SchoolTransfers parent
**/
var SchoolTransferObject = Events.extend({
/**
* This is the initialization function
*/
initialize : function(id, name, type,  translateDTO, parent) {
this._translateDTO = translateDTO;
this._transferName = name;
this._type = type;
this._transferId = id;
this._parent = parent;
this._classNameBase = this._parent.getClassNameBase();
this._isMandatory = false;
// transferType 1 for round trip, 2 for one way at arrival , 3 for one way to departure
this._transferTypeData = 1;
// true if roundtrip
this._roundTrip = 1;
},
/**
* Generate the Html structure of this transfer
*/
createVisualTransfer : function() {
this._container = new Element('div', {'class': this._classNameBase + 'ItemAdded'});
this._title = new Element('div', {'class': this._classNameBase + 'Section-Item-Title'});
this._transferTypeValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Value'});
this._transferType = new Element('div').setProperties({'class': this._classNameBase + 'Section-Item-Info-Name TransferType'});
this._deleteButton = new Element('div', {'class': this._classNameBase + 'Section-Item-DeleteButton'});
this._title.injectInside(this._container);
this._transferType.injectInside(this._container);
this._transferTypeValue.injectInside(this._container);
this._deleteButton.injectInside(this._container);
this._clearElement = new Element('div');
this._clearElement.setStyle('clear', 'both');
this._clearElement.injectInside(this._container);
this._title.setHTML(this._transferName);
this._transferType.setHTML(this._translateDTO.transferType);
this._transferTypeValue.setHTML(this._translateDTO.roundTrip);
this._deleteButton.setHTML(this._translateDTO.deleteButton);
// add event listener
this._deleteButton.addEvent('click', function(e) {
this.removeTransfer();
this.fireEvent('deleteTransfer');
}.bind(this));
this._transferList = new SchoolList(this._title, this._classNameBase);
this.getVisualTransferList(this._transferList);
this._transferList.getHtml().injectInside(this._parent.getParent().getListContainer());
this._transferList.initializeEvents();
this._transfersList = new SchoolList(this._transferTypeValue, this._classNameBase);
this.getVisualTransferOptionsList(this._transfersList);
this._transfersList.getHtml().injectInside(this._parent.getParent().getListContainer());
this._transfersList.initializeEvents();
if(this._transfersList.getValidListItems().length == 1){
this._transferTypeValue.setAttribute('class', this._classNameBase + 'Section-Item-Info-ValueNotEditable');
this._transfersList.removeButtonEvent();
this._transfersList.getValidListItems()[0].getHtml().fireEvent('click');
}else{
this._transferTypeValue.setAttribute('class', this._classNameBase + 'Section-Item-Info-Value');
this._transfersList.addButtonEvent();
}
},
/**
* Returns an object containing the informations for the calculation price
*
* @return object The informations needed to calculate the price
*/
getDTO : function() {
var transferDTO = new Object();
transferDTO.id = this._transferId;
transferDTO.roundTrip = this._roundTrip;
transferDTO.transferType = this._transferTypeData;
return transferDTO;
},
/**
* Set this transfer mandatory
*
* @param Boolean isMandatory True if the transfer is mandatory
*/
setIsMandatoryTransfer : function(isMandatory) {
this._isMandatory = isMandatory;
if (this._isMandatory) {
this._deleteButton.setStyle('display', 'none');
} else {
this._deleteButton.setStyle('display', 'block');
}
},
/**
* Get this transfer mandatory
*
* @return Boolean True if mandatory
*/
getIsMandatoryTransfer : function() {
return this._isMandatory;
},
/**
* Return the transfer ID
*
* @return integer The Transfer ID
*/
getTransferId : function() {
return parseInt(this._transferId);
},
/**
* Populate the transfer from a dto
*/
populateFromDTO : function(toPopulateDTO) {
this._roundTrip = parseInt(toPopulateDTO.roundTrip);
if (!this._roundTrip) {
this._transferTypeValue.setHTML(this._translateDTO.oneWay);
} else {
this._transferTypeValue.setHTML(this._translateDTO.roundTrip);
}
},
/**
* Return true if the transfer is complete
*
* @return Boolean Return true if complete
*/
isComplete : function() {
if (this._roundTrip != -1) {
return true;
}
},
/**
* Returns the HTML structure of this course
*
* @return Element the transfer element
*/
getHtml : function() {
return this._container;
},
/**
* Generate the list of transfers for this school
*
* @param schoolList list The list to update
*/
getVisualTransferList : function(list) {
list.clear();
this._parent._schoolTransfersDTO.each(function(item, index) {
list.addItem(item.id, item.name);
list.getListItems().getLast().getHtml().addEvent('click', function() {
this.setTransfer(item);
}.bind(this));
}.bind(this));
list.addItem('error', this._translateDTO.notAvailable);
if (!this._parent._schoolTransfersDTO || this._parent.getParent().getCompletedCourses().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
this.refreshVisualTransferList();
},
/**
* refresh the list of transfers for this school
*
*/
refreshVisualTransferList : function() {
this._parent.refreshVisualTransferList(this._transferList);
},
/**
* Replace the transfer with the one given in parameter
*
* @param Object transfer The transfer DTO
*/
setTransfer : function(transfer) {
this._transferName = transfer.name;
this._transferId = transfer.id;
this._type = transfer.type;
this._title.setHTML(this._transferName);
if (this._transfersList._listItems.length) {
this._transfersList.getHtml().remove();
this._transfersList.clear();
}
this.getVisualTransferOptionsList(this._transfersList);
this._transfersList.getHtml().injectInside(this._parent.getParent().getListContainer());
this._transfersList.initializeEvents();
if(this._transfersList.getValidListItems().length == 1){
this._transferTypeValue.setAttribute('class', this._classNameBase + 'Section-Item-Info-ValueNotEditable');
this._transfersList.removeButtonEvent();
this._transfersList.getValidListItems()[0].getHtml().fireEvent('click');
}else{
this._transferTypeValue.setAttribute('class', this._classNameBase + 'Section-Item-Info-Value');
this._transfersList.addButtonEvent();
}
this._parent.getParent().fireEvent('refreshPrice');
},
/**
* Generate the options list for a transfer
* and set an event on each option
*
* @param SchoolList The list to update
*/
getVisualTransferOptionsList : function(list) {
list.clear();
if(this._type != 2 && this._type != 4){
list.addItem(0, this._translateDTO.oneWay);
}
if(this._type != 2 && this._type != 1){
list.addItem(2, this._translateDTO.wayBack);
}
if(this._type != 1 && this._type != 4){
list.addItem(1, this._translateDTO.roundTrip);
}
list.getListItems().each(function(item, index) {
item.getHtml().addClass(this._classNameBase + 'List-Item');
item.getHtml().addEvent('click', function() {
this._transferTypeValue.setHTML(item.getHtmlValue());
this._roundTrip = item.getValue();
this._transferTypeData = item.getValue();
this._parent.getParent().fireEvent('refreshPrice');
}.bind(this));
if((this._roundTrip == 1 && this._type == 1) || (this._roundTrip == 0 && this._type == 2)){
item.getHtml().fireEvent('click');
}
}.bind(this));
},
/**
* Remove the transfer from the list
*
*/
removeTransfer : function() {
this._transfersList.getHtml().remove();
this._container.remove();
}
});
/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @param TransferListItemDTO schoolTransfersDTO the transfers informations
* @param Object translateDTO The DTO containing the translations for this class
* @param SchoolPriceEstimation parent the parent
**/
var SchoolTransfers = Events.extend({
/**
* This is the initialization function
*/
initialize : function(schoolTransfersDTO, translateDTO, parent) {
this._schoolTransfersDTO = schoolTransfersDTO;
this._translateDTO = translateDTO;
this._parent = parent;
this._classNameBase = this.getParent().getClassNameBase();
this._transfers = new Array();
},
/**
* Returns the visual transfer container
*/
getHtml : function() {
this._transferContainer = new Element('div', {'class': this._classNameBase + 'Section'});
this._transferTitle = new Element('div', {'class': this._classNameBase + 'Section-Title'});
this._transferListContainer = new Element('div', {'class': this._classNameBase + 'Courses-CoursesList-Container'});
this._transferUserAccommodationList = new Element('div', {'class': this._classNameBase + 'Courses-UserCoursesList'});
this._transferAddButton = new Element('div', {'class': this._classNameBase + 'AddButton'});
this._transferTitle.injectInside(this._transferContainer);
this._transferListContainer.injectInside(this._transferContainer);
this._transferUserAccommodationList.injectInside(this._transferListContainer);
this._transferAddButton.injectInside(this._transferContainer);
this._transferTitle.setHTML(this._translateDTO.title);
this._transferAddButton.setHTML(this._translateDTO.add);
this._transfersList = new SchoolList(this._transferAddButton, this._classNameBase);
this.getVisualTransferList(this._transfersList);
this._transfersList.getHtml().injectInside(this._parent.getListContainer());
this._transfersList.initializeEvents();
if(!this._schoolTransfersDTO.length){
this._transferContainer.setStyle('display','none');
}
return this._transferContainer;
},
/**
*  Return the classNameBase
*/
getClassNameBase : function() {
return this._classNameBase;
},
/**
* Returns an array containing the informations for the calculation price
*
* @return Array The informations needed to calculate the price
*/
getDTO : function() {
var transfersDTO = new Array();
this._transfers.each(function(item, index) {
if (item.isComplete()) {
transfersDTO.push(item.getDTO());
}
});
return transfersDTO;
},
/**
* Populate the transfers from a dto
*/
populateFromDTO : function(toPopulateDTO) {
if (toPopulateDTO) {
toPopulateDTO.each(function(item, index) {
var transfer;
transfer = this._schoolTransfersDTO.filter(function(itemDTO, indexDTO) {
return itemDTO.id == item.id;
}.bind(this));
if (transfer[0]) {
for(var i = 0; i < this._transfers.length; i++){
if(parseInt(this._transfers[i]._transferId) == parseInt(transfer[0].id)){
this._transfers[i].removeTransfer();
this._transfers.remove(this._transfers[i]);
i--;
}
}
this.addTransfer(item.id);
this._transfers[this._transfers.length - 1].populateFromDTO(item);
}
}.bind(this));
}
},
/**
* Retrieve the list of transfers for this school
*
* @param schoolList list The list to update
*/
getVisualTransferList : function(list) {
list.clear();
this._schoolTransfersDTO.each(function(item, index) {
list.addItem(item.id, item.name);
list.getListItems().getLast().getHtml().addEvent('click', function() {
this.addTransfer(item.id);
}.bind(this));
}.bind(this));
list.addItem('error', this._translateDTO.notAvailable);
if (this._parent.getCompletedCourses().length > 0) {
if (this._schoolTransfersDTO.length) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setHtml(this._translateDTO.noTransfers);
list.getListItems().getLast().setIsValid(true);
}
} else {
list.getListItems().getLast().setHtml(this._translateDTO.notAvailable);
list.getListItems().getLast().setIsValid(true);
}
this.refreshVisualTransferList(list);
},
/**
* Refresh the list of transfers for this school
*
* @param schoolList list The list to update
*/
refreshVisualTransferList : function(list) {
var availableTransfers = this._parent.getAvailableTransfers();
list.getListItems().each(function(item, index) {
if ((!this._schoolTransfersDTO || this._parent.getCompletedCourses().length > 0) && availableTransfers.contains(parseInt(item.getValue()))) {
item.setIsValid(true);
item.setIsSelectionnable(true);
} else {
item.setIsValid(false);
}
}.bind(this));
if (this._parent.getCompletedCourses().length > 0) {
if (this._schoolTransfersDTO.length) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setHtml(this._translateDTO.noTransfers);
list.getListItems().getLast().setIsValid(true);
}
} else {
list.getListItems().getLast().setHtml(this._translateDTO.notAvailable);
list.getListItems().getLast().setIsValid(true);
}
},
/**
* Refresh the transfers lists
*
*/
refreshTransfers : function() {
var transfNb = this._transfers.length;
this.refreshVisualTransferList(this._transfersList);
// refresh every transfer list for the added transfers
for (var i = 0; i < this._transfers.length; i++) {
this._transfers[i].refreshVisualTransferList();
}
if (this._parent.getCompletedCourses().length == 0) {
for (var i = this._transfers.length - 1; i >= 0; i--) {
this._transfers[i].removeTransfer();
this._transfers.remove(this._transfers[i]);
}
this._parent.fireEvent('heightModified');
if (transfNb > 0)this._parent.fireEvent('refreshPrice');
} else {
// get the available transfers List
var availableTransfers = this._parent.getAvailableTransfers();
// remove the unavailable transfers
this._transfers.each(function(item) {
if (!availableTransfers.contains(item.getTransferId())) {
item.removeTransfer();
this._transfers.remove(item);
}
}.bind(this));
// add transfers if they are mandatory
if (!this._transfers.length && availableTransfers.length && this._parent.getIsTransferMandatory()) {
var transfersToAdd = this._schoolTransfersDTO.filter(function(item) {
return  availableTransfers.contains(parseInt(item.id));
});
if (transfersToAdd.length) {
this.addTransfer(transfersToAdd[0].id);
} else {
this.addTransfer(availableTransfers[0]);
}
this._transfers[0].setIsMandatoryTransfer(true);
} else {
if (this._parent.getIsTransferMandatory() && this._transfers.length) {
this._transfers[0].setIsMandatoryTransfer(true);
}
}
}
if (!this._parent.getIsTransferMandatory()) {
for (var i = 0; i < this._transfers.length; i++) {
this._transfers[i].setIsMandatoryTransfer(false);
}
}
if ((this._parent.getIsTransferMandatory() == true && this._transfers.length) || this._parent.getCompletedAccommodations().length == 0) {
this.displayAddButton(false);
} else {
this.displayAddButton(true);
}
},
/**
* Add a transfer from its ID
*
* @param Number id The transfer id
*/
addTransfer : function(id) {
var schoolTransfersDTO = this._schoolTransfersDTO.copy();
var schoolTransfer = schoolTransfersDTO.filter(function(item, index) {
return item.id == id;
}.bind(this));
var newTransfer = new SchoolTransferObject(schoolTransfer[0].id, schoolTransfer[0].name, schoolTransfer[0].type, this._translateDTO.transferObject, this);
this._transfers.push(newTransfer);
newTransfer.createVisualTransfer();
this._transfers.getLast().getHtml().injectInside(this._transferUserAccommodationList);
newTransfer.addEvent('deleteTransfer', function(e) {
this.deleteTransfer(newTransfer);
}.bind(this));
this._parent.fireEvent('heightModified');
this._parent.fireEvent('refreshPrice');
},
/**
* Returns the parent of this object
*
* @return SchoolPriceEstimation The parent
*/
getParent : function() {
return this._parent;
},
/**
* Display or hide the add button
*
* @param boolean isDisplayed True to display the hide button
*/
displayAddButton : function(isDisplayed) {
if (isDisplayed) {
this._transferAddButton.setStyle('display', '');
} else {
this._transferAddButton.setStyle('display', 'none');
}
},
/**
* Returns the number of completed transfers
*
* @return Number The number of completed transfers
*/
getCompletedTransfers : function() {
return this._transfers.length;
},
/**
* Delete the given transfer
*
* @param SchoolTransferObject transfer The transfer to delete
*/
deleteTransfer : function(transfer) {
this._transfers.remove(transfer);
this._parent.fireEvent('heightModified');
this._parent.fireEvent('refreshPrice');
}
});/**
* This class is used for the price estimation functionnalities
*
* @author Yves-André Giroud <yves-andre.giroud@pyrameed.com>
* @copyright Copyright 2007 Pyrameed
*
* @event Event deleteCourse This event is fired when a course is deleted
*
* @param FixedDatesCourseListItemDTO courseDetails courseDetails The object containing the course informations
* @param Object translateDTO The object containing all the translations for this class
* @param SchoolCourses parent The parent
*
**/
var SchoolVariableCourseObject = Events.extend({
/**
* This is the initialization function
*
*/
initialize : function(courseDetails, translateDTO, listContainer, classNamePrefix, parent) {
this._translateDTO = translateDTO;
this._courseDetails = courseDetails;
this._parent = parent;
this._listContainer = listContainer;
this._classNameBase = classNamePrefix;
this._dateFormat = this._parent.getParent().getDateFormat();
this._monthsTranslations = this._parent.getParent().getMonthTranslations();
this._manager = this.getParent().getParent().getParent();
this._manager.addEvent('descriptionsUpdated', function(){
this.updateDescriptions();
}.bind(this));
this._courseStartDate = null;
this._courseEndDate = null;
this._courseDuration = null;
},
/**
* Return the course details DTO
*
* @return CourseDetailsDTO The course Details DTO
*/
getCourseDetails : function() {
return this._courseDetails;
},
/**
* Return true if the course is complete
*
* @return Boolean Return true if the course is complete
*/
isComplete : function() {
if (this._courseStartDate && this._courseEndDate && this._courseDuration) {
return true;
} else {
return false;
}
},
/**
* Generate the html structure of the course
* and add an event on the delete button
*
*/
createVisualCourse : function() {
this._container = new Element('div', {'class': this._classNameBase + 'ItemAdded'});
this._title = new Element('div', {'class': this._classNameBase + 'Section-Item-Title'});
this._subTitle = new Element('div', {'class': this._classNameBase + 'Section-Item-SubTitle'});
this._moreInfo = new Element('div', {'class': this._classNameBase + 'Section-Item-SubTitle MoreInfos'});
this._moreInfo.setStyle('display','none');
this._startDateContainer = new Element('div',{'class': this._classNameBase + 'Section-Item-StartDate-Container'});
this._endDateContainer = new Element('div',{'class': this._classNameBase + 'Section-Item-EndDate-Container'});
this._startDate = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._startDateValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Value ' + this._classNameBase + 'Section-Item-ToUpdate'});
this._endDate = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._endDateValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-ValueNotEditable'});
this._durationContainer = new Element('div',{'class': this._classNameBase + 'Section-Item-Duration-Container'});
this._duration = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Name'});
this._durationValue = new Element('div', {'class': this._classNameBase + 'Section-Item-Info-Value ' + this._classNameBase + 'Section-Item-ToUpdate'});
this._deleteButton = new Element('div', {'class': this._classNameBase + 'Section-Item-DeleteButton'});
this._duration.injectInside(this._durationContainer);
this._durationValue.injectInside(this._durationContainer);
this._startDate.injectInside(this._startDateContainer);
this._startDateValue.injectInside(this._startDateContainer);
this._endDate.injectInside(this._endDateContainer);
this._endDateValue.injectInside(this._endDateContainer);
this._title.injectInside(this._container);
this._moreInfo.injectInside(this._container);
this._subTitle.injectInside(this._container);
new Element('div',{'style':'clear:both'}).injectInside(this._container);
this._startDateContainer.injectInside(this._container);
this._endDateContainer.injectInside(this._container);
this._durationContainer.injectInside(this._container);
this._deleteButton.injectInside(this._container);
new Element('div',{'style':'clear:both'}).injectInside(this._container);
this._title.setHTML(this._courseDetails.name);
this._subTitle.setHTML(this._courseDetails.subtitle);
this._moreInfo.setHTML(this._translateDTO.moreInfos);
this._startDate.setHTML(this._translateDTO.startDate);
this._startDateValue.setHTML(this._translateDTO.dateSelect);
this._endDate.setHTML(this._translateDTO.endDate);
this._endDateValue.setHTML(this._translateDTO.endDateValue);
this._duration.setHTML(this._translateDTO.duration);
this._durationValue.setHTML(this._translateDTO.durationSelect);
this._deleteButton.setHTML(this._translateDTO.deleteButton);
this.updateDescriptions();
// add event listener
this._deleteButton.addEvent('click', function(e) {
this.removeCourse();
this.fireEvent('deleteCourse');
}.bind(this));
this._coursesValidList = new SchoolList(this._title, this._classNameBase);
this.getVisualValidCoursesList(this._coursesValidList);
this._coursesValidList.getHtml().injectInside(this._listContainer);
this._coursesValidList.initializeEvents();
this._schoolStartList = new SchoolList(this._startDateValue, this._classNameBase);
this.getVisualVariableCourseStartDates(this._courseDetails.startDates, this._schoolStartList);
this._schoolStartList.getHtml().injectInside(this._listContainer);
this._schoolStartList.initializeEvents();
this._schoolDurationList = new SchoolList(this._durationValue, this._classNameBase);
this.getVisualVariableCourseDurationList(this._courseDetails.duration, this._schoolDurationList);
this._schoolDurationList.getHtml().injectInside(this._listContainer);
this._schoolDurationList.initializeEvents();
this.refreshLists();
},
updateDescriptions : function(){
if (this._manager.getDescription && this._manager.getDescription('course', this._courseDetails.courseTypeId) && this._manager.getDescription('course', this._courseDetails.courseTypeId) != '') {
this._moreInfo.setAttribute('title', this._courseDetails.name + ' :: ' + this._manager.getDescription('course', this._courseDetails.courseTypeId));
this._moreInfo.setStyle('display','');
if(!this._descriptionToolTip ){
this._descriptionToolTip = new SynergeeTips(this._moreInfo, {'className':'PriceEstimationToolTip', 'hideDelay':1000, 'fixed':true, 'closeButton':true, 'maxHeight':280});
}else {
this._descriptionToolTip.build(this._moreInfo);
}
}else {
this._moreInfo.setStyle('display','none');
}
},
/**
* Returns the html Element of this course
*
* @return Element The HTML view of this course
*/
getHtml : function() {
return this._container;
},
/**
* return the course start date
*
* @return Date The course start date
*/
getCourseStartDate : function() {
return this._courseStartDate;
},
/**
* return the course start date
*
* @return Date The course start date
*/
getCourseEndDate : function() {
return this._courseEndDate;
},
/**
* return the accommodation end date for this course
*
* @return Date The accommodation end date date
*/
getAccommodationEndDate : function() {
var endDate = new Date(this._courseEndDate);
var endDateDay = endDate.getDay();
return endDate;
},
/**
* Return an object containing the informations for the calculation price
*
* @return Object The informations needed to calculate the price
*/
getDTO : function() {
var courseDTO = new Object();
courseDTO.id = this._courseDetails.id;
courseDTO.startDate = this._courseStartDate.toIso();
courseDTO.endDate = this._courseEndDate.toIso();
return courseDTO;
},
/**
* Populate the variable course from a dto
*
* @param Object The fixed course informations needed to populate
*/
populateFromDTO : function(toPopulateDTO) {
this._courseStartDate = (new Date()).fromIso(toPopulateDTO.startDate);
this._startDateValue.setHTML(this._courseStartDate.format(this._dateFormat , this._monthsTranslations));
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
this._courseEndDate = (new Date()).fromIso(toPopulateDTO.endDate);
this._courseDuration = this.getCalculatedDuration(this._courseStartDate, this._courseEndDate );
if(this._courseDetails.duration.length && this._courseDuration < parseInt(this._courseDetails.duration[0])) this._courseDuration = parseInt(this._courseDetails.duration[0]);
if (this._courseDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace("%0", this._courseDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._courseDuration));
}
this._durationValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
// If the start and the duration are set,  the end date is calculated
if (this._courseStartDate && this._courseDuration) {
this._courseEndDate = this.getVariableCourseEndDate();
this._endDateValue.setHTML(this._courseEndDate.format(this._dateFormat , this._monthsTranslations));
}
// when the user selects only the start date, the duration is set with the minimal value
if (this._courseStartDate && !this._courseDuration) {
this._courseDuration = this._courseDetails.duration[0];
if (this._courseDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace("%0", this._courseDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._courseDuration));
}
this._courseEndDate = this.getVariableCourseEndDate();
this._endDateValue.setHTML(this._courseEndDate.format(this._dateFormat , this._monthsTranslations));
}
},
/**
* Refresh all the lists of this course
*
*/
refreshLists : function() {
// add the list of courses that fit the start and end Date
this.refreshVisualValidCoursesList(this._coursesValidList);
// initialize the start date list and its event
this.refreshVisualVariableCourseStartDates(this._parent.getValidVariableCourseStartDate(this), this._schoolStartList);
// initialize the duration list and its event
this.refreshVisualVariableCourseDurationList(this._parent.getValidVariableCourseDuration(this), this._schoolDurationList);
// check if the buttons must be activated or not
if(this._schoolStartList.getValidListItems().length == 1 ){
this._startDateValue.addClass(this._classNameBase + 'Section-Item-Info-ValueNotEditable');
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-Info-Value');
this._schoolStartList.removeButtonEvent();
if(this._courseStartDate != this._schoolStartList.getValidListItems()[0].getValue())this._schoolStartList.getValidListItems()[0].getHtml().fireEvent('click');
}else{
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-Info-ValueNotEditable');
this._startDateValue.addClass(this._classNameBase + 'Section-Item-Info-Value');
this._schoolStartList.addButtonEvent();
}
if(this._schoolDurationList.getValidListItems().length == 1 ){
this._durationValue.addClass(this._classNameBase + 'Section-Item-Info-ValueNotEditable');
this._durationValue.removeClass(this._classNameBase + 'Section-Item-Info-Value');
this._schoolDurationList.removeButtonEvent();
if(parseInt(this._courseDuration) != parseInt(this._schoolDurationList.getValidListItems()[0].getValue()))this._schoolDurationList.getValidListItems()[0].getHtml().fireEvent('click');
}else{
this._durationValue.addClass(this._classNameBase + 'Section-Item-Info-Value');
this._durationValue.removeClass(this._classNameBase + 'Section-Item-Info-ValueNotEditable');
this._schoolDurationList.addButtonEvent();
}
},
/**
* Generate all the lists of this course
*
*/
reGenerateLists : function() {
// remove old list if exists
if (this._coursesValidList._listItems.length) {
this._coursesValidList.getHtml().remove();
this._coursesValidList.clear();
}
if (this._schoolStartList._listItems.length) {
this._schoolStartList.getHtml().remove();
this._schoolStartList.clear();
}
if (this._schoolDurationList._listItems.length) {
this._schoolDurationList.getHtml().remove();
this._schoolDurationList.clear();
}
this.getVisualValidCoursesList(this._coursesValidList);
this._coursesValidList.getHtml().injectInside(this._listContainer);
this._coursesValidList.initializeEvents();
this.getVisualVariableCourseStartDates(this._courseDetails.startDates, this._schoolStartList);
this.refreshVisualVariableCourseStartDates(this._parent.getValidVariableCourseStartDate(this), this._schoolStartList);
this._schoolStartList.getHtml().injectInside(this._listContainer);
this._schoolStartList.initializeEvents();
this.getVisualVariableCourseDurationList(this._courseDetails.duration, this._schoolDurationList);
this.refreshVisualVariableCourseDurationList(this._parent.getValidVariableCourseDuration(this), this._schoolDurationList);
this._schoolDurationList.getHtml().injectInside(this._listContainer);
this._schoolDurationList.initializeEvents();
},
/**
* Refresh the course data
*
*/
refreshVariableCourseData : function() {
// If the start and the duration are set,  the end date is calculated
if (this._courseStartDate && this._courseDuration) {
this._durationValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
this._courseEndDate = this.getVariableCourseEndDate();
this._endDateValue.setHTML(this._courseEndDate.format(this._dateFormat , this._monthsTranslations));
}
// when the user selects only the start date
if (this._courseStartDate && !this._courseDuration) {
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
if(this._courseDuration){
if (this._courseDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace("%0", this._courseDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._courseDuration));
}
this._courseEndDate = this.getVariableCourseEndDate();
this._endDateValue.setHTML(this._courseEndDate.format(this._dateFormat , this._monthsTranslations));
}else {
this.refreshVisualVariableCourseDurationList(this._parent.getValidVariableCourseDuration(this), this._schoolDurationList);
}
}
if (this.isComplete()) {
this._durationValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
this._startDateValue.removeClass(this._classNameBase + 'Section-Item-ToUpdate');
// refresh the course list
this._parent.fireEvent('refreshCourses');
this._parent.fireEvent('refreshPrice');
}
},
/**
*  Returns the endDate of a variable course
*
*  @return Date The variable course end date
*/
getVariableCourseEndDate : function() {
var endDate = new Date(this._courseStartDate.getFullYear(), this._courseStartDate.getMonth(), this._courseStartDate.getDate() + this._courseDuration * 7 + 2);
var endDateDay = endDate.getDay();
if (endDateDay == 0) endDateDay = 7;
while (endDateDay != this._courseDetails.courseEndDay) {
endDate.setDate(endDate.getDate() - 1);
endDateDay = endDate.getDay();
if (endDateDay == 0) endDateDay = 7;
}
return endDate;
},
/**
* Replace the courses and find the best possible dates
*
* @param Object The new course DTO
*/
replaceCourse : function(newCourse) {
this._durationValue.removeClass(this._classNameBase + 'Section-Item-Info-Value');
if (!this._parent.getIsFixedCourse(newCourse)) {
if (this.isComplete()) {
this._courseDetails = newCourse;
this._durationValue.addClass(this._classNameBase + 'Section-Item-Info-Value');
this.replaceVariableCourseDates(this._courseStartDate, this._courseDuration);
this._title.setHTML(this._courseDetails.name);
this._subTitle.setHTML(this._courseDetails.subtitle);
this.reGenerateLists();
this._parent.fireEvent('refreshCourses');
} else {
this._schoolStartList.getHtml().remove();
this._schoolDurationList.getHtml().remove();
this._coursesValidList.getHtml().remove();
this._parent.replaceCourse(this, newCourse);
}
} else {
this._schoolStartList.getHtml().remove();
this._schoolDurationList.getHtml().remove();
this._coursesValidList.getHtml().remove();
if (this.isComplete()) {
this._parent.replaceCourse(this, newCourse, this._courseStartDate);
} else {
this._parent.replaceCourse(this, newCourse);
}
}
this.updateDescriptions();
},
/**
* this method find the best dates and duration for the new variable course based on the old one
*
* @param Date oldStartDate the date of the replaced course
* @param number oldDuration the duration of the replaced course
*/
replaceVariableCourseDates : function(oldStartDate, oldDuration) {
// if the start date is already set
if (oldStartDate) {
var dateDifference = null;
var newDate;
this._courseDetails.startDates.each(function(item, index) {
if (dateDifference > Math.abs(oldStartDate.getTime() - item.getTime()) || dateDifference == null) {
dateDifference = Math.abs(oldStartDate.getTime() - item.getTime());
newDate = item;
}
});
// if there is already a duration set
if (oldDuration) {
var durationDifference = null;
var newDuration;
this._courseDetails.duration.each(function(item, index) {
if (durationDifference > Math.abs(oldDuration - item) || durationDifference == null) {
durationDifference = Math.abs(oldDuration - item);
newDuration = item;
}
});
this._courseDuration = newDuration;
if (this._courseDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace("%0", this._courseDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._courseDuration));
}
}
this._courseStartDate = newDate;
this._startDateValue.setHTML(newDate.format(this._dateFormat , this._monthsTranslations));
this.refreshVariableCourseData();
}
},
/**
* Generate a list of valid course
*
* @param SchoolList list The valid courses list
*
*/
getVisualValidCoursesList : function(list) {
var validCourses = this._parent.getCourses();
// clearing the list
list.clear();
validCourses.each(function(item, index) {
list.addItem(item, item.name);
list.getListItems().getLast().getHtml().addClass(this._classNameBase + 'List-Item');
list.getListItems().getLast().getHtml().addEvent('click', function() {
this.replaceCourse(item);
}.bind(this));
}, this);
this.refreshVisualValidCoursesList(list);
},
/**
* Refresh a list of course that have possible dates between this courseStartDate and courseEndDate
*
* @param SchoolList list The courses list
*
*/
refreshVisualValidCoursesList : function(list) {
var validCourses = this._parent.getValidCourses(this);
list.getListItems().each(function(item, index) {
if (validCourses.indexOf(item.getValue()) != -1) {
item.setIsValid(true);
} else {
item.setIsValid(false);
}
}.bind(this));
},
/**
* This function set a formated list from an array of a course start dates
*
* @param Array startDates An array of Date containing all the possible startDates
* @param SchoolList list The valid courses list
*/
getVisualVariableCourseStartDates : function(startDates, list) {
// clearing the list
list.clear();
startDates.each(function(item, index) {
list.addItem(item, item.format(this._dateFormat , this._monthsTranslations));
index = list.getListItems().indexOf(list.getListItems().getLast());
list.getListItems().getLast().getHtml().addEvent('click', function() {
if (list.getListItems()[index].getIsSelectionnable()) {
// Set the variables for this course
this._courseStartDate = item;
// set the visual data of this course
this._startDateValue.setHTML(item.format(this._dateFormat , this._monthsTranslations));
this.refreshVariableCourseData();
}
}.bind(this));
}.bind(this));
list.addItem('error', this._translateDTO.noValidStartDates);
if (list.getValidListItems().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* this function refresh a list from an array of a course start dates
*
* @param Array validStartDates an array of Date containing the validated startDates
* @param SchoolList list the valid courses list
*/
refreshVisualVariableCourseStartDates : function(validStartDate, list) {
var firstValid = true;
list.getListItems().each(function(item, index) {
if (validStartDate.indexOf(item.getValue()) != -1) {
item.setIsValid(true);
item.setIsSelectionnable(true);
if (firstValid) {
list.setSelectedItem(item);
}
if (this._courseStartDate == item.getValue()) {
list.setSelectedItem(item);
}
firstValid = false;
} else {
if (item.getValue == 'error') {
item.setIsValid(false);
}
item.setIsSelectionnable(false);
}
}.bind(this));
if (list.getValidListItems().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* This function return a formated list from an array of duration
*
* @param Array durations An array of Date containing the startDates
* @param Array validDurations An array of number containing the validated durations
*/
getVisualVariableCourseDurationList : function(durations, list) {
// clearing the list
list.clear();
durations.each(function(item, index) {
if (item > 1) {
list.addItem(item, this._translateDTO.weeks.replace('%0', item));
} else {
list.addItem(item, this._translateDTO.week.replace('%0', item));
}
index = list.getListItems().indexOf(list.getListItems().getLast());
// adding the event on the valid courses
list.getListItems().getLast().getHtml().addEvent('click', function() {
if (list.getListItems()[index].getIsSelectionnable()) {
this._courseDuration = item;
if (this._courseDuration > 1) {
this._durationValue.setHTML(this._translateDTO.weeks.replace("%0", this._courseDuration));
} else {
this._durationValue.setHTML(this._translateDTO.week.replace("%0", this._courseDuration));
}
this.refreshVariableCourseData();
}
}.bind(this));
}.bind(this));
list.addItem('error', this._translateDTO.noValidDuration);
if (list.getValidListItems().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* This function return a formated list from an array of duration
*
* @param Array validDurations An array of number containing the validated durations
* @param SchoolList list The list to refresh
*/
refreshVisualVariableCourseDurationList : function(validDurations, list) {
var firstValid = true;
var lastValid = null;
list.getListItems().each(function(item, index) {
if (validDurations.indexOf(item.getValue()) != -1) {
item.setIsValid(true);
item.setIsSelectionnable(true);
if (firstValid)list.setSelectedItem(item);
if (this._courseDuration == item.getValue()) list.setSelectedItem(item);
firstValid = false;
lastValid = item;
} else {
if (item.getValue == 'error')item.setIsValid(false);
item.setIsSelectionnable(false);
if(this._courseDuration == item.getValue()){
if(lastValid)lastValid.getHtml().fireEvent('click');
}
}
}.bind(this));
if (list.getValidListItems().length > 0) {
list.getListItems().getLast().setIsValid(false);
} else {
list.getListItems().getLast().setIsValid(true);
}
},
/**
* Return the duration in weeks.
* To perform the calculation we count the number of time the week day of the start date
* can be repeated between the start date and the end date.
*
* @param date startDate The start date
* @param date endDate The end date
* @return integer the number of weeks
*/
getCalculatedDuration : function(startDate, endDate) {
startDate = startDate.getTime();
endDate = endDate.getTime() - (86400 * 2 * 1000);
var numberOfWeeks = 0;
while(startDate <= endDate) {
numberOfWeeks++;
startDate += (86400 * 7 * 1000);
}
return numberOfWeeks;
},
/**
*  Returns the available accommodations for this course
*
* @return Array of integer The Accommodation IDs
*/
getAvailableAccommodations : function() {
return this._courseDetails.availableAccommodations;
},
/**
*  return the course duration
*
* @return integer The course duration
*/
getCourseDuration : function() {
return this._courseDuration;
},
/**
* Returns false is it's not a fixed course
*
* @return Boolean Return false because it's a variable course
*/
getIsFixedCourse : function() {
return false;
},
/**
* return the parent
*
* @return SchoolCourses The parent
*/
getParent : function() {
return this._parent;
},
/**
* Remove the course from the list
*
*/
removeCourse : function() {
this._schoolStartList.getHtml().remove();
this._schoolDurationList.getHtml().remove();
this._coursesValidList.getHtml().remove();
this._container.remove();
}
});
var Lightbox={init:function(options){this.options=Object.extend({resizeDuration:400,resizeTransition:Fx.Transitions.sineInOut,initialWidth:250,initialHeight:250,animateCaption:true,defaultIframeWidth:500,defaultIframeHeight:300},options||{});if(window.ie6&&document.compatMode=="BackCompat"){this.options.animateCaption=false}this.anchors=[];$each(document.links,function(el){if(el.rel&&el.rel.test(/^lightbox/i)){el.onclick=this.click.pass(el,this);this.anchors.push(el)}},this);this.eventKeyDown=this.keyboardListener.bindAsEventListener(this);this.eventPosition=this.position.bind(this);this.overlay=new Element("div").setProperty("id","lbOverlay").injectInside(document.body);this.center=new Element("div").setProperty("id","lbCenter").setStyles({width:this.options.initialWidth+"px",height:this.options.initialHeight+"px",marginLeft:"-"+(this.options.initialWidth/2)+"px",display:"none"}).injectInside(document.body);this.canvas=new Element("div").setProperty("id","lbCanvas").injectInside(this.center);new Element("a").setProperties({id:"lbCloseLinkTop",href:"#"}).injectInside(this.canvas).onclick=this.overlay.onclick=this.close.bind(this);this.prevLink=new Element("a").setProperties({id:"lbPrevLink",href:"#"}).setStyle("display","none").injectInside(this.canvas);this.nextLink=this.prevLink.clone().setProperty("id","lbNextLink").injectInside(this.canvas);this.prevLink.onclick=this.previous.bind(this);this.nextLink.onclick=this.next.bind(this);this.bottomContainer=new Element("div").setProperty("id","lbBottomContainer").setStyle("display","none").injectInside(document.body);this.bottom=new Element("div").setProperty("id","lbBottom").injectInside(this.bottomContainer);new Element("a").setProperties({id:"lbCloseLink",href:"#"}).injectInside(this.bottom).onclick=this.overlay.onclick=this.close.bind(this);this.caption=new Element("div").setProperty("id","lbCaption").injectInside(this.bottom);this.number=new Element("div").setProperty("id","lbNumber").injectInside(this.bottom);new Element("div").setStyle("clear","both").injectInside(this.bottom);var nextEffect=this.nextEffect.bind(this);this.fx={overlay:this.overlay.effect("opacity",{duration:500}).hide(),resizeCenter:this.center.effects({duration:this.options.resizeDuration,transition:this.options.resizeTransition,onComplete:nextEffect}),image:this.canvas.effect("opacity",{duration:500,onComplete:nextEffect}),bottom:this.bottomContainer.effect("height",{duration:400,onComplete:nextEffect})};this.preloadPrev=new Image();this.preloadNext=new Image()},click:function(link){if(link.rel.length==8){return this.show(link.href,link.title,link.rev)}var j,itemNumber,items=[];this.anchors.each(function(el){if(el.rel==link.rel){for(j=0;j<items.length;j++){if(items[j][0]==el.href&&items[j][2]==el.rev){break}}if(j==items.length){items.push([el.href,el.title,el.rev]);if(el.href==link.href&&el.rev==link.rev){itemNumber=j}}}},this);return this.open(items,itemNumber)},show:function(url,title,rev){return this.open([[url,title,rev]],0)},open:function(items,itemNumber){this.items=items;this.position();this.setup(true);var wh=(window.getHeight()==0)?window.getScrollHeight():window.getHeight();var st=document.body.scrollTop||document.documentElement.scrollTop;var rev=this.items[0][2];var height=this.matchOrDefault(rev,new RegExp("height=(\\d+)","i"),600);this.top=st+((wh-(height))/2)-30;this.center.setStyles({top:this.top+"px",display:""});this.fx.overlay.start(0.8);return this.changeItem(itemNumber)},position:function(){var ww=(window.getWidth()==0)?window.getScrollWidth()-22:window.getWidth();var wh=(window.getHeight()==0)?window.getScrollHeight():window.getHeight();var st=document.body.scrollTop||document.documentElement.scrollTop;this.overlay.setStyles({top:st+"px",height:wh+"px",width:ww+"px"})},setup:function(open){var elements=$A(document.getElementsByTagName("object"));if(window.ie){elements.extend(document.getElementsByTagName("select"))}elements.each(function(el){el.style.visibility=open?"hidden":""});var fn=open?"addEvent":"removeEvent";window[fn]("scroll",this.eventPosition)[fn]("resize",this.eventPosition);document[fn]("keydown",this.eventKeyDown);this.step=0},keyboardListener:function(event){switch(event.keyCode){case 27:case 88:case 67:this.close();break;case 37:case 80:this.previous();break;case 39:case 78:this.next()}},previous:function(){return this.changeItem(this.activeItem-1)},next:function(){return this.changeItem(this.activeItem+1)},changeItem:function(itemNumber){if(this.step||(itemNumber<0)||(itemNumber>=this.items.length)){return false}this.step=1;this.activeItem=itemNumber;this.bottomContainer.style.display=this.prevLink.style.display=this.nextLink.style.display="none";this.fx.image.hide();this.center.className="lbLoading";this.removeCurrentItem();var url=this.items[this.activeItem][0];var rev=this.items[this.activeItem][2];var re_imageURL=/\.(jpe?g|png|gif|bmp)/i;var re_flashURL=/\.(swf)/i;var re_youtubeURL=/http\:\/\/(?:www\.){0,1}youtube\.com\/watch\?v=(.*)?/i;var re_dailymotionURL=/^http\:\/\/(?:www\.){0,1}dailymotion\.com\/video\/(.*?)\_/i;var re_streamURL=/stream\.(php)/i;var re_externalStreamURL=/^http\:\/\/(.*).(mp4|flv)/i;var re_downloadURL=/download\.php\?ressource=(.*)\&filename=(.*)/i;var re_hiddenDivURL=/\{hiddenId\|(\w+)\}/i;var matches=null;if(url.match(re_imageURL)){this.preload=new Image();this.preload.datatype="image";this.preload.w=this.matchOrDefault(rev,new RegExp("width=(\\d+%?)","i"),-1);this.preload.h=this.matchOrDefault(rev,new RegExp("height=(\\d+%?)","i"),-1);this.preload.onload=this.nextEffect.bind(this);this.preload.src=url}else{if(url.match(re_flashURL)){this.preload=new Object();this.preload.datatype="flash";this.preload.w=this.matchOrDefault(rev,new RegExp("width=(\\d+)","i"),425);this.preload.h=this.matchOrDefault(rev,new RegExp("height=(\\d+)","i"),355);this.preload.src=url;this.nextEffect()}else{if(url.match(re_streamURL)){this.preload=new Object();this.preload.datatype="stream";this.preload.w=this.matchOrDefault(rev,new RegExp("width=(\\d+)","i"),425);this.preload.h=this.matchOrDefault(rev,new RegExp("height=(\\d+)","i"),355);this.preload.src=url;this.nextEffect()}else{if(matches=url.match(re_downloadURL)){this.preload=new Object();if(matches[2].match(/\.flv/)||matches[2].match(/\.mp4/)){this.preload.src="stream.php?media="+matches[2];this.preload.datatype="stream"}else{this.preload.src="ressource.php?media="+matches[2];this.preload.datatype="iframe"}this.preload.w=this.matchOrDefault(rev,new RegExp("width=(\\d+)","i"),425);this.preload.h=this.matchOrDefault(rev,new RegExp("height=(\\d+)","i"),355);this.nextEffect()}else{if(matches=url.match(re_youtubeURL)){this.preload=new Object();this.preload.datatype="youtube";this.preload.w=this.matchOrDefault(rev,new RegExp("width=(\\d+)","i"),this.options.defaultIframeWidth);this.preload.h=this.matchOrDefault(rev,new RegExp("height=(\\d+)","i"),this.options.defaultIframeHeight);this.preload.src=matches[1];this.nextEffect()}else{if(matches=url.match(re_dailymotionURL)){this.preload=new Object();this.preload.datatype="dailymotion";this.preload.w=this.matchOrDefault(rev,new RegExp("width=(\\d+)","i"),this.options.defaultIframeWidth);this.preload.h=this.matchOrDefault(rev,new RegExp("height=(\\d+)","i"),this.options.defaultIframeHeight);this.preload.src=matches[1];this.nextEffect()}else{if(matches=url.match(re_hiddenDivURL)){this.preload=new Object();this.preload.datatype="hidden";this.preload.src=matches[1];this.preload.w=this.matchOrDefault(rev,new RegExp("width=(\\d+)","i"),this.options.defaultIframeWidth);this.preload.h=this.matchOrDefault(rev,new RegExp("height=(\\d+)","i"),this.options.defaultIframeHeight);this.nextEffect()}else{if(matches=url.match(re_externalStreamURL)){this.preload=new Object();this.preload.src=url;this.preload.datatype="stream";this.preload.w=this.matchOrDefault(rev,new RegExp("width=(\\d+)","i"),425);this.preload.h=this.matchOrDefault(rev,new RegExp("height=(\\d+)","i"),355);this.nextEffect()}else{this.preload=new Object();this.preload.datatype="iframe";this.preload.w=this.matchOrDefault(rev,new RegExp("width=(\\d+)","i"),this.options.defaultIframeWidth);this.preload.h=this.matchOrDefault(rev,new RegExp("height=(\\d+)","i"),this.options.defaultIframeHeight);this.preload.src=url;this.nextEffect()}}}}}}}}return false},nextEffect:function(){switch(this.step++){case 1:this.center.className="";if(this.preload.datatype=="image"){var ws=(this.preload.w==-1)?this.preload.width.toString():this.preload.w.toString();var hs=(this.preload.h==-1)?this.preload.height.toString():this.preload.h.toString();this.p_width=(q=ws.match(/(\d+)%/))?q[1]*this.preload.width*0.01:ws;this.p_height=(q=hs.match(/(\d+)%/))?q[1]*this.preload.height*0.01:hs;new Element("img").setProperties({id:"lbImage",src:this.preload.src,width:this.p_width,height:this.p_height}).injectInside(this.canvas);this.nextLink.style.right=""}else{if(this.preload.datatype=="youtube"){this.p_width=this.preload.w;this.p_height=this.preload.h;var so=new SWFObject("http://www.youtube.com/v/"+this.preload.src+"&rel=0&autoplay=1&enablejsapi=1&playerapiid=lbYoutube","lbYoutubePlayer",this.p_width,this.p_height,"8","#FFFFFF");new Element("div").setProperties({id:"lbYoutube"}).injectInside(this.canvas);so.write("lbYoutube")}else{if(this.preload.datatype=="dailymotion"){this.p_width=this.preload.w;this.p_height=this.preload.h;var so=new SWFObject("http://www.dailymotion.com/swf/"+this.preload.src+"&v3=1&related=0&autoplay=1","lbDailymotionPlayer",this.p_width,this.p_height,"8","#FFFFFF");new Element("div").setProperties({id:"lbDailymotion"}).injectInside(this.canvas);so.write("lbDailymotion")}else{if(this.preload.datatype=="stream"){this.p_width=this.preload.w;this.p_height=this.preload.h;var so=new SWFObject(window.getCurrentPageLocation()+"Themes/Default/Components/Video/Flash/mediaplayer.swf","lbStreamPlayer",this.p_width,this.p_height,"8","#FFFFFF");so.addParam("allowfullscreen","true");so.addVariable("type","flv");so.addVariable("displayheight",this.p_height);so.addVariable("file",this.preload.src);so.addVariable("enablejs","true");so.addVariable("overstretch","true");new Element("div").setProperties({id:"lbStream"}).injectInside(this.canvas);so.write("lbStream")}else{if(this.preload.datatype=="flash"){this.p_width=this.preload.w;this.p_height=this.preload.h;var so=new SWFObject(this.preload.src,"lbFlashPlayer",this.p_width,this.p_height,"8","#FFFFFF");new Element("div").setProperties({id:"lbFlash"}).injectInside(this.canvas);so.write("lbFlash")}else{if(this.preload.datatype=="googleMap"){this.p_width=this.preload.w;this.p_height=this.preload.h;this.iframeId="mapContainer";new Element("iframe").setProperties({id:this.iframeId,width:this.p_width,height:this.p_height,frameBorder:0,scrolling:"auto",src:this.preload.src+"&output=embed&s=AARTsJrrJfAezwFwvFA6u8OWSecjpwNIVw"}).injectInside(this.canvas);this.nextLinkscr.style.right="25px"}else{if(this.preload.datatype=="hidden"){this.p_width=this.preload.w;this.p_height=this.preload.h;this.iframeId=this.preload.src;$(this.iframeId).setStyles({left:"0px",top:"0px",height:this.p_height,width:this.p_width,display:"block"});$(this.preload.src).setProperties({width:this.p_width,height:this.p_height,frameBorder:0,scrolling:"auto"}).injectInside(this.canvas);this.nextLink.style.right="25px"}else{this.p_width=this.preload.w;this.p_height=this.preload.h;this.iframeId="lbFrame_"+new Date().getTime();try{new Element("iframe").setProperties({id:this.iframeId,width:this.p_width,height:this.p_height,frameBorder:0,scrolling:"auto",src:this.preload.src}).injectInside(this.canvas)}catch(ex){}this.nextLink.style.right="25px"}}}}}}}this.canvas.style.width=this.bottom.style.width=this.p_width+"px";this.canvas.style.height=this.prevLink.style.height=this.nextLink.style.height=this.p_height+"px";this.caption.setHTML(this.items[this.activeItem][1]||"");this.number.setHTML((this.items.length==1)?"":"Page "+(this.activeItem+1)+" of "+this.items.length);if(this.activeItem){this.preloadPrev.src=this.items[this.activeItem-1][0]}if(this.activeItem!=(this.items.length-1)){this.preloadNext.src=this.items[this.activeItem+1][0]}if(this.center.clientHeight!=this.canvas.offsetHeight){var oh=(this.p_height==this.canvas.clientHeight)?this.canvas.offsetHeight:eval(this.p_height)+18;this.fx.resizeCenter.start({height:oh});break}this.step++;case 2:if(this.center.clientWidth!=this.canvas.offsetWidth){var ow=(this.p_width==this.canvas.clientWidth)?this.canvas.offsetWidth:eval(this.p_width)+18;this.fx.resizeCenter.start({width:ow,marginLeft:-ow/2});break}this.step++;case 3:this.bottomContainer.setStyles({top:(this.top+this.center.clientHeight)+"px",height:"0px",marginLeft:this.center.style.marginLeft,width:this.center.style.width,display:""});this.fx.image.start(1);break;case 4:if(this.options.animateCaption){this.fx.bottom.start(0,this.bottom.offsetHeight+10);break}this.bottomContainer.style.height=(this.bottom.offsetHeight+10)+"px";case 5:if(this.activeItem){this.prevLink.style.display=""}if(this.activeItem!=(this.items.length-1)){this.nextLink.style.display=""}if(this.preload.datatype=="stream"){try{$("lbStreamPlayer").sendEvent("playpause")}catch(ex){}}else{if(this.preload.datatype=="youtube"){try{$("lbYoutube").playVideo()}catch(ex){}}}window.fireEvent("slimboxready");this.step=0}},close:function(){if(this.step<0){return}this.step=-1;this.removeCurrentItem();for(var f in this.fx){this.fx[f].stop()}this.center.style.display=this.bottomContainer.style.display="none";this.center.style.width=this.options.initialWidth+"px";this.center.style.height=this.options.initialHeight+"px";this.center.style.marginLeft="-"+(this.options.initialWidth/2)+"px";this.fx.overlay.chain(this.setup.pass(false,this)).start(0);return false},removeCurrentItem:function(){if(this.preload){if(this.preload.datatype=="image"){$("lbImage").remove();this.preload.onload=Class.empty}else{if(this.preload.datatype=="youtube"){$("lbYoutubePlayer").parentNode.removeChild($("lbYoutubePlayer"))}else{if(this.preload.datatype=="dailymotion"){$("lbDailymotionPlayer").parentNode.removeChild($("lbDailymotionPlayer"))}else{if(this.preload.datatype=="flash"){$("lbFlashPlayer").parentNode.removeChild($("lbFlashPlayer"))}else{if(this.preload.datatype=="stream"){$("lbStreamPlayer").parentNode.removeChild($("lbStreamPlayer"))}else{if(this.preload.datatype=="googleMap"){$(this.iframeId).remove()}else{if(this.preload.datatype=="hidden"){$(this.iframeId).setStyle("display","none")}else{$(this.iframeId).remove()}}}}}}}this.preload=null}},matchOrDefault:function(str,re,val){if(!str){return val}var hasQuery=str.match(re);return hasQuery?hasQuery[1]:val}};window.addEvent("domready",Lightbox.init.bind(Lightbox)); if(window.ie)window.addEvent("load",Lightbox.init.bind(Lightbox));/**
* SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
*
* SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
* http://www.opensource.org/licenses/mit-license.php
*
*/
if(typeof deconcept == "undefined") var deconcept = new Object();
if(typeof deconcept.util == "undefined") deconcept.util = new Object();
if(typeof deconcept.SWFObjectUtil == "undefined") deconcept.SWFObjectUtil = new Object();
deconcept.SWFObject = function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey) {
if (!document.getElementById) { return; }
this.DETECT_KEY = detectKey ? detectKey : 'detectflash';
this.skipDetect = deconcept.util.getRequestParameter(this.DETECT_KEY);
this.params = new Object();
this.variables = new Object();
this.attributes = new Array();
if(swf) { this.setAttribute('swf', swf); }
if(id) { this.setAttribute('id', id); }
if(w) { this.setAttribute('width', w); }
if(h) { this.setAttribute('height', h); }
if(ver) { this.setAttribute('version', new deconcept.PlayerVersion(ver.toString().split("."))); }
this.installedVer = deconcept.SWFObjectUtil.getPlayerVersion();
if (!window.opera && document.all && this.installedVer.major > 7) {
// only add the onunload cleanup if the Flash Player version supports External Interface and we are in IE
deconcept.SWFObject.doPrepUnload = true;
}
if(c) { this.addParam('bgcolor', c); }
var q = quality ? quality : 'high';
this.addParam('quality', q);
this.setAttribute('useExpressInstall', false);
this.setAttribute('doExpressInstall', false);
var xir = (xiRedirectUrl) ? xiRedirectUrl : window.location;
this.setAttribute('xiRedirectUrl', xir);
this.setAttribute('redirectUrl', '');
if(redirectUrl) { this.setAttribute('redirectUrl', redirectUrl); }
};
deconcept.SWFObject.prototype = {
useExpressInstall: function(path) {
this.xiSWFPath = !path ? "expressinstall.swf" : path;
this.setAttribute('useExpressInstall', true);
},
setAttribute: function(name, value){
this.attributes[name] = value;
},
getAttribute: function(name){
return this.attributes[name];
},
addParam: function(name, value){
this.params[name] = value;
},
getParams: function(){
return this.params;
},
addVariable: function(name, value){
this.variables[name] = value;
},
getVariable: function(name){
return this.variables[name];
},
getVariables: function(){
return this.variables;
},
getVariablePairs: function(){
var variablePairs = new Array();
var key;
var variables = this.getVariables();
for(key in variables){
variablePairs[variablePairs.length] = key +"="+ variables[key];
}
return variablePairs;
},
getSWFHTML: function() {
var swfNode = "";
if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { // netscape plugin architecture
if (this.getAttribute("doExpressInstall")) {
this.addVariable("MMplayerType", "PlugIn");
this.setAttribute('swf', this.xiSWFPath);
}
swfNode = '<embed type="application/x-shockwave-flash" src="'+ this.getAttribute('swf') +'" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'"';
swfNode += ' id="'+ this.getAttribute('id') +'" name="'+ this.getAttribute('id') +'" ';
var params = this.getParams();
for(var key in params){ swfNode += [key] +'="'+ params[key] +'" '; }
var pairs = this.getVariablePairs().join("&");
if (pairs.length > 0){ swfNode += 'flashvars="'+ pairs +'"'; }
swfNode += '/>';
} else { // PC IE
if (this.getAttribute("doExpressInstall")) {
this.addVariable("MMplayerType", "ActiveX");
this.setAttribute('swf', this.xiSWFPath);
}
swfNode = '<object id="'+ this.getAttribute('id') +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'">';
swfNode += '<param name="movie" value="'+ this.getAttribute('swf') +'" />';
var params = this.getParams();
for(var key in params) {
swfNode += '<param name="'+ key +'" value="'+ params[key] +'" />';
}
var pairs = this.getVariablePairs().join("&");
if(pairs.length > 0) {swfNode += '<param name="flashvars" value="'+ pairs +'" />';}
swfNode += "</object>";
}
return swfNode;
},
write: function(elementId){
if(this.getAttribute('useExpressInstall')) {
// check to see if we need to do an express install
var expressInstallReqVer = new deconcept.PlayerVersion([6,0,65]);
if (this.installedVer.versionIsValid(expressInstallReqVer) && !this.installedVer.versionIsValid(this.getAttribute('version'))) {
this.setAttribute('doExpressInstall', true);
this.addVariable("MMredirectURL", escape(this.getAttribute('xiRedirectUrl')));
document.title = document.title.slice(0, 47) + " - Flash Player Installation";
this.addVariable("MMdoctitle", document.title);
}
}
if(this.skipDetect || this.getAttribute('doExpressInstall') || this.installedVer.versionIsValid(this.getAttribute('version'))){
var n = (typeof elementId == 'string') ? document.getElementById(elementId) : elementId;
n.innerHTML = this.getSWFHTML();
return true;
}else{
if(this.getAttribute('redirectUrl') != "") {
document.location.replace(this.getAttribute('redirectUrl'));
}
}
return false;
}
};
/* ---- detection functions ---- */
deconcept.SWFObjectUtil.getPlayerVersion = function(){
var PlayerVersion = new deconcept.PlayerVersion([0,0,0]);
if(navigator.plugins && navigator.mimeTypes.length){
var x = navigator.plugins["Shockwave Flash"];
if(x && x.description) {
PlayerVersion = new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split("."));
}
}else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ // if Windows CE
var axo = 1;
var counter = 3;
while(axo) {
try {
counter++;
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ counter);
//				document.write("player v: "+ counter);
PlayerVersion = new deconcept.PlayerVersion([counter,0,0]);
} catch (e) {
axo = null;
}
}
} else { // Win IE (non mobile)
// do minor version lookup in IE, but avoid fp6 crashing issues
// see http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/
try{
var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
}catch(e){
try {
var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
PlayerVersion = new deconcept.PlayerVersion([6,0,21]);
axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code)
} catch(e) {
if (PlayerVersion.major == 6) {
return PlayerVersion;
}
}
try {
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
} catch(e) {}
}
if (axo != null) {
PlayerVersion = new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));
}
}
return PlayerVersion;
};
deconcept.PlayerVersion = function(arrVersion){
this.major = arrVersion[0] != null ? parseInt(arrVersion[0]) : 0;
this.minor = arrVersion[1] != null ? parseInt(arrVersion[1]) : 0;
this.rev = arrVersion[2] != null ? parseInt(arrVersion[2]) : 0;
};
deconcept.PlayerVersion.prototype.versionIsValid = function(fv){
if(this.major < fv.major) return false;
if(this.major > fv.major) return true;
if(this.minor < fv.minor) return false;
if(this.minor > fv.minor) return true;
if(this.rev < fv.rev) return false;
return true;
};
/* ---- get value of query string param ---- */
deconcept.util = {
getRequestParameter: function(param) {
var q = document.location.search || document.location.hash;
if (param == null) { return q; }
if(q) {
var pairs = q.substring(1).split("&");
for (var i=0; i < pairs.length; i++) {
if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
return pairs[i].substring((pairs[i].indexOf("=")+1));
}
}
}
return "";
}
};
/* fix for video streaming bug */
deconcept.SWFObjectUtil.cleanupSWFs = function() {
var objects = document.getElementsByTagName("OBJECT");
for (var i = objects.length - 1; i >= 0; i--) {
objects[i].style.display = 'none';
for (var x in objects[i]) {
if (typeof objects[i][x] == 'function') {
objects[i][x] = function(){};
}
}
}
};
// fixes bug in some fp9 versions see http://blog.deconcept.com/2006/07/28/swfobject-143-released/
if (deconcept.SWFObject.doPrepUnload) {
if (!deconcept.unloadSet) {
deconcept.SWFObjectUtil.prepUnload = function() {
__flash_unloadHandler = function(){};
__flash_savedUnloadHandler = function(){};
window.attachEvent("onunload", deconcept.SWFObjectUtil.cleanupSWFs);
};
window.attachEvent("onbeforeunload", deconcept.SWFObjectUtil.prepUnload);
deconcept.unloadSet = true;
}
};
/* add document.getElementById if needed (mobile IE < 5) */
if (!document.getElementById && document.all) { document.getElementById = function(id) { return document.all[id]; }}
/* add some aliases for ease of use/backwards compatibility */
var getQueryParamValue = deconcept.util.getRequestParameter;
var FlashObject = deconcept.SWFObject; // for legacy support
var SWFObject = deconcept.SWFObject;
// Calendar: a Javascript class for Mootools that adds accessible and unobtrusive date pickers to your form elements <http://electricprism.com/aeron/calendar>
// Calendar RC4, Copyright (c) 2007 Aeron Glemann <http://electricprism.com/aeron>, MIT Style License.
var Calendar = new Class({
options: {
blocked: [], // blocked dates
classes: [], // ['calendar', 'prev', 'next', 'month', 'year', 'today', 'invalid', 'valid', 'inactive', 'active', 'hover', 'hilite']
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // days of the week starting at sunday
direction: 0, // -1 past, 0 past + future, 1 future
draggable: true,
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
navigation: 1, // 0 = no nav; 1 = single nav for month; 2 = dual nav for month and year
offset: 0, // first day of the week: 0 = sunday, 1 = monday, etc..
onHideStart: Class.empty,
onHideComplete: Class.empty,
onShowStart: Class.empty,
onShowComplete: Class.empty,
maxYear : 2999,
pad: 1, // padding between multiple calendars
tweak: {x: 0, y: 0} // tweak calendar positioning
},
// initialize: calendar constructor
// @param obj (obj) a js object containing the form elements and format strings { id: 'format', id: 'format' etc }
// @param props (obj) optional properties
initialize: function(obj, options) {
// basic error checking
if (!obj) { return false; }
this.setOptions(options);
// create our classes array
var keys = ['calendar', 'prev', 'next', 'month', 'year', 'today', 'invalid', 'valid', 'inactive', 'active', 'hover', 'hilite'];
var values = keys.map(function(key, i) {
if (this.options.classes[i]) {
if (this.options.classes[i].length) { key = this.options.classes[i]; }
}
return key;
}, this);
this.classes = values.associate(keys);
// create cal element with css styles required for proper cal functioning
this.calendar = new Element('div', {
'styles': { left: '-1000px', opacity: 0, position: 'absolute', top: '-1000px', zIndex: 1000 }
}).addClass(this.classes.calendar).injectInside(document.body);
// iex 6 needs a transparent iframe underneath the calendar in order to not allow select elements to render through
if (window.ie6) {
this.iframe = new Element('iframe', {
'styles': { left: '-1000px', position: 'absolute', top: '-1000px', zIndex: 999 }
}).injectInside(document.body);
this.iframe.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';
}
// initialize fade method
this.fx = this.calendar.effect('opacity', {
onStart: function() {
if (this.calendar.getStyle('opacity') == 0) { // show
if (window.ie6) { this.iframe.setStyle('display', 'block'); }
this.calendar.setStyle('display', 'block');
this.fireEvent('onShowStart', this.element);
}
else { // hide
this.fireEvent('onHideStart', this.element);
}
}.bind(this),
onComplete: function() {
if (this.calendar.getStyle('opacity') == 0) { // hidden
this.calendar.setStyle('display', 'none');
if (window.ie6) { this.iframe.setStyle('display', 'none'); }
this.fireEvent('onHideComplete', this.element);
}
else { // shown
this.fireEvent('onShowComplete', this.element);
}
}.bind(this)
});
// initialize drag method
if (window.Drag && this.options.draggable) {
this.drag = new Drag.Move(this.calendar, {
onDrag: function() {
if (window.ie6) { this.iframe.setStyles({ left: this.calendar.style.left, top: this.calendar.style.top }); }
}.bind(this)
});
}
// create calendars array
this.calendars = [];
this._id = 0;
var d = new Date(); // today
d.setDate(d.getDate() + this.options.direction.toInt()); // correct today for directional offset
for (var i in obj) {
var cal = {
button: new Element('button').setProperties({'type': 'button'}),
el: $(i),
els: [],
id: this._id++,
month: d.getMonth(),
visible: false,
year: d.getFullYear()
};
// fix for bad element (naughty, naughty element!)
if (!this.element(i, obj[i], cal)) { continue; }
cal.el.addClass(this.classes.calendar);
// create cal button
cal.button.addClass(this.classes.calendar).addEvent('click', function(cal) { this.toggle(cal); }.pass(cal, this)).injectAfter(cal.el);
// read in default value
cal.val = this.read(cal);
$extend(cal, this.bounds(cal)); // abs bounds of calendar
$extend(cal, this.values(cal)); // valid days, months, years
if(cal.val)
this.rebuild(cal);
this.calendars.push(cal); // add to cals array
}
},
addElement: function(obj){
var d = new Date(); // today
d.setDate(d.getDate() + this.options.direction.toInt()); // correct today for directional offset
for (var i in obj) {
var cal = {
button: new Element('button').setProperties({'type': 'button'}),
el: $(i),
els: [],
id: this._id++,
month: d.getMonth(),
visible: false,
year: d.getFullYear()
};
// fix for bad element (naughty, naughty element!)
if (!this.element(i, obj[i], cal)) { continue; }
cal.el.addClass(this.classes.calendar);
// create cal button
cal.button.addClass(this.classes.calendar).addEvent('click', function(cal) { this.toggle(cal); }.pass(cal, this)).injectAfter(cal.el);
// read in default value
//	cal.val = this.read(cal);
$extend(cal, this.bounds(cal)); // abs bounds of calendar
$extend(cal, this.values(cal)); // valid days, months, years
//this.rebuild(cal);
this.calendars.push(cal); // add to cals array
}
},
// blocked: returns an array of blocked days for the month / year
// @param cal (obj)
// @returns blocked days (array)
blocked: function(cal) {
var blocked = [];
var offset = new Date(cal.year, cal.month, 1).getDay(); // day of the week (offset)
var last = new Date(cal.year, cal.month + 1, 0).getDate(); // last day of this month
this.options.blocked.each(function(date){
var values = date.split(' ');
// preparation
for (var i = 0; i <= 3; i++){
if (!values[i]){ values[i] = (i == 3) ? '' : '*'; } // make sure blocked date contains values for at least d, m and y
values[i] = values[i].contains(',') ? values[i].split(',') : new Array(values[i]); // split multiple values
var count = values[i].length - 1;
for (var j = count; j >= 0; j--){
if (values[i][j].contains('-')){ // a range
var val = values[i][j].split('-');
for (var k = val[0]; k <= val[1]; k++){
if (!values[i].contains(k)){ values[i].push(k + ''); }
}
values[i].splice(j, 1);
}
}
}
// execution
if (values[2].contains(cal.year + '') || values[2].contains('*')){
if (values[1].contains(cal.month + 1 + '') || values[1].contains('*')){
values[0].each(function(val){ // if blocked value indicates this month / year
if (val > 0){ blocked.push(val.toInt()); } // add date to blocked array
});
if (values[3]){ // optional value for day of week
for (var i = 0; i < last; i++){
var day = (i + offset) % 7;
if (values[3].contains(day + '')){
blocked.push(i + 1); // add every date that corresponds to the blocked day of the week to the blocked array
}
}
}
}
}
}, this);
return blocked;
},
// bounds: returns the start / end bounds of the calendar
// @param cal (obj)
// @returns obj
bounds: function(cal) {
// 1. first we assume the calendar has no bounds (or a thousand years in either direction)
// by default the calendar will accept a millennium in either direction
var start = new Date(1000, 0, 1); // jan 1, 1000
var end = new Date(2999, 11, 31); // dec 31, 2999
// 2. but if the cal is one directional we adjust accordingly
var date = new Date().getDate() + this.options.direction.toInt();
if (this.options.direction > 0) {
start = new Date();
start.setDate(date + this.options.pad * cal.id);
}
if (this.options.direction < 0) {
end = new Date();
end.setDate(date - this.options.pad * (this.calendars.length - cal.id - 1));
}
// 3. then we can further filter the limits by using the pre-existing values in the selects
cal.els.each(function(el) {
if (el.getTag() == 'select') {
if (el.format.test('(y|Y)')) { // search for a year select
var years = [];
el.getChildren().each(function(option) { // get options
var values = this.unformat(option.value, el.format);
if (!years.contains(values[0])) { years.push(values[0]); } // add to years array
}, this);
years.sort(this.sort);
if (years[0] > start.getFullYear()) {
d = new Date(years[0], start.getMonth() + 1, 0); // last day of new month
if (start.getDate() > d.getDate()) { start.setDate(d.getDate()); }
start.setYear(years[0]);
}
if (years.getLast() < end.getFullYear()) {
d = new Date(years.getLast(), end.getMonth() + 1, 0); // last day of new month
if (end.getDate() > d.getDate()) { end.setDate(d.getDate()); }
end.setYear(years.getLast());
}
}
if (el.format.test('(F|m|M|n)')) { // search for a month select
var months_start = [];
var months_end = [];
el.getChildren().each(function(option) { // get options
var values = this.unformat(option.value, el.format);
if ($type(values[0]) != 'number' || values[0] == years[0]) { // if it's a year / month combo for curr year, or simply a month select
if (!months_start.contains(values[1])) { months_start.push(values[1]); } // add to months array
}
if ($type(values[0]) != 'number' || values[0] == years.getLast()) { // if it's a year / month combo for curr year, or simply a month select
if (!months_end.contains(values[1])) { months_end.push(values[1]); } // add to months array
}
}, this);
months_start.sort(this.sort);
months_end.sort(this.sort);
if (months_start[0] > start.getMonth()) {
d = new Date(start.getFullYear(), months_start[0] + 1, 0); // last day of new month
if (start.getDate() > d.getDate()) { start.setDate(d.getDate()); }
start.setMonth(months_start[0]);
}
if (months_end.getLast() < end.getMonth()) {
d = new Date(start.getFullYear(), months_end.getLast() + 1, 0); // last day of new month
if (end.getDate() > d.getDate()) { end.setDate(d.getDate()); }
end.setMonth(months_end.getLast());
}
}
}
}, this);
return { 'start': start, 'end': end };
},
// caption: returns the caption element with header and navigation
// @param cal (obj)
// @returns caption (element)
caption: function(cal) {
// start by assuming navigation is allowed
var navigation = {
prev: { 'month': true, 'year': true },
next: { 'month': true, 'year': true }
};
// if we're in an out of bounds year
if (cal.year == cal.start.getFullYear()) {
navigation.prev.year = false;
if (cal.month == cal.start.getMonth() && this.options.navigation == 1) {
navigation.prev.month = false;
}
}
if (cal.year == cal.end.getFullYear()) {
navigation.next.year = false;
if (cal.month == cal.end.getMonth() && this.options.navigation == 1) {
navigation.next.month = false;
}
}
// special case of improved navigation but months array with only 1 month we can disable all month navigation
if ($type(cal.months) == 'array') {
if (cal.months.length == 1 && this.options.navigation == 2) {
navigation.prev.month = navigation.next.month = false;
}
}
var caption = new Element('caption');
//		var prev = new Element('a').addClass(this.classes.prev).appendText('\x3c'); // <
//		var next = new Element('a').addClass(this.classes.next).appendText('\x3e'); // >
var prev = new Element('a').addClass(this.classes.prev).setHTML('&nbsp;&nbsp;&nbsp;&nbsp;'); // <
var next = new Element('a').addClass(this.classes.next).setHTML('&nbsp;&nbsp;&nbsp;&nbsp;'); // >
if (this.options.navigation == 2) {
var month = new Element('span').addClass(this.classes.month).injectInside(caption);
if (navigation.prev.month) { prev.clone().addEvent('click', function(cal) { this.navigate(cal, 'm', -1); }.pass(cal, this)).injectInside(month); }
var monthSpan = new Element('span').setHTML(this.options.months[cal.month]);
monthSpan.setStyle('cursor','pointer');
monthSpan.addEvent('mouseenter', function(e){
monthSpan.setStyle('text-decoration', 'underline');
});
monthSpan.addEvent('mouseleave', function(e){
monthSpan.setStyle('text-decoration', 'none');
});
// create a list of month select menu
var monthsList = new Element('select', {'style': 'width:60px; font-size:11px;'});
for (var i = 0; i < this.options.months.length; i++) {
var option = new Element('option', {'style': 'font-size:11px;','value':i}).setHTML(this.options.months[i]);
if(cal.month == i){
option.setAttribute('selected', 'selected');
}
option.injectInside(monthsList);
}
monthsList.addEvent('change', function(e){
this.navigate(cal, 'm', monthsList.value-cal.month);
}.bind(this));
monthSpan.addEvent('click', function(e){
monthSpan.removeEvents('click');
monthSpan.empty();
monthsList.injectInside(monthSpan);
}.bind(this));
month.adopt(monthSpan);
if (navigation.next.month) { next.clone().addEvent('click', function(cal) { this.navigate(cal, 'm', 1); }.pass(cal, this)).injectInside(month); }
var year = new Element('span').addClass(this.classes.year).injectInside(caption);
if (navigation.prev.year) { prev.clone().addEvent('click', function(cal) { this.navigate(cal, 'y', -1); }.pass(cal, this)).injectInside(year); }
var yearSpan = new Element('span').appendText(cal.year);
yearSpan.setStyle('cursor','pointer');
yearSpan.addEvent('mouseenter', function(e){
yearSpan.setStyle('text-decoration', 'underline');
});
yearSpan.addEvent('mouseleave', function(e){
yearSpan.setStyle('text-decoration', 'none');
});
// create a list of years select menu
var yearsList = new Element('select', {'style': 'font-size:11px;'});
var currentYear = new Date().getFullYear();
for (var i = currentYear - 100; i < currentYear+1; i++) {
var option = new Element('option', {'style': 'font-size:11px;','value':i}).appendText(i);
if(cal.year == i){
option.setAttribute('selected', 'selected');
}
option.injectInside(yearsList);
}
yearsList.addEvent('change', function(e){
this.navigate(cal, 'y', yearsList.value-cal.year);
}.bind(this));
yearSpan.addEvent('click', function(e){
yearSpan.removeEvents('click');
yearSpan.empty();
yearsList.injectInside(yearSpan);
}.bind(this));
year.adopt(yearSpan);
if (navigation.next.year) { next.clone().addEvent('click', function(cal) { this.navigate(cal, 'y', 1); }.pass(cal, this)).injectInside(year); }
}
else { // 1 or 0
if (navigation.prev.month && this.options.navigation) { prev.clone().addEvent('click', function(cal) { this.navigate(cal, 'm', -1); }.pass(cal, this)).injectInside(caption); }
caption.adopt(new Element('span').addClass(this.classes.month).appendText(this.options.months[cal.month]));
caption.adopt(new Element('span').addClass(this.classes.year).appendText(cal.year));
if (navigation.next.month && this.options.navigation) { next.clone().addEvent('click', function(cal) { this.navigate(cal, 'm', 1); }.pass(cal, this)).injectInside(caption); }
}
return caption;
},
// changed: run when a select value is changed
// @param cal (obj)
changed: function(cal) {
cal.val = this.read(cal); // update calendar val from inputs
$extend(cal, this.values(cal)); // update bounds - based on curr month
this.rebuild(cal); // rebuild days select
if (!cal.val) { return; } // in case the same date was clicked the cal has no set date we should exit
if (cal.val.getDate() < cal.days[0]) { cal.val.setDate(cal.days[0]); }
if (cal.val.getDate() > cal.days.getLast()) { cal.val.setDate(cal.days.getLast()); }
cal.els.each(function(el) {	// then we can set the value to the field
el.value = this.format(cal.val, el.format);
}, this);
this.check(cal); // checks other cals
this.calendars.each(function(kal) { // update cal graphic if visible
if (kal.visible) { this.display(kal); }
}, this);
},
// check: checks other calendars to make sure no overlapping values
// @param cal (obj)
check: function(cal) {
/** this.calendars.each(function(kal, i) {
if (kal.val) { // if calendar has value set
var change = false;
if (i < cal.id) { // preceding calendar
var bound = new Date(Date.parse(cal.val));
bound.setDate(bound.getDate() - (this.options.pad * (cal.id - i)));
if (bound < kal.val) { change = true; }
}
if (i > cal.id) { // following calendar
var bound = new Date(Date.parse(cal.val));
bound.setDate(bound.getDate() + (this.options.pad * (i - cal.id)));
if (bound > kal.val) { change = true; }
}
if (change) {
if (kal.start > bound) { bound = kal.start; }
if (kal.end < bound) { bound = kal.end; }
kal.month = bound.getMonth();
kal.year = bound.getFullYear();
$extend(kal, this.values(kal));
// TODO - IN THE CASE OF SELECT MOVE TO NEAREST VALID VALUE
// IN THE CASE OF INPUT DISABLE
// if new date is not valid better unset cal value
// otherwise it would mean incrementally checking to find the nearest valid date which could be months / years away
kal.val = kal.days.contains(bound.getDate()) ? bound : null;
this.write(kal);
if (kal.visible) { this.display(kal); } // update cal graphic if visible
}
}
else {
kal.month = cal.month;
kal.year = cal.year;
}
}, this); **/
},
// clicked: run when a valid day is clicked in the calendar
// @param cal (obj)
clicked: function(td, day, cal) {
cal.val = (this.value(cal) == day) ? null : new Date(cal.year, cal.month, day); // set new value - if same then disable
this.write(cal);
// ok - in the special case that it's all selects and there's always a date no matter what (at least as far as the form is concerned)
// we can't let the calendar undo a date selection - it's just not possible!!
if (!cal.val) { cal.val = this.read(cal); }
if (cal.val) {
this.check(cal); // checks other cals
this.toggle(cal); // hide cal
}
else { // remove active class and replace with valid
td.addClass(this.classes.valid);
td.removeClass(this.classes.active);
}
},
// display: create calendar element
// @param cal (obj)
display: function(cal) {
// 1. header and navigation
this.calendar.empty(); // init div
this.calendar.className = this.classes.calendar + ' ' + this.options.months[cal.month].toLowerCase();
var div = new Element('div').injectInside(this.calendar); // a wrapper div to help correct browser css problems with the caption element
var table = new Element('table').injectInside(div).adopt(this.caption(cal));
// 2. day names
var thead = new Element('thead').injectInside(table);
var tr = new Element('tr').injectInside(thead);
for (var i = 0; i <= 6; i++) {
var th = this.options.days[(i + this.options.offset) % 7];
tr.adopt(new Element('th', { 'title': th }).appendText(th.substr(0, 1)));
}
// 3. day numbers
var tbody = new Element('tbody').injectInside(table);
var tr = new Element('tr').injectInside(tbody);
var d = new Date(cal.year, cal.month, 1);
var offset = ((d.getDay() - this.options.offset) + 7) % 7; // day of the week (offset)
var last = new Date(cal.year, cal.month + 1, 0).getDate(); // last day of this month
var prev = new Date(cal.year, cal.month, 0).getDate(); // last day of previous month
var active = this.value(cal); // active date (if set and within curr month)
var valid = cal.days; // valid days for curr month
var inactive = []; // active dates set by other calendars
var hilited = [];
/**	this.calendars.each(function(kal, i) {
if (kal != cal && kal.val) {
if (cal.year == kal.val.getFullYear() && cal.month == kal.val.getMonth()) { inactive.push(kal.val.getDate()); }
if (cal.val) {
for (var day = 1; day <= last; day++) {
d.setDate(day);
if ((i < cal.id && d > kal.val && d < cal.val) || (i > cal.id && d > cal.val && d < kal.val)) {
if (!hilited.contains(day)) { hilited.push(day); }
}
}
}
}
}, this);**/
var d = new Date();
var today = new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime(); // today obv
for (var i = 1; i < 43; i++) { // 1 to 42 (6 x 7 or 6 weeks)
if ((i - 1) % 7 == 0) { tr = new Element('tr').injectInside(tbody); } // each week is it's own table row
var td = new Element('td').injectInside(tr);
var day = i - offset;
var date = new Date(cal.year, cal.month, day);
var cls = '';
if (day === active) { cls = this.classes.active; } // active
else if (inactive.contains(day)) { cls = this.classes.inactive; } // inactive
else if (valid.contains(day)) { cls = this.classes.valid; } // valid
else if (day >= 1 && day <= last) { cls = this.classes.invalid; } // invalid
if (date.getTime() == today) { cls = cls + ' ' + this.classes.today; } // adds class for today
if (hilited.contains(day)) { cls = cls + ' ' + this.classes.hilite; } // adds class if hilited
td.addClass(cls);
if (valid.contains(day)) { // if it's a valid - clickable - day we add interaction
td.setProperty('title', this.format(date, 'D M jS Y'));
td.addEvents({
'click': function(td, day, cal) {
this.clicked(td, day, cal);
}.pass([td, day, cal], this),
'mouseover': function(td, cls) {
td.addClass(cls);
}.pass([td, this.classes.hover]),
'mouseout': function(td, cls) {
td.removeClass(cls);
}.pass([td, this.classes.hover])
});
}
// pad calendar with last days of prev month and first days of next month
if (day < 1) { day = prev + day; }
else if (day > last) { day = day - last; }
td.appendText(day);
}
},
// element: helper function
// @param el (string) element id
// @param f (string) format string
// @param cal (obj)
element: function(el, f, cal) {
if ($type(f) == 'object') { // in the case of multiple inputs per calendar
for (var i in f) {
if (!this.element(i, f[i], cal)) { return false; }
}
return true;
}
el = $(el);
if (!el) { return false; }
el.format = f;
if (el.getTag() == 'select') { // select elements allow the user to manually set the date via select option
el.addEvent('change', function(cal) { this.changed(cal); }.pass(cal, this));
}
else { // input (type text) elements restrict the user to only setting the date via the calendar
el.readOnly = true;
el.addEvent('focus', function(cal) { this.toggle(cal); }.pass(cal, this));
}
cal.els.push(el);
return true;
},
// format: formats a date object according to passed in instructions
// @param date (obj)
// @param f (string) any combination of punctuation / separators and d, j, D, l, S, m, n, F, M, y, Y
// @returns string
format: function(date, format) {
var str = '';
if (date) {
var j = date.getDate(); // 1 - 31
var w = date.getDay(); // 0 - 6
var l = this.options.days[w]; // Sunday - Saturday
var n = date.getMonth() + 1; // 1 - 12
var f = this.options.months[n - 1]; // January - December
var y = date.getFullYear() + ''; // 19xx - 20xx
for (var i = 0, len = format.length; i < len; i++) {
var cha = format.charAt(i); // format char
switch(cha) {
// year cases
case 'y': // xx - xx
y = y.substr(2);
case 'Y': // 19xx - 20xx
str += y;
break;
// month cases
case 'm': // 01 - 12
if (n < 10) { n = '0' + n; }
case 'n': // 1 - 12
str += n;
break;
case 'M': // Jan - Dec
f = f.substr(0, 3);
case 'F': // January - December
str += f;
break;
// day cases
case 'd': // 01 - 31
if (j < 10) { j = '0' + j; }
case 'j': // 1 - 31
str += j;
break;
case 'D': // Sun - Sat
l = l.substr(0, 3);
case 'l': // Sunday - Saturday
str += l;
break;
case 'N': // 1 - 7
w += 1;
case 'w': // 0 - 6
str += w;
break;
case 'S': // st, nd, rd or th (works well with j)
if (j % 10 == 1 && j != '11') { str += 'st'; }
else if (j % 10 == 2 && j != '12') { str += 'nd'; }
else if (j % 10 == 3 && j != '13') { str += 'rd'; }
else { str += 'th'; }
break;
default:
str += cha;
}
}
}
return str; //  return format with values replaced
},
// navigate: calendar navigation
// @param cal (obj)
// @param type (str) m or y for month or year
// @param n (int) + or - for next or prev
navigate: function(cal, type, n) {
switch (type) {
case 'm': // month
if ($type(cal.months) == 'array') {
var i = cal.months.indexOf(cal.month) + n; // index of current month
if (i < 0 || i == cal.months.length) { // out of range
if (this.options.navigation == 1) { // if type 1 nav we'll need to increment the year
this.navigate(cal, 'y', n);
}
i = (i < 0) ? cal.months.length - 1 : 0;
}
cal.month = cal.months[i];
}
else {
var i = cal.month + n;
if (i < 0 || i == 12) {
if (this.options.navigation == 1) {
this.navigate(cal, 'y', n);
}
i = (i < 0) ? 11 : 0;
}
cal.month = i;
}
break;
case 'y': // year
if ($type(cal.years) == 'array') {
var i = cal.years.indexOf(cal.year) + n;
cal.year = cal.years[i];
}
else {
cal.year += n;
}
break;
}
$extend(cal, this.values(cal));
if ($type(cal.months) == 'array') { // if the calendar has a months select
var i = cal.months.indexOf(cal.month); // and make sure the curr months exists for the new year
if (i < 0) { cal.month = cal.months[0]; } // otherwise we'll reset the month
}
this.display(cal);
},
// read: compiles cal value based on array of inputs passed in
// @param cal (obj)
// @returns date (obj) or (null)
read: function(cal) {
var arr = [null, null, null];
cal.els.each(function(el) {
// returns an array which may contain empty values
var values = this.unformat(el.value, el.format);
values.each(function(val, i) {
if ($type(val) == 'number') { arr[i] = val; }
});
}, this);
// we can update the cals month and year values
if ($type(arr[0]) == 'number') { cal.year = arr[0]; }
if ($type(arr[1]) == 'number') { cal.month = arr[1]; }
var val = null;
if (arr.every(function(i) { return $type(i) == 'number'; })) { // if valid date
var last = new Date(arr[0], arr[1] + 1, 0).getDate(); // last day of month
if (arr[2] > last) { arr[2] = last; } // make sure we stay within the month (ex in case default day of select is 31 and month is feb)
val = new Date(arr[0], arr[1], arr[2]);
}
return (cal.val == val) ? null : val; // if new date matches old return null (same date clicked twice = disable)
},
// rebuild: rebuilds days + months selects
// @param cal (obj)
rebuild: function(cal) {
cal.els.each(function(el) {
/*
if (el.getTag() == 'select' && el.format.test('^(F|m|M|n)$')) { // special case for months-only select
if (!cal.options) { cal.options = el.clone(); } // clone a copy of months select
var val = (cal.val) ? cal.val.getMonth() : el.value.toInt();
el.empty(); // initialize select
cal.months.each(function(month) {
// create an option element
var option = new Element('option', {
'selected': (val == month),
'value': this.format(new Date(1, month, 1), el.format);
}).appendText(day).injectInside(el);
}, this);
}
*/
if (el.getTag() == 'select' && el.format.test('^(d|j)$')) { // special case for days-only select
var d = this.value(cal);
if (!d) { d = el.value.toInt(); } // if the calendar doesn't have a set value, try to use value from select
el.empty(); // initialize select
var emptyOption = new Element('option', {
'selected':'true',
'value': '0'
}).injectInside(el);
cal.days.each(function(day) {
// create an option element
var option = new Element('option', {
'selected': (d == day),
'value': ((el.format == 'd' && day < 10) ? '0' + day : day)
}).appendText(day).injectInside(el);
}, this);
}
}, this);
},
// sort: helper function for numerical sorting
sort: function(a, b) {
return a - b;
},
// toggle: show / hide calendar
// @param cal (obj)
toggle: function(cal) {
document.removeEvent('mousedown', this.fn); // always remove the current mousedown script first
if (cal.visible) { // simply hide curr cal
cal.visible = false;
cal.button.removeClass(this.classes.active); // active
this.fx.start(1, 0);
}
else { // otherwise show (may have to hide others)
// hide cal on out-of-bounds click
this.fn = function(e, cal) {
var e = new Event(e);
var el = e.target;
var stop = false;
while (el != document.body && el.nodeType == 1) {
if (el == this.calendar) { stop = true; }
this.calendars.each(function(kal) {
if (kal.button == el || kal.els.contains(el)) { stop = true; }
});
if (stop) {
e.stop();
return false;
}
else { el = el.parentNode; }
}
this.toggle(cal);
}.create({ 'arguments': cal, 'bind': this, 'event': true });
document.addEvent('mousedown', this.fn);
this.calendars.each(function(kal) {
if (kal == cal) {
kal.visible = true;
kal.button.addClass(this.classes.active); // css c-icon-active
}
else {
kal.visible = false;
kal.button.removeClass(this.classes.active); // css c-icon-active
}
}, this);
var size = window.getSize().scrollSize;
var coord = cal.button.getCoordinates();
var x = coord.right + this.options.tweak.x;
var y = coord.top + this.options.tweak.y;
// make sure the calendar doesn't open off screen
if (!this.calendar.coord) { this.calendar.coord = this.calendar.getCoordinates(); }
if (x + this.calendar.coord.width > size.x) { x -= (x + this.calendar.coord.width - size.x); }
if (y + this.calendar.coord.height > size.y) { y -= (y + this.calendar.coord.height - size.y); }
this.calendar.setStyles({ left: x + 'px', top: y + 'px' });
if (window.ie6) {
this.iframe.setStyles({ height: this.calendar.coord.height + 'px', left: x + 'px', top: y + 'px', width: this.calendar.coord.width + 'px' });
}
this.display(cal);
this.fx.start(0, 1);
}
},
// unformat: takes a value from an input and parses the d, m and y elements
// @param val (string)
// @param f (string) any combination of punctuation / separators and d, j, D, l, S, m, n, F, M, y, Y
// @returns array
unformat: function(val, f) {
f = f.escapeRegExp();
var re = {
d: '([0-9]{2})',
j: '([0-9]{1,2})',
D: '(' + this.options.days.map(function(day) { return day.substr(0, 3); }).join('|') + ')',
l: '(' + this.options.days.join('|') + ')',
S: '(st|nd|rd|th)',
F: '(' + this.options.months.join('|') + ')',
m: '([0-9]{2})',
M: '(' + this.options.months.map(function(month) { return month.substr(0, 3); }).join('|') + ')',
n: '([0-9]{1,2})',
Y: '([0-9]{4})',
y: '([0-9]{2})'
};
var arr = []; // array of indexes
var g = '';
// convert our format string to regexp
for (var i = 0; i < f.length; i++) {
var c = f.charAt(i);
if (re[c]) {
arr.push(c);
g += re[c];
}
else {
g += c;
}
}
// match against date
var matches = val.match('^' + g + '$');
var dates = new Array(3);
if (matches) {
matches = matches.slice(1); // remove first match which is the date
arr.each(function(c, i) {
i = matches[i];
switch(c) {
// year cases
case 'y':
i = '19' + i; // 2 digit year assumes 19th century (same as JS)
case 'Y':
dates[0] = i.toInt();
break;
// month cases
case 'F':
i = i.substr(0, 3);
case 'M':
i = this.options.months.map(function(month) { return month.substr(0, 3); }).indexOf(i) + 1;
case 'm':
case 'n':
dates[1] = i.toInt() - 1;
break;
// day cases
case 'd':
case 'j':
dates[2] = i.toInt();
break;
}
}, this);
}
return dates;
},
// value: returns day value of calendar if set
// @param cal (obj)
// @returns day (int) or null
value: function(cal) {
var day = null;
if (cal.val) {
if (cal.year == cal.val.getFullYear() && cal.month == cal.val.getMonth()) { day = cal.val.getDate(); }
}
return day;
},
// values: returns the years, months (for curr year) and days (for curr month and year) for the calendar
// @param cal (obj)
// @returns obj
values: function(cal) {
var years, months, days;
cal.els.each(function(el) {
if (el.getTag() == 'select') {
if (el.format.test('(y|Y)')) { // search for a year select
years = [];
el.getChildren().each(function(option) { // get options
var values = this.unformat(option.value, el.format);
if (!years.contains(values[0])) { years.push(values[0]); } // add to years array
}, this);
years.sort(this.sort);
}
if (el.format.test('(F|m|M|n)')) { // search for a month select
months = []; // 0 - 11 should be
el.getChildren().each(function(option) { // get options
var values = this.unformat(option.value, el.format);
if ($type(values[0]) != 'number' || values[0] == cal.year) { // if it's a year / month combo for curr year, or simply a month select
if (!months.contains(values[1])) { months.push(values[1]); } // add to months array
}
}, this);
months.sort(this.sort);
}
if (el.format.test('(d|j)') && !el.format.test('^(d|j)$')) { // search for a day select, but NOT a days only select
days = []; // 1 - 31
el.getChildren().each(function(option) { // get options
var values = this.unformat(option.value, el.format);
// in the special case of days we dont want the value if its a days only select
// otherwise that will screw up the options rebuilding
// we will take the values if they are exact dates though
if (values[0] == cal.year && values[1] == cal.month) {
if (!days.contains(values[2])) { days.push(values[2]); } // add to days array
}
}, this);
}
}
}, this);
// we start with what would be the first and last days were there no restrictions
var first = 1;
var last = new Date(cal.year, cal.month + 1, 0).getDate(); // last day of the month
// if we're in an out of bounds year
if (cal.year == cal.start.getFullYear()) {
// in the special case of improved navigation but no months array, we'll need to construct one
if (months == null && this.options.navigation == 2) {
months = [];
for (var i = 0; i < 12; i ++) {
if (i >= cal.start.getMonth()) { months.push(i); }
}
}
// if we're in an out of bounds month
if (cal.month == cal.start.getMonth()) {
first = cal.start.getDate(); // first day equals day of bound
}
}
if (cal.year == cal.end.getFullYear()) {
// in the special case of improved navigation but no months array, we'll need to construct one
if (months == null && this.options.navigation == 2) {
months = [];
for (var i = 0; i < 12; i ++) {
if (i <= cal.end.getMonth()) { months.push(i); }
}
}
if (cal.month == cal.end.getMonth()) {
last = cal.end.getDate(); // last day equals day of bound
}
}
// let's get our invalid days
var blocked = this.blocked(cal);
// finally we can prepare all the valid days in a neat little array
if ($type(days) == 'array') { // somewhere there was a days select
days = days.filter(function(day) {
if (day >= first && day <= last && !blocked.contains(day)) { return day; }
});
}
else { // no days select we'll need to construct a valid days array
days = [];
for (var i = first; i <= last; i++) {
if (!blocked.contains(i)) { days.push(i); }
}
}
days.sort(this.sort); // sorting our days will give us first and last of month
return { 'days': days, 'months': months, 'years': years };
},
// write: sets calendars value to form elements
// @param cal (obj)
write: function(cal) {
this.rebuild(cal);	 // in the case of options, we'll need to make sure we have the correct number of days available
cal.els.each(function(el) {	// then we can set the value to the field
el.value = this.format(cal.val, el.format);
}, this);
}
});
Calendar.implement(new Events, new Options);/**
*  Create a drop-down menu for navigation
*
*/
var DropDownMenu = Options.extend({
options: {
onComplete: Class.empty,
onStart: Class.empty,
delay:500
},
initialize: function(el, options) {
this.el = $(el);
this.setOptions(options);
var elementToHide;
this.el.getElements('li').each(function(li, index) {
if(li.getElements('a')[0])li.getElements('a')[0].removeAttribute('title');
if(li.getElements('ul').length){
li.addClass('HasChild');
}
li.menu = this;
li.addEvent('mouseenter', function() {
this.addClass('iehover');
$clear(this._myTimer);
if(elementToHide && !this.getElements('ul').contains(elementToHide)){
elementToHide.removeClass('ulhover');
}
elementToHide = null;
if(this.getElements('ul')[0]) {
this.getElements('ul')[0].addClass('ulhover');
}
});
li.addEvent('mouseleave', function() {
this.removeClass('iehover');
if(this.getElements('ul')[0]) {
elementToHide = this.getElements('ul')[0];
this._myTimer = this.getElements('ul')[0].removeClass.delay(this.menu.options.delay ,this.getElements('ul')[0], 'ulhover');
}
});
}.bind(this));
},
hide : function(){
this.el.getElements('ul').each(function(item,index){
item.removeClass('ulhover');
});
}
});
var SynergeeNews = new Class({
initialize: function(el, elementClass, timer, className) {
this.el = el;
this.elementClass = elementClass;
this._timer = timer;
this._className = ' ';
if(className){
this._className += className;
}
this.items = this.el.getElements(this.elementClass);
// create the nav div
var nav = new Element('ul', {'class': 'Synergee-Web-Page-TextTicker-Nav-Container' + this._className});
this.navButtons = new Array();
for (var i = 0; i < this.items.length; i++) {
this.navButtons[i] = new Element('li', {'class': 'Synergee-Web-Page-TextTicker-NavButton' + this._className});
this.navButtons[i].position = i;
nav.appendChild(this.navButtons[i]);
this.navButtons[i].addEvent('click', function(event) {
event = new Event(event);
this.goto(event.target.position);
}.bind(this));
}
this.el.getParent().appendChild(nav);
if (this.items.length) {
var w = 0;
this.items.each(function(item, index) {
w += item.getSize().size.x;
item.addEvent('mouseenter', function() {
$clear(this.delayedFunction);
}.bind(this));
item.addEvent('mouseleave', function() {
$clear(this.delayedFunction);
this.delayedFunction = this.next.bind(this).delay(this._timer);
}.bind(this));
}.bind(this));
this.el.setStyles({
position: 'absolute',
top: 0,
left: 0,
width: w
});
this.fx = new Fx.Styles(this.el, {duration:800, transition: Fx.Transitions.Quint.easeInOut,
onStart: function(){
var i = (this.current == 0) ? this.items.length : this.current;
this.navButtons[this.current].addClass('Active');
for (var j = 0; j < this.navButtons.length; j ++) {
if (j != this.current)this.navButtons[j].removeClass('Active');
}
this.el.fireEvent('onstart', this.items[this.current]);
}.bind(this),
onCancel :function() {
this.el.fireEvent('oncancel', this.items[this.current]);
},
onComplete:function() {
this.el.fireEvent('itemchanged', this.items[this.current]);
}.bind(this)});
this.current = this.items.length;
this.next();
}
},
next : function() {
this.current++;
if (this.current >= this.items.length) this.current = 0;
this.fx.stop();
this.fx.start({
top: this.items[this.current].offsetTop,
left: -this.items[this.current].offsetLeft
});
this.delayedFunction = this.next.bind(this).delay(this._timer );
},
goto : function(to) {
$clear(this.delayedFunction);
this.current = to;
this.fx.start({
top: this.items[to].offsetTop,
left: -this.items[to].offsetLeft
});
this.delayedFunction = this.next.bind(this).delay(this._timer);
}
});var TextSplitter = new Class({
initialize: function(component, splitterElements, titleElement) {
if (component.getElement) {
this.el = component.getElement('div');
var elements = new Array();
if(!(splitterElements instanceof Array)){
splitterElements = new Array(splitterElements);
}
for(var i = 0; i < splitterElements.length; i++){
elements = this.el.getElement(splitterElements[i]);
if(elements.length)break;
}
// retrieve the blocks
if (elements) {
var children = this.el.childNodes;
this.blocks = new Array();
this.titles = new Array();
this.blocks.push(new Element('div', {"class": "Synergee-Web-Page-TextSplitter-Content"}));
for (var i = 0; i < children.length; i++) {
if ($type(children[i]) == 'element' && splitterElements.contains(children[i].tagName.toLowerCase())) {
this.blocks.push(new Element('div', {"class": "Synergee-Web-Page-TextSplitter-Content"}));
} else if (this.blocks.length) {
if ($type(children[i]) == 'element') {
this.blocks[this.blocks.length - 1].appendChild(children[i]);
} else {
this.blocks[this.blocks.length - 1].appendChild(children[i]);
}
i--;
}
}
this.el.empty();
if (titleElement) {
for (var i = 0; i < this.blocks.length; i++) {
if (this.blocks[i].getElement(titleElement)) {
this.titles[i] = this.blocks[i].getElement(titleElement);
this.titles[i].addClass('Synergee-Web-Page-TextSplitter-Title');
} else {
this.titles[i] = new Element(titleElement, {'class': 'Synergee-Web-Page-TextSplitter-Title'});
this.titles[i].setHTML('"' + titleElement + '" title missing');
}
}
if (this.titles.length) {
this.titles[this.titles.length - 1].addClass('Synergee-Web-Page-TextSplitter-Title-Last');
}
this.titlesContainer = new Element('div', {"class": "Synergee-Web-Page-TextSplitter-Title-Container"});
this.el.appendChild(this.titlesContainer);
}
this.contentsContainer = new Element('div', {"class": "Synergee-Web-Page-TextSplitter-Content-Container"});
this.el.appendChild(this.contentsContainer);
for (var i = 0; i < this.titles.length; i ++) {
this.titlesContainer.appendChild(this.titles[i]);
}
for (var i = 0; i < this.blocks.length; i ++) {
this.contentsContainer.appendChild(this.blocks[i]);
}
}
}
},
getContentContainer : function() {
return this.contentsContainer;
},
getTitleContainer :  function() {
if(this.titlesContainer)return this.titlesContainer;
return null;
},
getTitles : function() {
return this.titles;
},
getContents : function(){
return this.blocks;
}
});var SynergeeTips = Tips.extend({
options: {
onShow: function(tip){
tip.setStyle('visibility', 'visible');
},
onHide: function(tip){
tip.setStyle('visibility', 'hidden');
},
maxTitleChars: 30,
showDelay: 100,
hideDelay: 100,
className: 'tool',
offsets: {'x': 16, 'y': 16},
fixed: false,
maxHeight : 0,
closeButton : false,
eventType : 'click'
},
build: function(el){
el.$tmp.myTitle = (el.href && el.getTag() == 'a') ? el.href.replace('http://', '') : (el.rel || false);
if (el.title){
var dual = el.title.split('::');
if (dual.length > 1) {
el.$tmp.myTitle = dual[0].trim();
el.$tmp.myText = dual[1].trim();
} else {
el.$tmp.myText = el.title;
}
el.removeAttribute('title');
} else {
el.$tmp.myText = false;
}
if (el.$tmp.myTitle && el.$tmp.myTitle.length > this.options.maxTitleChars) el.$tmp.myTitle = el.$tmp.myTitle.substr(0, this.options.maxTitleChars - 1) + "&hellip;";
el.addEvent(this.options.eventType, function(event){
this.start(el);
if (this.options.maxHeight) {
if(this.text && this.options.maxHeight < this.text.getParent().getCoordinates().height){
this.text.getParent().setStyle('max-height', this.options.maxHeight);
this.text.getParent().setStyle('overflowY', 'scroll');
}
}
if (!this.options.fixed) this.locate(event);
else this.position(el);
}.bind(this));
if (!this.options.fixed) el.addEvent('mousemove', this.locate.bindWithEvent(this));
var end = this.end.bind(this);
el.addEvent('mouseleave', end);
el.addEvent('trash', end);
this.toolTip.addEvent('mouseleave', end);
this.toolTip.addEvent('mouseenter', function(event){
$clear(this.timer);
}.bind(this));
},
start: function(el){
this.wrapper.empty();
if (el.$tmp.myTitle){
this.title = new Element('span').inject(
new Element('div', {'class': this.options.className + '-title'}).inject(this.wrapper)
).setHTML(el.$tmp.myTitle);
if(this.options.closeButton){
this.closeButton = new Element('div',{'class':this.options.className + '-Close'});
var end = this.hide.bind(this);
this.closeButton.injectInside(this.title.getParent());
this.closeButton.addEvent('click',end);
}
}
if (el.$tmp.myText){
this.text = new Element('span').inject(
new Element('div', {'class': this.options.className + '-text'}).inject(this.wrapper)
).setHTML(el.$tmp.myText);
}
$clear(this.timer);
this.timer = this.show.delay(this.options.showDelay, this);
}
});
/**
* The synergee form javascript code.
* This file contains all the necessary code used by the form widget.
*
* Copyright (c) 2007 Pyrameed all right reserved (http://www.pyrameed.com)
*/
/**
* The field validator.
* This class is used to validate a form field
*/
var SynergeeFieldValidator = new Class({
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return true;
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
throw Error('The method "getValidatorName" has to be defined for the field validator classes.');
}
});
/**
* The not empty field validator
*/
var SynergeeFieldValidatorNotEmpty = SynergeeFieldValidator.extend({
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return (field.tagName.toLowerCase() == 'div' || field.getValue() != '');
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorNotEmpty';
}
});
/**
* The email field validator
*/
var SynergeeFieldValidatorEmail = SynergeeFieldValidator.extend({
_emailRegex : new RegExp("^([_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3}))?$"),
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return this._emailRegex.test(field.getValue());
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorEmail';
}
});
/**
* The list field validator
*/
var SynergeeFieldValidatorList = SynergeeFieldValidator.extend({
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
var inputElements = field.getElementsByTagName('input');
for (var i = 0; i < inputElements.length; i++) {
if (inputElements[i].checked) {
return true;
}
}
return false;
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorList';
}
});
/**
* The alpha field validator
*/
var SynergeeFieldValidatorAlpha = SynergeeFieldValidator.extend({
_alphaRegex : new RegExp("^([a-zA-Z])*?$"),
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return this._alphaRegex.test(field.getValue());
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorAlpha';
}
});
/**
* The numeric field validator
*/
var SynergeeFieldValidatorNum = SynergeeFieldValidator.extend({
_numRegex : new RegExp("^([0-9])*?$"),
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return this._numRegex.test(field.getValue());
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorNum';
}
});
/**
* The alphanumeric field validator
*/
var SynergeeFieldValidatorAlnum = SynergeeFieldValidator.extend({
_alnumRegex : new RegExp("^([a-zA-Z0-9])*?$"),
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return this._alnumRegex.test(field.getValue());
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorAlnum';
}
});
/**
* The date field validator
*/
var SynergeeFieldValidatorDate = SynergeeFieldValidator.extend({
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
return (field.tagName.toLowerCase() == 'input' || field.getValue() != '');
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorDate';
}
});
/**
* The Birthdate field validator
*/
var SynergeeFieldValidatorBirthdate = SynergeeFieldValidator.extend({
initialize : function(minDate, maxDate, format) {
if(minDate){
this._minDate = (new Date()).fromIso(minDate);
}   else{
this._minDate = null;
}
if(maxDate){
this._maxDate = (new Date()).fromIso(maxDate);
}   else{
this._maxDate = null;
}
if(format) this._format = format;
},
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
// always return true, the backend check the right dates
////
//        var fieldValue = field.getValue();
//        if(fieldValue != '' && (new Date()).fromIso(fieldValue)){
//            fieldValue = (new Date()).fromIso(fieldValue);
//            if(this._maxDate && this._maxDate.getTime() < fieldValue){
//                return false;
//
//            }
//            if(this._minDate && this._minDate.getTime() > fieldValue){
//                return false;
//            }
//        }
return true;
},
/**
* Return the vaidator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorBirthdate';
}
});
/**
* The Birthdate field validator
*/
var SynergeeFieldValidatorLevel = SynergeeFieldValidator.extend({
initialize : function(minimumLevel, maximumLevel) {
if(minimumLevel){
this._minimumLevel = minimumLevel;
}   else{
this._minimumLevel = 1;
}
if(maximumLevel){
this._maximumLevel = maximumLevel;
}   else{
this._maximumLevel = 7;
}
},
/**
* The validation method
*
* @param Element field The field element to validate
* @return boolean True if the field is valid
*/
isValid : function(field) {
var selIndex = field.selectedIndex;
var comboValue = field.options[selIndex].value;
if(comboValue){
if(comboValue >= this._minimumLevel && comboValue <= this._maximumLevel){
return true;
}
return false;
}
return true;
},
/**
* Return the validator name
*
* @return string The validator name
*/
getValidatorName : function() {
return 'SynergeeFieldValidatorLevel';
}
});
/**
* The form validator.
* This class is used to validate the fields of a specific form
*/
var SynergeeFormValidator = new Class({
_formElement : null,
_onComplete : null,
_fields : [],
_submitButton : null,
/**
* The constructor
*
* @param Element formElement The form element
* @param function onComplete The function called once the form has been submitted (this function is called by the ajax component)
*/
initialize: function(formElement, onComplete) {
this._fields = [];
this._formElement = formElement;
this._scroller = new Fx.Scroll(window, {offset: {'x': 0, 'y': -50}});
if (typeof(onComplete) == 'function') {
this._onComplete = onComplete;
} else {
this._onComplete = eval(onComplete);
}
this._formElement.addEvent('submit', function(e) {
new Event(e).stop();
});
// The error message functions are added to the form
this._formElement._errorMessage = new Fx.Slide(this._formElement.getElementsByTagName('div')[0]);
this._formElement.getElementsByTagName('div')[0].setStyle('clear', 'both');
this._formElement._errorMessage.hide();
this._formElement.displayErrorMessage = function() {
if (this._errorMessage) {
this._errorMessage.stop();
this._errorMessage.slideIn();
}
};
this._formElement.hideErrorMessage = function() {
if (this._errorMessage) {
this._errorMessage.stop();
this._errorMessage.slideOut();
}
};
},
/**
* This method is called when the response of the form has been received.
* The goal of this method is to analyse the response and if some fields were
* invalid the error message is displayed again.
* If no invalidate fields are returned, the user defined function (set on the onComplete
* attribute of the form tag) is called with the response as parameter.
*
* @param string response The response returned by the server
*/
onComplete : function(response) {
// The submit button is ungrayed
if (this._submitButton) {
this._submitButton.removeProperty('disabled');
}
// We check if the invalidateFields is empty or not
try {
var response = Json.evaluate(response);
if (response.invalidFields && response.invalidFields.length) {
try {
if ($(response.invalidFields[0])) {
$(response.invalidFields[0]).focus();
} else {
$('id_' + response.invalidFields[0]).focus();
}
}catch(ex){
// if the element is not focusable (it's hidden or something)
}
response.invalidFields.each(function(fieldName) {
if ($(fieldName)) {
$(fieldName).displayErrorMessage();
} else {
$('id_' + fieldName).displayErrorMessage();
}
});
try {
if(response.invalidFields[0]){
if ($(response.invalidFields[0])) {
if($(response.invalidFields[0]).getStyle('display') == 'none'){
var element = $(response.invalidFields[0]).getParent();
}else {
var element = $(response.invalidFields[0]);
}
this._scroller.toElement(element);
} else {
if($('id_' + response.invalidFields[0]).getStyle('display') == 'none'){
var element = $('id_' + response.invalidFields[0]).getParent();
}else {
var element = $('id_' + response.invalidFields[0]);
}
this._scroller.toElement(element);
}
}
}catch (ex){}
this._formElement.fireEvent('invalidfield');
} else if (response.isValid) {
// The user defined on complete method is called with the response as parameter
this._onComplete(response.response);
} else {
// The request wasn't valid, then a global message has to be send
this._formElement.displayErrorMessage();
}
} catch(ex) {
// The response is not a valid JSON encoded one
this._formElement.displayErrorMessage();
this._formElement.fireEvent('invalidfield');
}
},
/**
* Validate the fields of the form
*
* @param boolean ajaxCall True if an ajax call has to be done
*/
validate : function(ajaxCall) {
// The submit button is grayed
if (this._submitButton) {
this._submitButton.addClass('WaitingButton');
this._submitButton.setProperty('disabled', 'disabled');
}
// The error message of the form is hidden
this._formElement.hideErrorMessage();
var valid = true;
var invalidFields = new Array();
for (var i = 0; i < this._fields.length; i++) {
for (var j = 0; j < this._fields[i].getValidators().length; j++) {
if (!this._fields[i].getValidators()[j].isValid(this._fields[i])) {
invalidFields.push(this._fields[i]);
}
}
}
// The valid fields error message are hidden
for (var i = 0; i < this._fields.length; i++) {
if (!invalidFields.contains(this._fields[i])) {
this._fields[i].hideErrorMessage();
}
}
// The invalidate fields error message are displayed
if (invalidFields.length) {
invalidFields[0].focus();
// The page is scrolled to the first error message
this._scroller.toElement(invalidFields[0]);
for (var i = 0; i < invalidFields.length; i++) {
invalidFields[i].displayErrorMessage();
}
// The submit button is ungrayed
if (this._submitButton) {
this._submitButton.removeClass('WaitingButton');
this._submitButton.removeProperty('disabled');
}
return false;
} else {
if (ajaxCall) {
// The right page location is set to the action attribute of the form
this._formElement.setProperty('action', window.getCurrentPageUrl());
// The componentName and componentId fields are populated
if (!this._formElement.getChildren().contains($('id_componentName'))) {
if ($('id_componentName')) {
$('id_componentName').remove();
}
(new Element('input').setProperties({name:'componentName',id:'id_componentName',type:'hidden'})).injectBefore(this._formElement.getChildren()[0]);
}
$('id_componentName').setProperty('value', this._formElement.getComponentName());
if (!this._formElement.getChildren().contains($('id_componentId'))) {
if ($('id_componentId')) {
$('id_componentId').remove();
}
(new Element('input').setProperties({name:'componentId',id:'id_componentId',type:'hidden'})).injectBefore(this._formElement.getChildren()[1]);
}
$('id_componentId').setProperty('value', this._formElement.getComponentId());
// The validationInformation field is populated with all the validation information
if (!this._formElement.getChildren().contains($('id_validationInformation'))) {
if ($('id_validationInformation')) {
$('id_validationInformation').remove();
}
(new Element('input').setProperties({name:'validationInformation',id:'id_validationInformation',type:'hidden'})).injectBefore(this._formElement.getChildren()[2]);
}
$('id_validationInformation').setProperty('value', this.getValidationInformation());
// All the fields are ok, then the form is sent
this._formElement.fireEvent('ajaxcall');
this._formElement.send({onComplete:this.onComplete.bind(this)});
return false;
} else {
return true;
}
}
},
createTips : function(field) {
},
/**
* Add a field to the validator
*
* @param Element field The field to validate
* @optionalParam string[] validators The list of validators to apply to the field
*/
addField : function(field, validators) {
var validatorObjects = [];
if (validators && validators.length) {
for (var i = 0; i < validators.length; i++) {
validatorObjects.push(validators[i]);
}
if (field.getStyle('position') == "absolute") {
if (field.parentNode.getElementsByTagName('div').length) {
field._errorImage = field.getParent().getElementsByTagName('div')[0];
field._errorMessage = new Tips(field._errorImage);
}
} else {
if (field.parentNode.getElementsByTagName('div').length) {
if (field.parentNode.getElementsByTagName('div').length) {
// The error fx object is created
field._errorMessage = new Fx.Slide(field.parentNode.getElementsByTagName('div')[0]);
field._errorMessage.hide();
}
}
}
}
field._validators = validatorObjects;
field.getValidators = function() {
return this._validators;
};
field.displayErrorMessage = function() {
if (this._errorMessage) {
if (this.getStyle('position') == "absolute") {
this._errorImage.setStyle('display', 'block');
} else {
this._errorMessage.stop();
this.setStyle('margin-top', '2px');
this._errorMessage.slideIn();
}
}
};
field.hideErrorMessage = function() {
if (this._errorMessage) {
if (this.getStyle('position') == "absolute") {
this._errorImage.setStyle('display', 'none');
} else {
this._errorMessage.stop();
this.setStyle('margin-top', '0px');
this._errorMessage.slideOut();
}
}
};
this._fields.push(field);
// A check to determine if this is the submit button
if (field && field.getProperty('type') && field.getProperty('type').toLowerCase() == 'submit') {
this._submitButton = field;
}
},
/**
* Return the validation information encoded in JSON.
* This is a hash table that have the field name as key and a coma separated validator name as values.
*
* @return string
*/
getValidationInformation : function() {
var validationInformation = {};
this._fields.each(function(field) {
var validators = new Array();
field.getValidators().each(function(validator) {
validators.push(validator.getValidatorName());
});
validationInformation[field.getProperty('name')] = validators.join(',');
});
return Json.toString(validationInformation);
}
});
/**
* The synergee general javascript code.
* This file contains all the necessary code used by the form widget.
*
* Copyright (c) 2007 Pyrameed all right reserved (http://www.pyrameed.com)
*/
/**
* Add two usefull method to the Element objects in order to determine
* its synergee web page parent component name and id.
* Those informations are usefull when dealing with AJAX requests.
*/
Element.extend({
/**
* Return the first synergee web page component name
*
* @return string The first synergee web page component name
*/
getComponentName : function() {
var currentElement = this;
while(!(currentElement.className && currentElement.className.test('Synergee-Web-Page-Component-(.*)-Container', 'i'))) {
currentElement = currentElement.getParent();
}
var regex = new RegExp('Synergee-Web-Page-Component-(.*)-Container', 'i');
var values = regex.exec(currentElement.className);
if (values && values.length == 2) {
return values[1];
} else {
return null;
}
},
/**
* Return the first synergee web page component id
*
* @return string The first synergee web page component id
*/
getComponentId : function() {
var currentElement = this;
while(!(currentElement.className && currentElement.className.test('Synergee-Web-Page-Component-(.*)-Container', 'i'))) {
currentElement = currentElement.getParent();
}
var regex = new RegExp('Synergee-Web-Page-Component-(.*)-Container', 'i');
var values = regex.exec(currentElement.className);
if (values && values.length == 2) {
return currentElement.getParent().id;
} else {
return null;
}
}
});
/**
* The getUrl method is added to the window object in order to be able to get the current page url easily
*/
window.extend({
/**
* Bookmark the current web page
*
* @param string title The page title
* @param string url The web page url
*/
bookmark : function(title, url) {
if (document.all) {
window.external.AddFavorite(url, title);
} else if (window.sidebar) {
window.sidebar.addPanel(title, url, "");
}
},
/**
* Return the current web page url
*
* @return string The current web page url
*/
getCurrentPageUrl : function() {
if (window.location.href.indexOf('?') != -1) {
return window.location.href.substr(0, window.location.href.indexOf('?'));
}
return window.location.href;
},
/**
* Return the current JSON url.
* This url is used by all the JSON invokations
*
* @param Element element The component element
* @return string The current JSON url
*/
getCurrentJsonUrl : function(element) {
var htmlElement = $E('html');
var windowUrl = window.getCurrentPageUrl();
//        if(windowUrl.indexOf('#')){
//            windowUrl = windowUrl.slice(0, windowUrl.indexOf('#'));
//        }
if (htmlElement.getAttribute('designmode') == 'on') {
var webPageId = /webPageId=([0-9]*)/.exec(window.location.href);
return windowUrl + '?webPageId=' + webPageId[1] + '&componentName=' + element.getComponentName() + '&componentId=' + element.getComponentId();
} else {
return windowUrl + '?componentName=' + element.getComponentName() + '&componentId=' + element.getComponentId();
}
},
/**
* Return the currrent page location (the url without the page name)
*
* @return string The current page location
*/
getCurrentPageLocation : function() {
return window.getCurrentPageUrl().substr(0, window.getCurrentPageUrl().lastIndexOf('/')) + '/';
}
});
/**
* Docucment is extended to add the isInDesignMode method.
*/
document.extend({
/**
* This method return true when the page is displayed in the designer
* @return boolean True if the page is displayed in the designer
*/
isInDesignMode : function() {
var htmlElement = $E('html');
return (htmlElement.getAttribute('designmode') == 'on');
}
});
/**
* Decode the html entities
*
* @param String sa
* @return String
*/
function decodeHtmlEntities(sa) {
var ta=document.createElement("textarea");
ta.innerHTML=sa.replace(/</g,"&lt;").replace(/>/g,"&gt;");
return ta.value;
};
/**
* Pad a number regarding the number passed to the pad. By default 2
* @param number valueToPad The value to pad
* @param number pad The pad value
* @return string the padded number
*/
Number.padTo = function(valueToPad, pad) {
pad = pad ? pad : 2;
pad = Math.pow(10, pad-1);
return (valueToPad < pad) ? ("0" + valueToPad) : valueToPad;
};
/**
* Populate the date from an iso formatted string that represent a date
*
* @param string The iso formatted date
*/
Date.prototype.fromIso = function(isoFormattedDate) {
var dateTimeRegex = new RegExp('^([0-9]{4})-([0-9]{2})-([0-9]{2})[T ]([0-9]{2}):([0-9]{2}):([0-9]{2})(([+-])([0-9]{2})(:([0-9]{2}))?)?$');
var dateRegex = new RegExp('^([0-9]{4})-([0-9]{2})-([0-9]{2})$');
var timeRegex = new RegExp('^([0-9]{2}):([0-9]{2}):([0-9]{2})$');
if (dateTimeRegex.test(isoFormattedDate)) {
var values = dateTimeRegex.exec(isoFormattedDate);
var tmpDate = new Date(values[1], values[2] - 1, values[3], values[4], values[5], values[6]);
this.setTime(tmpDate.getTime());
//this.setTime(Date.parse(values[1] + ' ' + values[2] + ' ' + values[3] + ' ' + values[4] + ':' + values[5] + ':' + values[6]));
// The time zone is calculated
if(values[9]){
var timeZoneOffset = -1 * (values[9]*60 + (values[11]?values[11]*1:0)) * (values[8]=='-'?-1:1);
var currentTimeZoneOffset = this.getTimezoneOffset();
this.setTime(this.getTime() + (timeZoneOffset - currentTimeZoneOffset) * 60000);
}
} else if (dateRegex.test(isoFormattedDate)) {
var values = dateRegex.exec(isoFormattedDate);
var tmpDate = new Date(values[1], values[2] - 1, values[3]);
this.setTime(tmpDate.getTime());
//this.setTime(Date.parse(values[1] + ' ' + values[2] + ' ' + values[3]));
} else if (timeRegex.test(isoFormattedDate)) {
var values = timeRegex.exec(isoFormattedDate);
this.setHours(values[1]);
this.setMinutes(values[2]);
this.setSeconds(values[3]);
}
return this;
};
/**
* Return the iso formatted representation of the date
*
* @return string The iso formatted date
*/
Date.prototype.toIso = function() {
var formattedDate = this.getFullYear() + '-' + Number.padTo(this.getMonth()+1) + '-' + Number.padTo(this.getDate());
formattedDate = formattedDate + 'T' + Number.padTo(this.getHours()) + ':' + Number.padTo(this.getMinutes()) + ':' + Number.padTo(this.getSeconds());
return formattedDate;
};
/**
* Return formatted date
*
* @param string format The date output format
* @optionalparam string[] months The translated months
* @return string The formatted date
*/
Date.prototype.format = function(format, months) {
// The date is formatted
format = format.replace('dddd','dd');
format = format.replace('ddd', 'dd');
format = format.replace('dd', Number.padTo(this.getDate()));
format = format.replace('d', this.getDate());
format = format.replace('yyyy', this.getFullYear());
format = format.replace('yy', (new String(this.getFullYear())).substr(2,2));
format = format.replace('y', (new String(this.getFullYear())).substr(2,2));
// The time is formatted
format = format.replace('HH', Number.padTo(this.getHours()));
format = format.replace('H', this.getHours());
format = format.replace('mm', Number.padTo(this.getMinutes()));
format = format.replace('m', this.getMinutes());
format = format.replace('ss', Number.padTo(this.getSeconds()));
format = format.replace('s', this.getSeconds());
if(format.indexOf('MMMM') != -1 && months && months.length && months[this.getMonth()]){
format = format.replace('MMMM', months[this.getMonth()]);
}else{
format = format.replace('MMMM','MM');
format = format.replace('MMM', 'MM');
format = format.replace('MM', Number.padTo(this.getMonth()+1));
format = format.replace('M', this.getMonth()+1);
}
format = format.replace(/['"]/g,'');
return format;
};
/**
* Returns the week number for this date.
* @return int
*/
Date.prototype.getWeek = function() {
var onejan = new Date(this.getFullYear(),0,1);
return Math.ceil((((this - onejan) / 86400000) + onejan.getDay())/7);
};
var BookingCalendar = new Class({
options: {
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // days of the week starting at sunday
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
offset: 0, // first day of the week: 0 = sunday, 1 = monday, etc..
onHideStart: Class.empty,
onHideComplete: Class.empty,
onShowStart: Class.empty,
onShowComplete: Class.empty
},
// initialize: calendar constructor
// @param props (obj) optional properties
initialize: function(options) {
if(options.days && !options.days.length){
options.days = this.options.days;
}
if(options.months && !options.months.length){
options.months = this.options.months;
}
this.setOptions(options);
this._validDates = new Array();
this._selectedDate = null;
this._linkedElement = null;
this._maxMonth = null;
this._minMonth = null;
var today = new Date();
today.setHours(0);
today.setMinutes(0);
today.setSeconds(0);
today.setMilliseconds(0);
this._todayTime = today.getTime();
// create cal element with css styles required for proper cal functioning
this.calendar = new Element('div', {
'styles': { left: '-1000px', opacity: 0, display:'none', position: 'absolute', top: '-1000px', zIndex: 1000 }
}).addClass('BookingCalendar Synergee-Web-Page-Component-SchoolPriceEstimation-List').injectInside(document.body);
// initialize fade method
this.fx = this.calendar.effect('opacity', {
onStart: function() {
if (this.calendar.getStyle('opacity') == 0) { // show
this.calendar.setStyle('display', 'block');
this.fireEvent('onShowStart', this.element);
}
else { // hide
this.fireEvent('onHideStart', this.element);
}
}.bind(this),
onComplete: function() {
if (this.calendar.getStyle('opacity') == 0) { // hidden
this.calendar.setStyle('display', 'none');
this.fireEvent('onHideComplete', this.element);
}
else { // shown
this.fireEvent('onShowComplete', this.element);
}
}.bind(this)
});
this.calendarPreviousMenu = new Element('input').setProperties({'type':'button', value: '<'}).addClass('NavButton PrevMonth Synergee-Web-Page-Component-SchoolPriceEstimation-List-Item Synergee-Web-Page-Component-ShoppingCart-List-Item').injectInside(this.calendar);
this.calendarNextMenu = new Element('input').setProperties({'type':'button' , value: '>'}).addClass('NavButton NextMonth Synergee-Web-Page-Component-SchoolPriceEstimation-List-Item Synergee-Web-Page-Component-ShoppingCart-List-Item').injectInside(this.calendar);
this.calendarInner = new Element('div',{}).addClass('CalendarInner').injectInside(this.calendar);
this.calendarFirstMonthContainer = new SynergeeCalendarMonth(this.options, this);
this.calendarFirstMonthContainer.getContainer().injectInside(this.calendarInner);
this.calendarSecondMonthContainer = new SynergeeCalendarMonth(this.options, this);
this.calendarSecondMonthContainer.getContainer().injectInside(this.calendarInner);
this.calendarPreviousMenu.addEvent('click', this.prevMonth.bind(this));
this.calendarNextMenu.addEvent('click', this.nextMonth.bind(this));
if(window.ie){
this.calendarPreviousMenu.addEvent('dblclick', this.prevMonth.bind(this));
this.calendarNextMenu.addEvent('dblclick', this.nextMonth.bind(this));
}
document.addEvent('click', function(event){
this.hide();
}.bind(this));
this.calendar.addEvent('click', function(e){
if(window.ie){
window.event.cancelBubble = true;
}else {
e.stopPropagation();
}
}.bind(this));
this.calendar.addEvent('mouseleave', function(){
this._hideDelay = this.hide.delay(2500, this);
}.bind(this));
this.calendar.addEvent('mouseenter', function(){
$clear(this._hideDelay);
}.bind(this));
this.calendarFirstMonthContainer.addEvent('dateselected', this._onDateSelected.bind(this));
this.calendarSecondMonthContainer.addEvent('dateselected', this._onDateSelected.bind(this));
var id = 0;
var d = new Date(); // today
d.setDate(1);
this.displayMonths(d.getMonth(), d.getFullYear());
},
/**
* Display the given month
*
* @param integer month The month 0-11
* @param integer year the year
*/
displayMonths : function(month, year) {
if(parseInt(year + (month > 9 ? '' : '0') + month) > parseInt(this.calendarFirstMonthContainer.year + (this.calendarFirstMonthContainer.month > 9 ? '' : '0') + this.calendarFirstMonthContainer.month)){
this._direction = 1;
} else {
this._direction = 0;
}
$clear(this._updateFirstCalendarTimer);
$clear(this._updateSecondCalendarTimer);
if(this._minMonth && parseInt(this._minMonth) < parseInt(year + (month > 9 ? '' : '0') + month)){
this.calendarPreviousMenu.setStyle('display', '');
}else {
this.calendarPreviousMenu.setStyle('display', 'none');
}
this.calendarFirstMonthContainer.month = month;
this.calendarFirstMonthContainer.year = year;
this.calendarFirstMonthContainer.calendarTitle.setHTML(this.options.months[month] + ' ' + year);
month = this.calendarFirstMonthContainer.month;
year = this.calendarFirstMonthContainer.year;
if (month == 11) {
month = 0;
year++;
} else {
month++;
}
this.calendarSecondMonthContainer.month = month;
this.calendarSecondMonthContainer.year = year;
this.calendarSecondMonthContainer.calendarTitle.setHTML(this.options.months[month] + ' ' + year);
if(this._maxMonth && parseInt(this._maxMonth) > parseInt(year + (month > 9 ? '' : '0') + month)){
this.calendarNextMenu.setStyle('display', '');
}else {
this.calendarNextMenu.setStyle('display', 'none');
}
this._updateFirstCalendarTimer = this.calendarFirstMonthContainer.updateCalendar.delay(100, this.calendarFirstMonthContainer, this._direction);
this._updateSecondCalendarTimer = this.calendarSecondMonthContainer.updateCalendar.delay(100, this.calendarSecondMonthContainer, this._direction);
},
/**
* go to the next month
*/
nextMonth : function(){
var month = this.calendarFirstMonthContainer.month;
var year = this.calendarFirstMonthContainer.year;
if(month == 11){
month= 0;
year++;
}else {
month++;
}
this.displayMonths(month, year);
},
/**
* Go to the previous month
*/
prevMonth : function(){
var month = this.calendarFirstMonthContainer.month;
var year = this.calendarFirstMonthContainer.year;
if(month == 0){
month = 11;
year--;
}else {
month--;
}
this.displayMonths(month, year);
},
/**
* Show the calendar
*
* @param element
*/
show : function(element){
this._linkedElement = element;
var ec = element.getCoordinates();
this.calendar.setStyles({
opacity : 0,
display : 'none',
left : ec.left + ec.width,
top : ec.top
});
this.fx.start(0,1);
},
/**
* Hide the calendar
*/
hide : function(){
if(this.calendar.getStyle('opacity') != 0)
this.fx.start(1,0);
},
/**
* When a date is selected
*
* @param date
*/
_onDateSelected : function(date){
this._selectedDate = date.value;
this.fireEvent('dateselected');
},
/**
* Return the selected date
*/
getSelectedDate : function() {
return this._selectedDate;
},
/**
* set the selected date
* @param date
* @param before
* @param after
*/
setSelectedDate : function(date, before, after) {
var year = date.getFullYear();
var month = date.getMonth();
var dateDay = date.getDate();
this._validDates.each(function(item, index){
if(item.year == year && item.month == month && item.date == dateDay && before == item.additionalNightsBefore && after == item.additionalNightsAfter){
this._selectedDate = item;
}
}.bind(this));
this.displayMonths(month, year);
},
/**
* Set the valid dates
*
* @param date[] validDates The valid date
* @param integer additionalNightsBefore the valid days before the dates
* @param integer additionalNightsAfter The valid days after the dates
* @param boolean onBoundsOnly True if the days before and after are only valid on the boundary dates
*/
setValidDates : function(validDates, additionalNightsBefore, additionalNightsAfter, onBoundsOnly){
if(!additionalNightsBefore)additionalNightsBefore = 0;
if (!additionalNightsAfter)additionalNightsAfter = 0;
this._validDates = new Array();
if (validDates.length) {
this._additionalNightsBefore = additionalNightsBefore;
this._additionalNightsAfter = additionalNightsAfter;
var dateIndex = new Date();
dateIndex.setHours(12);
dateIndex.setMinutes(0);
dateIndex.setSeconds(0);
dateIndex.setMilliseconds(0);
var dayTime = (86400) * 1000; // ms
var firstDate = validDates[0];
validDates.each(function(item, index) {
if (this._additionalNightsBefore && (index == 0 || !onBoundsOnly)) {
dateIndex.setYear(item.getFullYear());
dateIndex.setMonth(item.getMonth());
dateIndex.setDate(item.getDate());
for (var i = 1; i <= this._additionalNightsBefore; i++) {
dateIndex.setTime(dateIndex.getTime() - dayTime);
if(this._todayTime <= dateIndex.getTime()){
var dateObject = new Object();
dateObject.relativeDate = item;
dateObject.additionalNightsBefore = i;
dateObject.additionalNightsAfter = 0;
dateObject.year = dateIndex.getFullYear();
dateObject.month = dateIndex.getMonth();
dateObject.date = dateIndex.getDate();
dateObject.time = dateIndex.getTime();
this._validDates.push(dateObject);
}
}
this._validDates.reverse();
}
var dateObject = new Object();
dateObject.relativeDate = item;
dateObject.additionalNightsBefore = 0;
dateObject.additionalNightsAfter = 0;
dateObject.year = item.getFullYear();
dateObject.month = item.getMonth();
dateObject.date = item.getDate();
dateObject.time = item.getTime();
this._validDates.push(dateObject);
if (this._additionalNightsAfter && (index == validDates.length - 1 || !onBoundsOnly)) {
dateIndex.setYear(item.getFullYear());
dateIndex.setMonth(item.getMonth());
dateIndex.setDate(item.getDate());
for (var i = 1; i <= this._additionalNightsAfter; i++) {
dateIndex.setTime(dateIndex.getTime() + dayTime);
var dateObject = new Object();
dateObject.relativeDate = item;
dateObject.additionalNightsBefore = 0;
dateObject.additionalNightsAfter = i;
dateObject.year = dateIndex.getFullYear();
dateObject.month = dateIndex.getMonth();
dateObject.date = dateIndex.getDate();
dateObject.time = dateIndex.getTime();
this._validDates.push(dateObject);
}
}
if (index == 0) {
firstDate = this._validDates[0];
}
}.bind(this));
}
if(this._validDates.length){
this._maxMonth = this._validDates.getLast().year  + (this._validDates.getLast().month > 9 ? '' : '0') + this._validDates.getLast().month;
this._minMonth = firstDate.year + (firstDate.month > 9 ? '' : '0') + firstDate.month;
}else {
this._maxMonth = null;
this._minMonth = null;
}
this.displayMonths(this.calendarFirstMonthContainer.month, this.calendarFirstMonthContainer.year);
},
/**
* Return the valid dates
*/
getValidDates : function () {
return this._validDates;
},
/**
* Return the valid days before
*/
getValidDaysBefore : function () {
return this._additionalNightsBefore;
},
/**
* Return the linked element
*/
getLinkedElement : function () {
return this._linkedElement;
},
/**
* Return the valid days after
*/
getValidDaysAfter : function () {
return this._additionalNightsAfter;
}
});
BookingCalendar.implement(new Events, new Options);
var SynergeeCalendarMonth = new Class({
options: {
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // days of the week starting at sunday
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
offset: 1 // first day of the week: 0 = sunday, 1 = monday, etc..
},
initialize: function(options, parent) {
this.setOptions(options);
this._parent = parent;
this.calendarFirstMonthContainer = new Element('div', {}).addClass('MonthContainer');
this.calendarHeaders = new Element('div',{}).addClass('CalendarHeader').injectInside(this.calendarFirstMonthContainer);
this.calendarTitleRow = new Element('div',{}).addClass('CalendarTitleRow').injectInside(this.calendarHeaders);
this.calendarTitle  = new Element('div',{}).addClass('CalendarTitle').injectInside(this.calendarTitleRow);
this.calendarWeekDaysHeader = new Element('div').addClass('WeekDaysHeader').injectInside(this.calendarHeaders);
this.calendarContent = new Element('div',{}).addClass('CalendarContent').injectInside(this.calendarFirstMonthContainer);
this.calendarContentScroller = new Element('div', {}).addClass('CalendarContentScroller').injectInside(this.calendarContent);
this.calendarContent.addEvent('click', this._onClick.bind(this));
this.fxScroll = new Fx.Styles(this.calendarContentScroller,  {duration: 100, transition: Fx.Transitions.linear});
if(!this.options.offset)
this.options.offset = 0;
for(var i = 0; i < 7; i++){
var dayNumber = i+this.options.offset;
if(dayNumber > 6)dayNumber = dayNumber-7;
var dayName = this.options.days[dayNumber];
var dayTitle = new Element('div').addClass('WeekDayHeader').injectInside(this.calendarWeekDaysHeader);
dayTitle.setHTML(dayName.substr(0,2));
}
for(var l = 0; l < 6; l++){
var line = new Element('div').addClass('WeekElement').injectInside(this.calendarContentScroller);
for(i = 0; i < 7; i++){
var day = new Element('div').addClass('DayElement').injectInside(line);
}
}
},
getContainer : function(){
return this.calendarFirstMonthContainer;
},
updateCalendar : function(direction){
var d = new Date(); // today
d.setDate(1);
d.setMonth(this.month);
d.setYear(this.year);
// find the start date
while (d.getDay() != this.options.offset) {
d.setDate(d.getDate() - 1);
}
if (direction) {
this.fxScroll.start({
'margin-left' : [0, -150]
}).chain(function() {
this.start({
'margin-left' : [150, 0]
});
});
} else {
this.fxScroll.start({
'margin-left' : [0, 150]
}).chain(function() {
this.start({
'margin-left' : [-150, 0]
});
});
}
// filter the date concerned by the current month
var validDates = new Hash();
if (this._parent.getValidDates().length) {
this._parent.getValidDates().each(function(item, index) {
// if we are on the current month
if(true || (item.month == this.month && item.year == this.year)){
// if there is already an entry for this date
if(validDates.hasKey(item.year + '-' + item.month + '-' + item.date)){
var currentEntry = validDates.get(item.year + '-' + item.month + '-' + item.date);
// if the space between the real date and the new date is bigger than the new one we replace it
if((currentEntry.additionalNightsBefore + currentEntry.additionalNightsAfter) > (item.additionalNightsBefore + item.additionalNightsAfter)){
validDates.set(item.year + '-' + item.month + '-' + item.date, item);
}
}else {
validDates.set(item.year + '-' + item.month + '-' + item.date, item);
}
}
}.bind(this));
}
for (var l = 0; l < 6; l++) {
var line = this.calendarContentScroller.getChildren()[l];
for (var i = 0; i < 7; i++) {
var dayElement = line.getChildren()[i];
dayElement.valid = true;
dayElement.date = d.getDate();
dayElement.year = d.getFullYear();
dayElement.month = d.getMonth();
dayElement.removeClass('Selected');
dayElement.setHTML(dayElement.date);
dayElement.removeClass('MainDate');
dayElement.removeClass('NotCurrentMonth');
if ((validDates.hasKey(dayElement.year + '-' +  dayElement.month + '-' + dayElement.date) )) {
dayElement.addClass('Synergee-Web-Page-Component-SchoolPriceEstimation-List-Item');
dayElement.addClass('Synergee-Web-Page-Component-ShoppingCart-List-Item');
dayElement.removeClass('Component-NotSelectionable');
dayElement.removeClass('Synergee-Web-Page-Component-SchoolPriceEstimation-NotSelectionable');
dayElement.removeClass('Synergee-Web-Page-Component-ShoppingCart-NotSelectionable');
dayElement.value = validDates.get(dayElement.year + '-' +  dayElement.month + '-' + dayElement.date);
if(dayElement.value.additionalNightsBefore == 0 && dayElement.value.additionalNightsAfter == 0){
dayElement.addClass('MainDate');
}
if(this._parent.getSelectedDate() && this._parent.getSelectedDate().time == dayElement.value.time){
dayElement.addClass('Selected');
}
} else {
dayElement.addClass('Component-NotSelectionable Synergee-Web-Page-Component-SchoolPriceEstimation-NotSelectionable');
dayElement.addClass('Component-NotSelectionable Synergee-Web-Page-Component-ShoppingCart-NotSelectionable');
dayElement.removeClass('Synergee-Web-Page-Component-SchoolPriceEstimation-List-Item');
dayElement.removeClass('Synergee-Web-Page-Component-ShoppingCart-List-Item');
dayElement.valid = false;
}
if(dayElement.month != this.month){
dayElement.addClass('NotCurrentMonth');
}
d.setDate(d.getDate() + 1);
}
}
},
_onClick : function(e){
if(window.ie){
window.event.cancelBubble = true;
}else {
e.stopPropagation();
}
var target = e.target || e.srcElement;
if(target.hasClass('DayElement') && target.valid){
$$('.DayElement').removeClass('Selected');
target.addClass('Selected');
this.fireEvent('dateselected', target);
}
},
getSelectedDate : function(){
return this._parent.getSelectedDate();
}
});
SynergeeCalendarMonth.implement(new Events, new Options);
var Ticker = new Class({
setOptions: function(options) {
this.options = Object.extend({
speed: 1000,
delay: 5000,
onComplete: Class.empty,
onStart: Class.empty
}, options || {});
},
initialize: function(el,options){
this.setOptions(options);
this.el = $(el).getElement('div');
if (this.el.getElement('hr')) {
var children = this.el.childNodes;
var news = new Array();
news.push(new Element('div'));
for (var i = 0; i < children.length; i++) {
if ($type(children[i]) == 'element' && children[i].tagName.toLowerCase() == 'hr') {
news.push(new Element('div'));
} else if (news.length) {
if ($type(children[i]) == 'element') {
news[news.length - 1].appendChild(children[i]);
} else {
news[news.length - 1].appendChild(children[i]);
}
i--;
}
}
this.el.empty();
for(var i = 0; i < news.length; i ++){
this.el.appendChild(news[i]);
}
this.items = this.el.getElements('div');
if (this.items.length) {
var w = 0;
this.items.each(function(item, index) {
w += item.getSize().size.x;
item.addEvent('mouseenter', function(){
$clear(this.delayedFunction);
}.bind(this));
item.addEvent('mouseleave', function(){
this.next();
}.bind(this));
}.bind(this));
this.el.setStyles({
position: 'absolute',
top: 0,
left: 0,
width: w
});
this.periodical =
this.fx = new Fx.Styles(this.el, {duration:this.options.speed,onComplete:function() {
var i = (this.current == 0) ? this.items.length : this.current;
this.items[i - 1].injectInside(this.el);
this.el.setStyle('left', 0);
}.bind(this)});
this.current = this.items.length;
this.next();
}
}
},
next: function() {
this.current++;
if (this.current >= this.items.length) this.current = 0;
this.fx.start({
top: this.items[this.current].offsetTop,
left: -this.items[this.current].offsetLeft
});
this.delayedFunction = this.next.bind(this).delay(this.options.delay);
}
});/**
*  Create a waiting panel object
*
*/
var WaitingPanel = Events.extend({
initialize: function(el) {
if($(el).waitingPanel){
return $(el).waitingPanel;
}
this.el = $(el);
this.el.waitingPanel = this;
},
buildObjects : function() {
// the waiting panel layer and fx style are created
this._waitingPanelLayer = new Element('div', {'class': 'WaitingPanel-AjaxLoading','id':'waitingPanel'});
this._waitingFxStyle = new Fx.Style(this._waitingPanelLayer, 'opacity', {duration:100});
this._waitingPanelLayer.injectAfter(document.getElementsByTagName('div')[0]);
this._waitingPanelLayer.setStyle('position', 'absolute');
this._waitingPanelLayer.setStyles({
opacity : 0
});
this._waitingImageLayer = new Element('div', {'class': 'WaitingPanel-AjaxLoadingImage','id':'waitingPanel'});
this._waitingImageFxStyle = new Fx.Style(this._waitingImageLayer, 'opacity', {duration:100});
this._waitingImageLayer.injectAfter(this._waitingPanelLayer);
this._waitingImageLayer.setStyle('position', 'absolute');
this._waitingImageLayer.setStyles({
opacity : 0
});
},
/**
*  Display a waiting panel layer over the element
*/
display : function() {
if (!this._waitingPanelLayer) {
this.buildObjects();
}
// refresh the height of the waiting panel layer
var coordinates = this.el.getCoordinates();
this._waitingPanelLayer.elementTo = this.el;
this._waitingPanelLayer.setStyles({
height : (coordinates.height + 2),
width : (coordinates.width + 2),
left : (coordinates.left - 2),
top : (coordinates.top - 2)
});
this._waitingImageLayer.setStyles({
height : (coordinates.height + 2),
width : (coordinates.width + 2),
left : (coordinates.left - 2),
top : (coordinates.top - 2)
});
this._waitingFxStyle.start(0, 0.5);
this._waitingImageFxStyle.start(0, 1);
},
/**
* Hide the waiting panel
*/
hide : function() {
if (this._waitingPanelLayer && this._waitingPanelLayer.getStyle('opacity') != 0) {
this._waitingFxStyle.start(0.5, 0);
this._waitingImageFxStyle.start(1, 0);
}
}
});/**
*  Create a message panel object
*
*/
var WindowMessagePanel = Events.extend({
initialize: function(el) {
if ($(el).messagePanel) {
return $(el).messagePanel;
}
this.el = $(el);
this.el.messagePanel = this;
},
/**
* Display a given message
* @param string message The message
* @param integer autoClose The autoclose timer in milliseconds
*/
displayMessage : function(message, title ,autoClose) {
$clear(this.autoClose);
if (!this._messageContainer) {
this._container = new Element('div',{'class': 'Synergee-Web-Page-Component-MessagePanel-Container'});
this._messageContainer = new Element('div', {'class': 'Synergee-Web-Page-Component-MessagePanel'});
this._messageTitle = new Element('div', {'class': 'Synergee-Web-Page-Component-MessagePanel-Title'});
this._messageContainerClose = new Element('div', {'class': 'Synergee-Web-Page-Component-MessagePanel-Close'});
this._messageContainerClose.addEvent('click', this.hideMessage.bind(this));
this._messageContainerClose.setHTML('x');
this._messageTitle.setHTML(title);
this._messageContainerFx = new Fx.Style(this._container, 'opacity', {duration:300});
this._container.injectInside(this.el);
this._messageTitle.injectInside(this._container);
this._messageContainer.injectInside(this._container);
this._messageContainerClose.injectInside(this._container);
this._container.setStyle('position', 'absolute');
this._container.setOpacity(0);
}
this._messageContainer.setHTML(message);
// the waiting panel layer and fx style are created
var containerCoord = this.el.getCoordinates();
this._messageContainerFx.stop();
this._container.setStyles({
'top': (this.el.getCoordinates().height - this._container.getCoordinates().height ) / 2,
'left': (containerCoord.width - 300) / 2,
'width':300,
'min-height':20,
'z-index':10000
});
this._messageContainerFx.start(0, 1);
if (autoClose) {
this.autoClose =  this.hideMessage.delay(autoClose, this);
}
},
getContent : function(){
return this._messageContainer;
},
hideMessage : function() {
$clear(this.autoClose);
this._messageContainerFx.stop();
this._messageContainerFx.start(1, 0);
}
});
var WebsiteSelector = Options.extend({
initialize: function(componentId) {
this._componentId = componentId;
this._websiteList = $(this._componentId + '_siteSelectorLanguageListId');
this._textLink = $(this._componentId + '_siteSelectorLanguageText');
this._websiteList.setStyle('margin-top', '-540000px');
window.addEvent('load', function(){
this._height = this._websiteList.getCoordinates().height;
$(this._componentId + '_siteSelectorCurrentSelectionId').addEvent('mouseover', this.displaySiteSelector.bind(this));
$(this._componentId + '_siteSelectorCurrentSelectionId').getParent().addEvent('mouseleave', this.hideSiteSelector.bind(this));
this._websiteList.setStyle('margin-top', '');
if(this.listFx)this.listFx.set(0);
this._websiteList.addClass('HideClass');
}.bind(this));
try {
this._websiteList.addClass('SiteSelectorLanguageListFx');
} catch(ex) {
}
if (!document.isInDesignMode()) {
this._fxTime = 300;
this.listFx = new Fx.Style($(this._componentId + '_siteSelectorLanguageListId'), 'height', {wait:false, duration:this._fxTime});
this._textFx = new Fx.Style($(this._componentId + '_siteSelectorLanguageText'), 'opacity', {wait:false, duration:this._fxTime / 2});
}
},
hideSiteSelector : function(e) {
var target = e.relatedTarget;
while (target && target.getAttribute && (target.getAttribute('id') != this._componentId + '_siteSelectorCurrentSelectionId' && target.getAttribute('id') != this._componentId + '_siteSelectorLanguageListId')) {
if (target.getParent && target.getParent()) {
target = target.getParent();
} else {
target = false;
}
}
if (target != this._websiteList) {
this.listFx.stop();
this.listFx.start(this._websiteList.getCoordinates().height, 0);
this._textFx.stop();
this._textFx.start(this._textLink.getStyle('opacity'), 1);
this._websiteList.addClass('HideClass');
}
},
displaySiteSelector : function(e) {
this._websiteList.removeClass('HideClass');
this._textFx.stop();
this.listFx.stop();
var height = this._websiteList.getCoordinates().height;
if(height < this._websiteList.getCoordinates().height)height =  this._websiteList.getCoordinates().height;
this.listFx.start(height, this._height);
this._textFx.start(this._textLink.getStyle('opacity'), 0);
}
});
var isVariableOrOptional;
var isPricesAvailable;
var isPricesAvailableNextYear;
var isCurrentYear;
// this function selects the current year in the price table
function selectCurrentYear() {
isCurrentYear = true;
$$('.CurrentYearTable').removeClass('HideTab');
$$('.CurrentYearTable').setStyle('visibility', 'visible');
$$('.CurrentYear').addClass('YearTabStyleSelected');
$$('.NextYearTable').addClass('HideTab');
$$('.NextYearTable').setStyle('visibility', 'hidden');
$$('.NextYear').removeClass('YearTabStyleSelected');
if (isVariableOrOptional && isPricesAvailable) {
$$('.YearTabs').addClass('TabPosition');
}
else {
$$('.YearTabs').removeClass('TabPosition');
}
};
// this function selects the next year in the price table
function selectNextYear() {
isCurrentYear = false;
$$('.NextYearTable').removeClass('HideTab');
$$('.NextYearTable').setStyle('visibility', 'visible');
$$('.NextYear').addClass('YearTabStyleSelected');
$$('.CurrentYearTable').addClass('HideTab');
$$('.CurrentYearTable').setStyle('visibility', 'hidden');
$$('.CurrentYear').removeClass('YearTabStyleSelected');
if (isVariableOrOptional) {
$$('.YearTabs').addClass('TabPosition');
}
else {
$$('.YearTabs').removeClass('TabPosition');
}
};
window.addEvent('domready', function() {
// if the following id exists, we are on a course type page, otherwise it is a school page
if ($('schoolCoursePriceCalculator')) {
isCurrentYear = (new Date()).getMonth() < 10;   // we show the next year prices if we are 2 months away from new year
$$('.CurrentYear').setHTML((new Date()).getFullYear());
$$('.NextYear').setHTML((new Date()).getFullYear()+1);
$$('.CurrentYear').addEvent('click', selectCurrentYear);
$$('.NextYear').addEvent('click', selectNextYear);
var fadeTime = window.ie == true ? 0 : 500;     // ie6 doesn't handle the transition effect properly so we just set the effect duration to 0
var padding = 0;
if($$('.Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Tables').length && $$('.Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Tables')[0]){
padding =  $$('.Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Tables')[0].getStyle('padding-left').toInt() + $$('.Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Tables')[0].getStyle('padding-right').toInt();
}
var componentSize = $('schoolCoursePriceCalculator').getStyle('width').toInt() - padding;
if(window.ie){
tableWidth = 'auto';
}else {
tableWidth =  componentSize;
}
$$('div.Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Tables').setStyle('width',tableWidth);
$$('div.SchoolPriceCalculatorCourseTitle').setStyle('width', componentSize - 1);
$$('div.SchoolPriceCalculatorCourseText').setStyle('width', componentSize - 1);
$$('div.Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Table').each(function(el, index) {
el.fxStart = new Fx.Style(el, 'opacity', {duration: 500,transition: Fx.Transitions.linear
});
el.fxEnd = new Fx.Style(el, 'opacity', {duration: 500,transition: Fx.Transitions.linear,
onComplete: function(el) {
el.setStyle('display', 'none');
}
});
}.bind(this));
var tabs = $$('.Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Course-Tab');
var tables = $$('div.Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Table');
if(tabs.length)tables.setStyle('display','none');
selectedTab = -1;
tabs.each(function(el, index){
el.table = tables[index];
el.tabIndex = index;
el.addEvent('click', function(e) {
if (selectedTab != el.tabIndex) {
if (selectedTab != -1) {
tabs[selectedTab].table.setOpacity(0);
tabs[selectedTab].table.setStyle('display', 'none');
tabs[selectedTab].removeClass('Synergee-Web-Page-Component-SchoolCoursePriceCalculator-CourseTabSelected');
}
selectedTab = el.tabIndex;
el.table.setStyle('display', 'block');
el.table.fxStart.start(0, 1);
el.addClass('Synergee-Web-Page-Component-SchoolCoursePriceCalculator-CourseTabSelected');
isPricesAvailable = el.table.getElement('table.NoPricesTable') == false;
isPricesAvailableNextYear = el.table.getElement('table.NoNextYearPricesTable') == false;
isVariableOrOptional = el.table.getProperty('id').indexOf('fixed') < 0;
el.table.setStyle('height', 'auto');
el.table.setStyle('width', tableWidth);
el.table.setStyle('overflow', 'visible');
if (isCurrentYear || !isPricesAvailableNextYear) {
selectNextYear();
selectCurrentYear();
}
else {
selectNextYear();
}
}
selectedTab = el.tabIndex;
}.bind(this));
}.bind(this));
if(tabs[0]){
tabs[0].fireEvent('click');
}
if(!$$('.CurrentYear').length && $$('.NextYear').length){
$$('.NextYear')[0].fireEvent('click');
}
}
// we are on a school page
else {
// add tabs to select current or next year prices if available
addCourseYearSelection('currentYearTabVariableId', 'nextYearTabVariableId', 'Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Table-CurrentYear-SchoolPageId-Variable', 'Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Table-NextYear-SchoolPageId-Variable', 'Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Year-TabSelected');
addCourseYearSelection('currentYearTabFixedId', 'nextYearTabFixedId', 'Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Table-CurrentYear-SchoolPageId-Fixed', 'Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Table-NextYear-SchoolPageId-Fixed', 'Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Year-TabSelected');
addCourseYearSelection('currentYearTabOptionalId', 'nextYearTabOptionalId', 'Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Table-CurrentYear-SchoolPageId-Optional', 'Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Table-NextYear-SchoolPageId-Optional', 'Synergee-Web-Page-Component-SchoolCoursePriceCalculator-Year-TabSelected');
}
});
function addCourseYearSelection(currentYearTabId, nextYearTabId, currentYearTableId, nextYearTableId, selectedTabStyle) {
var yearSelectionAvailable = $(currentYearTabId) && $(nextYearTabId);
if ($(currentYearTabId)) {
$(currentYearTabId).setHTML((new Date()).getFullYear());
$(currentYearTabId).addClass(selectedTabStyle);
}
if ($(nextYearTabId)) {
$(nextYearTabId).setHTML((new Date()).getFullYear()+1);
if (!yearSelectionAvailable) {
$(nextYearTabId).addClass(selectedTabStyle);
}
else {
$(nextYearTableId).addClass('HideTab');
}
}
// check if the next year price table exists, if not the year selection is useless so we don't create it
if (yearSelectionAvailable) {
$(currentYearTabId).addEvent('click', function () {
$(nextYearTableId).addClass('HideTab');
$(currentYearTableId).removeClass('HideTab');
$(currentYearTabId).addClass(selectedTabStyle);
$(nextYearTabId).removeClass(selectedTabStyle);
});
$(nextYearTabId).addEvent('click', function () {
$(currentYearTableId).addClass('HideTab');
$(nextYearTableId).removeClass('HideTab');
$(nextYearTabId).addClass(selectedTabStyle);
$(currentYearTabId).removeClass(selectedTabStyle);
});
}
};

