/*
	Sharp $Id: scripts.js 699 2009-05-11 21:51:33Z Sebastian.Martens $
	main JavaScript for Sharp
*/

// global Sharp package ==================================================
if(typeof sha == "undefined"){
	if(typeof this["sha"] == "undefined"){
		this.sha = {};
	}
	sha.global = this;
}

// Global Constants ===============================================
// custom events
sha.EVT_REPOSELEM = "reposElem"; // reposition elements on page if content is resized (e.g. shadows, footer, ...)
sha.EVT_UPDCP = "updateContent"; // update the content of a content pane by passing i.e. a product id
sha.EVT_SWTAB = "switchTab"; // switch a tab within a tab container
sha.EVT_PLFLY = "placeFlyouts"; // places the flyout menu items at the end of the body container
sha.EVT_SHOWCP = "showContentPane"; // shows the contentpane

// prodList and compareLayer events
sha.EVT_RESIZE = "resizeJS";
sha.EVT_GETCONTENT = "getContentJS";
sha.EVT_TOOLTIP = "toolTip";
sha.EVT_OPENCOMPARELAYER = "openCompareLayer";
sha.EVT_CLOSECOMPARELAYER = "closeCompareLayer";
sha.EVT_STARTCOMPARELAYER = "startCompareLayer";
sha.EVT_PRINTPAGE = "printPage";
sha.EVT_BACKTOPRODLSTFRCOMP = "backToProdLstFrComp";
sha.EVT_BACKTOPRODLSTDETL = "backToProdLstFrDetl";
sha.EVT_COMPARETODETAIL = "compareToDetail";
sha.EVT_DETAILTOCOMPARE = "detailToCompare";
sha.EVT_LOCCONSUBSCRIBER = "locConSubscriber";
sha.EVT_VERTICALSHIFT = "verticalShiftFunc";

// Event Dispatcher ======================================================
sha.evtDispatch = {
	resizeJSFunc: function(obj) {
		var iobj = dojo.fromJson(obj);
		dojo.publish(sha.EVT_RESIZE, [iobj.height, iobj.width]);
	},
	getContentJSFunc: function(obj) {
		var iobj = dojo.fromJson(obj);
		dojo.publish(sha.EVT_GETCONTENT, [iobj.url]);
	},
	toolTipJSFunc: function(obj) {
		dojo.publish(sha.EVT_TOOLTIP, [obj]);
	},
	openCompareLayerFunc: function(obj) {
		dojo.publish(sha.EVT_OPENCOMPARELAYER);
	},
	closeCompareLayerFunc: function() {
		dojo.publish(sha.EVT_CLOSECOMPARELAYER);
	},
	startCompareFunc: function() {
		dojo.publish(sha.EVT_STARTCOMPARELAYER);
	},
	printPageFunc: function(obj) {
		var iobj = dojo.fromJson(obj);
		dojo.publish(sha.EVT_PRINTPAGE, [iobj.url]);
	},
	backToProdLstFrComp: function() {
		dojo.publish(sha.EVT_BACKTOPRODLSTFRCOMP);
	},
	backToProdLstFrDetl: function() {
		dojo.publish(sha.EVT_BACKTOPRODLSTDETL);
	},
	compareToDetail: function() {
		dojo.publish(sha.EVT_COMPARETODETAIL);
	},
	detailToCompare: function() {
		dojo.publish(sha.EVT_DETAILTOCOMPARE);
	},
	locConSubscriber: function() {
		dojo.publish(sha.EVT_LOCCONSUBSCRIBER);
	}
}
// Flyout Menue ==========================================================
sha.topnav = {
	navHeader: "sha_headfunc", // id of main navigation container
	nav1: "sha_nav1", // id of main navigation top ul element
	nav2: "sha_nav2", // id of language selection element
	flyoutObjects: new Array(), // contains all flyout elements as manageable objects
	flyoutClassname: "sha_nav1_flyout", // CSS class for main navigation flyout
	flyoutRightClassname: "sha_nav2_flyout", // CSS class for language selection flyout
	counter:0, // counter for flyout elements to generate unique id's
	ifr: null, // iframe for IE 6 to cover windowed elements (repositioned under actually shown flyout)
	ifrZindex: 639, // z-index for iframe
	outOfScreen: -9999, // CSS top or left position for visually hiding elements 
	dropShadowClass: ".sha_dropshadow", // CSS class for shadowed containers
	hideClass: "sha_acchide", // CSS class for hiding containers by shifting them out of the viewport
	
	/**
	 * menu initialization: appends menu functionality on all menu items and flyouts
	 * 
	 */
	initMenu: function() {
		this.navHeader = dojo.byId(this.navHeader);
		if (!this.navHeader) return;
		var sfEls = dojo.query("#"+this.nav1 +" > li", this.navHeader);
		var nav2elem = dojo.byId(this.nav2);
		if(nav2elem) sfEls.push(nav2elem);
		dojo.forEach(sfEls, function(navEl) {
			if(navEl.id != this.nav2) navEl.id = "sha_nav1_el_" +this.counter;
			this.flyoutObjects[navEl.id] = new sha.topnav.flyout(navEl);
			this.counter++;
			if(this.flyoutObjects[navEl.id].shadowContainer){
				this.flyoutObjects[navEl.id].shadowContainer.onmouseover = function() {
					sha.topnav.flyoutObjects[this._id].show();
				}
				this.flyoutObjects[navEl.id].shadowContainer.onmouseout = function() {
					sha.topnav.flyoutObjects[this._id].hide();
				}
				navEl.onmouseover=function() {
					sha.topnav.flyoutObjects[this.id].show();
				}
				navEl.onmouseout=function() {
					sha.topnav.flyoutObjects[this.id].hide();
				}
			}
		},this);
		var flyoutListener = dojo.subscribe(sha.EVT_PLFLY,this,"placeFlyouts");
		dojo.publish(sha.EVT_PLFLY);
	},
	/**
	 * generating the iframe for IE 6, replacing flyout elements in DOM at the end of the body element and hiding them
	 * 
	 */
	placeFlyouts: function(){
		var _lastBodyChild = dojo.query("body")[0].lastChild;
		if(dojo.isIE && dojo.isIE<7){
			this.ifr = document.createElement("iframe");
			this.ifr.src ="javascript:false";
			this.ifr.longdesc = "no content";
			this.ifr.scrolling ="no";
			this.ifr.frameborder="0";
			this.ifr.style.display = "none";
			this.ifr.style.filter = "progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)";
			this.ifr.style.position = "absolute";
			this.ifr.style.zIndex = this.ifrZindex;
			dojo.place(this.ifr, _lastBodyChild, "after");
		}
		for (var i in this.flyoutObjects) {
			this.flyoutObjects[i].place(_lastBodyChild);
			this.flyoutObjects[i].hide();
		}
	}
};
/**
 * @classDescription Flyout object for main navigation and language selection
 */
dojo.declare("sha.topnav.flyout", null, {
	shadowContainer: null, // shadowed flyout container node
	coordinates: null, // coordinates of parent element for later positioning of flyout
	visible: false, // visibility state of the flyout element
	ifrPos:null, // position and size of the flyout for iframe formatting
	
	/**
	 * Initializes the flyout Object by querying the shadowed flyout container, setting class name and defining the delayed hide method
	 * @param {domNode} node: parent element containing a shadowed flyout container
	 */
	constructor: function(node) {
		this.shadowContainer = dojo.query(sha.topnav.dropShadowClass,node)[0];
		if(this.shadowContainer){
			this.shadowContainer._id = node.id;
			if(node.id != sha.topnav.nav2){
				dojo.addClass(this.shadowContainer,sha.topnav.flyoutClassname);
			} else {
				dojo.addClass(this.shadowContainer,sha.topnav.flyoutRightClassname);
			}
			this.delayHide = (function(id){
				return function(){
					if(!sha.topnav.flyoutObjects[id].visible){
						dojo.style(sha.topnav.flyoutObjects[id].shadowContainer,"left",sha.topnav.outOfScreen +"px");
						dojo.style(sha.topnav.flyoutObjects[id].shadowContainer,sha.topnav.outOfScreen +"px");
					}
				}
			})(node.id);
		}
	},
	
	/**
	 * Displays the flyout container and places the iframe for IE
	 */
	show: function(){
		if(this.shadowContainer){
			this.coordinates = dojo.coords(this.shadowContainer._id, true);
			this.visible = true;
			if(this.shadowContainer._id != sha.topnav.nav2) {
				dojo.isIE ? dojo.style(this.shadowContainer,"left",this.coordinates.x -12 +"px") : dojo.style(this.shadowContainer,"left",this.coordinates.x -5 +"px");
				dojo.isIE ? dojo.style(this.shadowContainer,"top",this.coordinates.y +23 +"px") : dojo.style(this.shadowContainer,"top",this.coordinates.y +31 +"px");
			} else {
				dojo.isIE ? dojo.style(this.shadowContainer,"left",this.coordinates.x +2*this.coordinates.w -this.shadowContainer.offsetWidth +2 +"px") : dojo.style(this.shadowContainer,"left",this.coordinates.x +2*this.coordinates.w -this.shadowContainer.offsetWidth +10 +"px");
				dojo.isIE ? dojo.style(this.shadowContainer,"top",this.coordinates.y +25 +"px") : dojo.style(this.shadowContainer,"top",this.coordinates.y +33 +"px");
			}
			dojo.style(this.shadowContainer,"position","absolute");
			dojo.removeClass(this.shadowContainer,sha.topnav.hideClass);
			if(dojo.isIE && dojo.isIE<7){
				this.ifrPos = dojo.coords(this.shadowContainer);
				dojo.style(sha.topnav.ifr,"left",this.ifrPos.x);
				dojo.style(sha.topnav.ifr,"top",this.ifrPos.y);
				dojo.style(sha.topnav.ifr,"width",this.ifrPos.w+4);
				dojo.style(sha.topnav.ifr,"height",this.ifrPos.h+4);
				dojo.style(sha.topnav.ifr,"display","block");
			}
		}
	},
	
	/**
	 * Hides the flyout container and iframe for IE
	 */
	hide: function(){
		this.visible = false;
		if(this.shadowContainer && !this.visible){
			setTimeout(this.delayHide,"50");
		}
		if(dojo.isIE && dojo.isIE<7) dojo.style(sha.topnav.ifr,"display","none");
	},
	
	/**
	 * repositions the flyout container in DOM at the end of the given DOM node
	 * @param {domNode} targetElem: parent element in which the flyout container is positioned as last child
	 */
	place: function(targetElem){
		dojo.place(this.shadowContainer, targetElem, "after");
	}
});
// END Flyout Menue

// Placing Shadow correctly in IE6.0+ ======================================================================
dojo.declare("sha.shadow", null, {
	_box: null,
	_boxbtm: null,
	_boxright: null,
	_boxcorner: null,
	_handle: null,
	
	constructor: function(shdwbox) {
		this._box = shdwbox;
	},
	addShadows: function() {
		var coordinate = dojo.coords(this._box, false);
		this._boxbtm = dojo.doc.createElement("div");
		if ( dojo.isIE >= 7 ) {
			dojo.style(this._boxbtm,"background","url("+sha.imgpath_btm+") no-repeat");
		} else if( dojo.isIE >= 5.5 ) {
			dojo.style(this._boxbtm,"filter","progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+sha.imgpath_btm+"', sizingMethod='crop')");
		}
		else return; // no shadows for IE5-
		dojo.style(this._boxbtm,"height","8px");
		dojo.style(this._boxbtm,"width",coordinate.w+"px");
		dojo.style(this._boxbtm,"position","absolute");
		dojo.style(this._boxbtm,"left", "0" );
		dojo.place(this._boxbtm,this._box,"");
		
		this._boxright = dojo.doc.createElement("div");
		if ( dojo.isIE >= 7 ) {
			dojo.style(this._boxright,"background","url("+sha.imgpath_right+") no-repeat");
		} else if( dojo.isIE >= 5.5 ) {
			dojo.style(this._boxright,"filter","progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+sha.imgpath_right+"', sizingMethod='crop')");
		}
		else return; // no shadows for IE5-
		dojo.style(this._boxright,"width","8px");
		dojo.style(this._boxright,"position","absolute");
		dojo.style(this._boxright,"top", "0px" );
		dojo.place(this._boxright,this._box,"");
		
		this._boxcorner = dojo.doc.createElement("div");
		if ( dojo.isIE >= 7 ) {
			dojo.style(this._boxcorner,"background","url("+sha.imgpath_corner+") no-repeat");
		} else if( dojo.isIE >= 5.5 ) {
			dojo.style(this._boxcorner,"filter","progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+sha.imgpath_corner+"', sizingMethod='crop')");	
		}
		else return; // no shadows for IE5-		
		dojo.style(this._boxcorner,"height","8px");
		dojo.style(this._boxcorner,"width","8px");
		dojo.style(this._boxcorner,"position","absolute");
		dojo.place(this._boxcorner,this._box,"");
	},
	rePos: function(){
		coord = dojo.coords(this._box, false);
		this._boxbtm.style.top = coord.h-10+"px";
		this._boxbtm.style.width = coord.w+"px";
		if(coord.h>=10) this._boxright.style.height = coord.h-10+"px";
		this._boxright.style.left = coord.w+"px";
		this._boxcorner.style.top = coord.h-10+"px";
		this._boxcorner.style.left = coord.w+"px";
	},
	subscribe: function() {
		this._handle = dojo.subscribe(sha.EVT_REPOSELEM, this, this.rePos);
	},
	unsubscribe: function() {
		dojo.unsubscribe(this._handle);
	}
});

sha.shadowManager = {
	posArray: new Array(),
	shadowObjects: new Array(),
	shadowClass: ".sha_dropshadow",
	
	/* Initial creation of the shadows for every box on dropshadow_box on the page. */
	createShadowBoxes: function(obj){
		if(dojo.isIE && obj.boxes.length>0) {
			var i = obj.boxes.length-1;
			do {
				var s = dojo.style(obj.boxes[i], "backgroundRepeat");
				if(s=="no-repeat") break; // in print view check for CSS attribute and quit the shadow creation
				this.shadowObjects[obj.boxes[i].id] = new sha.shadow(obj.boxes[i]);
				this.shadowObjects[obj.boxes[i].id].addShadows();
				this.shadowObjects[obj.boxes[i].id].subscribe();
				i--;
			} while (i >= 0);
		}
	},
	removeShadowObject: function(id){
		if(dojo.isIE && this.shadowObjects && this.shadowObjects[id] ){
			this.shadowObjects[id].unsubscribe();
			this.shadowObjects[id] = null;
		}
	},
	init: function() {
		var boxes = dojo.query(this.shadowClass, document);
		if(boxes.length==0) return; // no shadow containers?
		this.createShadowBoxes({boxes:boxes});
		/* Triggers a method on every assigned instance to position the shadows correctly. */ 
		dojo.publish(sha.EVT_REPOSELEM);
	}
};

// product detail spec view ====================================================
dojo.declare("sha.specsview", null, {
	_open: false,
	_anchor: null,
	_divcnt: null,
	
	constructor: function(anchor, divcnt) {
		this._anchor = anchor;
		if(divcnt){
			this._divcnt = divcnt;
			if (dojo.hasClass(this._anchor,"sha_lnk_minus",true) ){
				dojo.style(this._divcnt, "display", "block");
				this._open = true;
			} else {
				dojo.toggleClass(this._anchor,"sha_lnk_plus",true);
				
				// print.css defines attribute {background-repeat:no-repeat}, indicates to show in printview
				var s = dojo.style(this._divcnt, 'backgroundRepeat');
				if(s!="no-repeat") dojo.style(this._divcnt, "display", "none");
			}
			dojo.connect(this._anchor,"onclick",this,this.toggleView);
		} else {
			dojo.connect(this._anchor,"onclick",this,this.preventLinkExec);
		}
	},
	
	toggleView: function(evt) {
		if (this._open == false) {
			this._open = true;
			dojo.toggleClass(this._anchor, "sha_lnk_plus",false);
			dojo.style(this._divcnt,"display","block");
			dojo.toggleClass(this._anchor, "sha_lnk_minus",true);
		} else {
			this._open = false;
			dojo.toggleClass(this._anchor, "sha_lnk_minus",false);
			dojo.style(this._divcnt,"display","none");
			dojo.toggleClass(this._anchor, "sha_lnk_plus", true);
		}
		dojo.publish(sha.EVT_REPOSELEM);
		dojo.stopEvent(evt);
	},
	preventLinkExec: function(evt){
		dojo.stopEvent(evt);
	}
});

sha.specsViewManager = {
	btn_array: new Array(),
	cnt_array: new Array(),
	
	init: function(parent_cnt) {
		this.cnt_array = dojo.query("h3.sha_swap", parent_cnt);
		
		dojo.forEach(this.cnt_array, function(divcnt) {
			var anchor = dojo.query("a",divcnt)[0];
			var divc = sha.specsViewManager.nextDiv(divcnt);
			
			if (divc && divc.nodeName == "DIV") {
				var instance = new sha.specsview(anchor,divc);
			} else {
				// no sha_tab_table available, onclick will not be set.
				var instance = new sha.specsview(anchor);
				// dojo.toggleClass(anchor,"sha_lnk_minus",true);
			}
		});
	},
	
	nextDiv: function(pre) {
		var n = pre;
		do n = n.nextSibling;
		while (n && n.nodeType != 1);
		return n;
	}
}

// reposition the footer for IE ==================================================
sha.footerEl = {
	_handle: null,
	rePos: function() {
		if(dojo.isIE && dojo.byId("sha_footer")) {
				dojo.byId("sha_footer").style.bottom = "1px";
				setTimeout('dojo.byId("sha_footer").style.bottom = "0px"', 60);
			}
		else {
			setTimeout("sha.footerEl.rePos()", 100);
		}
	},
	evtSub: function() {
		if(dojo.isIE) this._handle = dojo.subscribe(sha.EVT_REPOSELEM, this, this.rePos);
	}
}

// WT10 contact form select combos functionality ==================================
sha.contactSel = {
	selEl: new Array(),
	
	// init 
	init: function(obj) {
		for(var i=0; i<obj.objid.length; i++) {
			this.selEl[i] = dojo.byId(obj.objid[i]);
			dojo.connect(this.selEl[i], 'onchange', this, this.changed);
		}
	},
	changed: function(evt) {
		dojo.forEach(this.selEl, function(el) {
			if(el != evt.target) el.selectedIndex = 0;
		});
	}
}

// WT01 communication JS with FLASH ===============================================
/**
 * build the communication between FLASH movie and LinkList
 * @param
 */
dojo.declare("sha.teah1grp", null, {
	lnkARR: new Array(),
	flaID: null,
	flaObj: null,
	overClass: "sha_hover",
	
	constructor: function(obj) {
		this.lnkARR = dojo.query("li a", obj.ulID);
		this.flaID = obj.flaID;
		this.flaObj = (dojo.isIE) ? window[this.flaID] : window.document[this.flaID];
	},
	
	buildLnks: function() {
		/* // lnk is only the href, not the element
		dojo.forEach(this.lnkARR, function(lnk) {
			dojo.connect(lnk, 'onmouseover', this, this.mouseOver);
		});
		*/
		for(var i=0; i<this.lnkARR.length; i++) {
			dojo.connect(this.lnkARR[i], 'onmouseover', this, this.mouseOver);
			dojo.connect(this.lnkARR[i], 'onmouseout', this, this.mouseOut);
		}
	},
	
	getFlaID: function() {
		return this.flaID;
	},
	
	mouseOver: function(evt) {
		// check if flaObj exists, e.g. if flash version is too minor
		if(this.flaObj){ try{ this.flaObj.hover(evt.target.getAttribute('prodid')); }catch(e){} }
	},
	mouseOut: function(evt) {
		// check if flaObj exists, e.g. if flash version is too minor
		if(this.flaObj){ try{ this.flaObj.hout(evt.target.getAttribute('prodid')); }catch(e){} }
	},
	
	/**
	 * call/transform the links from the FLA
	 */
	aover: function(no) {
		for(var i=0; i<this.lnkARR.length; i++) {
			if(this.lnkARR[i].getAttribute('prodid')==no) dojo.addClass(this.lnkARR[i], this.overClass);
		}
	},
	aout: function(no) {
		for(var i=0; i<this.lnkARR.length; i++) {
			if(this.lnkARR[i].getAttribute('prodid')==no) dojo.removeClass(this.lnkARR[i], this.overClass);
		}
	}
});

sha.teah1grpManager = {
	instARR: new Array(),
	
	init: function(obj) {
		var instance = new sha.teah1grp({ulID:obj.ulID, flaID:obj.flaID});
		this.instARR.push(instance);
		instance.buildLnks();
		return instance;
	},
	
	/**
	 * called from FLA just to get the link group number
	 * @param {Object} flaID: id of flash object
	 */
	callRegister: function(flaID) {
		for(var i in this.instARR) {
			if(this.instARR[i].getFlaID() == flaID) return i;
		}
	},
	
	/**
	 * called from FLA
	 * @param {Object} lnkARRno: lnkGroup id
	 * @param {Object} num: number of link within this group
	 */
	flaHover: function(lnkARRno, num) {
		this.instARR[lnkARRno].aover(num);
	},
	flaHout: function(lnkARRno, num) {
		this.instARR[lnkARRno].aout(num);
	}
}

// sIFR replacements ====================================================
/**
 * @classDescription sIFR replacement of headlines
 * @param {Object} headlines:  src:"path to flash file containing font" - mandatory, ratios:"defining ratios of headline/flash movie size for stable rendering" - optional
 */
sha.sifrReplacement = {
	/**
	 * performs sIFR replacement of headlines
	 */
	run: function(){
		var singleLine = dojo.isIE ? true : false;
		
		sIFR.replace(this.headlines, {
			selector:'.sha_sifr_h1', wmode:'transparent', css: {'.sIFR-root': {'letter-spacing':'0.7'}}
		});
		sIFR.replace(this.headlines, {
			selector:'.sha_tea_h1 .sha_sifr_h2, .sha_tea_h2 .sha_sifr_h2, .sha_tea_c1 .sha_sifr_h2', wmode:'transparent', css: ['.sIFR-root {letter-spacing:0.3;}', 'a {text-decoration:none;}', 'a:link {color: #333333;}', 'a:hover {color:#e6000d;}']
		});
		sIFR.replace(this.headlines, {
			selector:'.sha_sifr_h2_sngl', wmode:'transparent', forceSingleLine:singleLine, tuneWidth:11, css: {'.sIFR-root': {'letter-spacing':'0.3'}}
		});
		sIFR.replace(this.headlines, {
			selector:'.sha_sifr_h2', wmode:'transparent', css: ['.sIFR-root {letter-spacing:0.3;}', '.sha_as {color: #e6000d}']
		});
		sIFR.replace(this.headlines, {
			selector:'.sha_sifr_nores', wmode:'transparent', css: {'.sIFR-root': {'letter-spacing':'0.3','color':'#e6000d'}}
		});
		window.setTimeout("sha.contentelements.reposElems()",200);
	}
}

/**
 * @classDescription content elements and content actions
 */
sha.contentelements = {
	topics: new Array(), // stores all subscriptions
	shadowClass: "sha_dropshadow",
	flexFacettId: "",
	flexFacettSmallClass: "",
	colFlexSmallClass: "",
	prodImgId: "",
	colFlexId:"",
	colDetailId: "",
	startCnt: "",
	hideClass: "sha_acchide",
	cpShow: false,
	
	/**
	 * initialization: defining subscriptions
	 */
	init: function(obj){
		this.topics[sha.EVT_GETCONTENT] = dojo.subscribe(sha.EVT_GETCONTENT, this, "getContent");
		this.topics[sha.EVT_BACKTOPRODLSTDETL] = dojo.subscribe(sha.EVT_BACKTOPRODLSTDETL, this, "backToProdLstDetl");
		this.topics[sha.EVT_DETAILTOCOMPARE] = dojo.subscribe(sha.EVT_DETAILTOCOMPARE, this, "detailToCompare");
		this.topics[sha.EVT_COMPARETODETAIL] = dojo.subscribe(sha.EVT_COMPARETODETAIL, this, "compareToDetail");
		this.topics[sha.EVT_TOOLTIP] = dojo.subscribe(sha.EVT_TOOLTIP, this, "tooltipFrFlex");
		try {
			for(var i in obj){
				this[i] = obj[i];
			}
		} catch(e){}
	},
	
	/**
	 * event listener method, triggered by flex to display product details
	 * @param {String} prodId: product ID to get product details
	 */
	getContent: function(url){
		sha.contentelements.cpShow = true;
		dojo.publish(sha.EVT_UPDCP,new Array(url));
		
	},
	
	/**
	 * event listener method, triggered by flex to return from product details to product listing
	 */
	backToProdLstDetl: function(){
		sha.contentelements.cpShow = false;
		dojo.removeClass(dojo.byId(this.colFlexId), this.colFlexSmallClass);
		dojo.addClass(dojo.byId(this.colDetailId), this.hideClass);
		dojo.removeClass(dojo.byId(this.flexFacettId), this.flexFacettSmallClass);
	},
	
	/**
	 * event listener method, triggered by flex to go from product details to product compare
	 */
	detailToCompare: function(){
		sha.contentelements.cpShow = false;
		dojo.removeClass(dojo.byId(this.colFlexId), this.colFlexSmallClass);
		dojo.addClass(dojo.byId(this.colDetailId), this.hideClass);
		dojo.removeClass(dojo.byId(this.flexFacettId), this.flexFacettSmallClass);
	},
	
	/**
	 * event listener method, triggered by flex to return from product details to product listing
	 */
	compareToDetail: function(){
		sha.contentelements.cpShow = false;
		dojo.removeClass(dojo.byId(this.colFlexId), this.colFlexSmallClass);
		dojo.addClass(dojo.byId(this.colDetailId), this.hideClass);
		dojo.removeClass(dojo.byId(this.flexFacettId), this.flexFacettSmallClass);
	},
	
	/**
	 * event listener method, triggered by flex to display a tooltip with given headline, text and position
	 */
	tooltipFrFlex: function(obj){
		var iobj = dojo.fromJson(obj);
		if(iobj.href){
			sha.contentelements.tooltip.display(iobj);
		} else {
			sha.contentelements.tooltip.displayFrFlex(iobj);
		}
	},
	/**
	 * switch product image display
	 */
	switchImgSrc: function(imgSrc){
		if(imgSrc) dojo.byId(this.prodImgId).src = imgSrc;
	},
	reposWT03: function(){
		if(sha.contentelements.cpShow) {
			dojo.addClass(dojo.byId(this.colFlexId), this.colFlexSmallClass);
			dojo.addClass(dojo.byId(this.flexFacettId), this.flexFacettSmallClass);
			dojo.publish(sha.EVT_SHOWCP);
		}
	},
	startContentPane: function(){
		dojo.byId(this.startCnt).innerHTML = "";
		dojo.style(dojo.byId(this.startCnt),"display","none");
		dojo.publish(sha.EVT_SHOWCP);
	},
	reposElems: function(){
		dojo.publish(sha.EVT_REPOSELEM);
	},
	rowManager: {
		pElemId: "",
		pElem: null,
		counter: 0,
		clone: null,
		init: function(obj){
			for(var i in obj){
				this[i] = obj[i];
			}
			this.pElem = dojo.byId(this.pElemId);
			
		},
		addRow: function(){
			if(this.pElem) {
				var lis = dojo.query("LI",this.pElem);
				this.counter = lis.length;
				this.clone = lis[this.counter-1].cloneNode(true);
				var inputs = dojo.query("INPUT",this.clone);
				for(var i = 0;i<inputs.length;i++){
					if(inputs[i].id != ""){
						inputs[i].id = inputs[i].name.substring(0,inputs[i].id.length-1)+this.counter;
						inputs[i].name = inputs[i].id;
						inputs[i].value = "";
					}
				}
				this.pElem.appendChild(this.clone);
				dojo.publish(sha.EVT_REPOSELEM);
			}
		}
	}
}
// content pane
/**
 * @classDescription Define ContentPane
 * 
 */
dojo.declare("sha.contentelements.contentpane", null, {
	actionUri: "", // URI to send xmlhttprequests
	nodeId: "", // DOM node id of element to be used as contentpane
	node:"", // DOM node of contentpane
	contentHeight:"",
	replaceSifr:false, // defines whether headlines within content pane are replaced by sIFR
	showLoadMsg:false, // defines whether a loading message within the content pane is displayed
	redrawShadows:false, // defines whether shadows are redrawn within contentpane on content change
	customEventTriggered:false, // defines whether content pane listens to custom event
	shadowElements: new Array(), // contains all shadowed elements within the content pane
	loadFunc: "", // defines a function within sha.contentelements, which is connected to content pane onload event
	showOnLoad: false, // defines whether to execute the show function on content pane onload
	
	/**
	 * initialization of content pane
	 * @param {Object} obj: configuration settings for content pane, i.e.
	 * 						{nodeId:"sha_col_cnt", replaceSifr:true, customEventTriggered:true, redrawShadows:true}
	 */
	constructor: function(obj) {
		dojo.mixin(this, obj);
		this.cp = new dojox.layout.ContentPane({
			id: this.nodeId,
			href: this.actionUri,
			executeScripts: true
		},dojo.byId(this.nodeId));
		if(this.replaceSifr && !this.showOnLoad) {
			dojo.connect(this.cp, "onLoad", sha.sifrReplacement, "run");
		}
		if(this.redrawShadows && dojo.isIE){
			dojo.connect(this.cp, "onLoad", this, "drawShadows");
		}
		if(this.loadFunc){
			dojo.connect(this.cp, "onLoad", sha.contentelements, this.loadFunc);
		}
		dojo.connect(this.cp, "onDownloadError", sha.contentelements, "reposElems");
		if(this.showLoadMsg)
			this.cp.onDownloadStart = this.showLoadingImage;
		else
			this.cp.onDownloadStart = this.preventLoadingMessage;
		if(this.customEventTriggered) dojo.subscribe(sha.EVT_UPDCP, this, this.updateContent);
		if(this.showOnLoad) dojo.subscribe(sha.EVT_SHOWCP, this, this.show);
		dojo.connect(this.cp, "onLoad", this, "exLoadedFunc");
		
	},
	
	/**
	 * displays a loading image for content pane
	 */
	showLoadingImage: function(){
		if (dojo.isIE)
			return('<div style="text-align:center; padding:20px; background-color:#fff;"><p>' +sha.cp_load_text +'</p></div>');
		else
			return('<div style="text-align:center; padding:20px; background-color:#fff;"><img alt="' +sha.cp_load_text +'" src="' +sha.imgpath_load +'" style="text-align:center;" /></div>');
	},
	/**
	 * prevents display of dojo standard loading message for content pane
	 */
	preventLoadingMessage: function(){
		return("");
	},
	
	/**
	 * tries to run an external loaded javascript function after 
	 * loading the content pane if existing 
	 */
	exLoadedFunc: function(){
		try{ 
			if(shaCPExLoadFunc){
				shaCPExLoadFunc.init();
			}
		}catch(e){}
	},
	
	/**
	 * loading new content to content pane, managing shadows within
	 */
	updateContent: function(uri){
		if(this.redrawShadows){
			for(var i=0;i<this.shadowElements.length;i++){
				sha.shadowManager.removeShadowObject(this.shadowElements[i]);
			}
			this.shadowElements = new Array();
		}
		this.actionUri = uri;
		this.cp.cancel();
		this.cp.setHref(this.actionUri);
	},
	
	/**
	 * wrapper for passing 2 parameters from 2 dependent dropdowns
	 * parameter JSON syntax:
	 * 
	 * @param(obj)
	 * 	uri: URL AJAX request
	 * 	key: the key value in the URL query
	 * 	id: id of the <select> element to read the selected value and pass it within the query
	 * 
	 * instancename.updateContentWrapper({
	 * 	'uri':'/sharp_static_html/ajax/serversim.jsp',
	 * 	'keyvals':[
	 * 		{'key':'command', 'id':'sha_supp_3'},
	 * 		{'key':'command2', 'id':'sha_supp_4'}
	 * 	]
	 * });
	 */
	updateContentWrapper: function(obj) {
		var s = "";
		for(var i=0; i<obj.keyvals.length; i++) {
			s += obj.keyvals[i].key;
			s+= "=";
			s += dojo.byId(obj.keyvals[i].id).value;
			if(i<obj.keyvals.length-1) s+="&";
		}
		var sp = (obj.uri.indexOf("?") == -1) ? "?" : "&"; // already parameters in URI? then just add with "&"
		this.updateContent(obj.uri +""+ sp +""+ s);
	},
	
	/**
	 * repainting the shadowed container within content pane
	 */
	drawShadows: function(){
		var shadowObjects = dojo.query(".sha_dropshadow", this.nodeId);
		for(var i=0;i<shadowObjects.length;i++){
			shadowObjects[i].id = this.nodeId +"_sh_" +i;
			this.shadowElements.push(shadowObjects[i].id);
		}
		if(shadowObjects.length>0) sha.shadowManager.createShadowBoxes({boxes:shadowObjects});
		if(!this.showOnLoad) dojo.publish(sha.EVT_REPOSELEM);
	},
	/**
	 * showing content pane on screen
	 */
	show:function(){
		dojo.removeClass(this.cp.domNode, sha.contentelements.hideClass);
		this.replaceSifr ? sha.sifrReplacement.run() : window.setTimeout("sha.contentelements.reposElems()",200);
	}
});

/**
 * @classDescription Define TabContainer (not the dojo one, but own construction with ul/li elements)
 * 
 * @param {Array} tabNodes: all LI elements of the parent dom node
 * @param {Array} tabs: all managed tab objects of the tab container
 * @param {Tab Object} activeTab: the currently selected (active) tab element
 * @param {domnode} pNode: parent node ID containing the LI tabs
 */
dojo.declare("sha.contentelements.tabcontainer", null, {
	tabNodes:[],
	tabs: [],
	activeTab: "",
	pNodeId: "",
	redrawSifr: false,
	
	/**
	 * Initializes the Tab Container (Manager), building Tab Objects out of given IDs, activating the first one and subscribing to listen on changes
	 * @param {Object} obj - all parameters for building the Tab Container, i.e. {pNodeId:"sha_tab_bar",actClass:"sha_act"}
	 */
	constructor: function(obj) {
		if(obj.pNodeId){
			dojo.mixin(this, obj);
			this.tabNodes = dojo.query("LI",this.pNodeId);
			if(this.tabNodes.length>0){
				var i = 0;
				var activated = false;
				for(var i=0;i<this.tabNodes.length;i++){
					this.generateTab(this.tabNodes[i].id,obj.actClass);
					if(!activated && dojo.hasClass(this.tabNodes[i],obj.actClass)){
						this.activeTab = this.tabs[this.tabNodes[i].id];
						activated = true;
					}
					dojo.removeClass(this.tabNodes[i],obj.actClass);
				}
				this.activeTab.activate({redrawSifr:this.redrawSifr});
			}
			dojo.subscribe(sha.EVT_SWTAB, this, this.changeTab);
		}
	},
	/**
	 * Building a Tab Object out of given ID
	 * @param {String} tabId - HTML id of tab element
	 */
	generateTab: function(tabId,actClass){
		node = dojo.byId(tabId);
		this.tabs[tabId] = new sha.contentelements.tab({id:tabId, pane:tabId+"_cnt", parentContainer:this, domNode:node, actClass:actClass});
	},
	/**
	 * Switching the active Tab Object
	 * @param {String} tabId - HTML id of tab element to activate
	 */
	changeTab: function(id){
		this.activeTab.deactivate();
		this.tabs[id].activate({redrawSifr:this.redrawSifr});
		this.activeTab = this.tabs[id];
	}
});

/**
 * @classDescription Define Tab for use with Tab Container (not the dojo one, but own construction with ul/li elements)
 * 
 * @param {String} id: id of the Tab Object
 * @param {domnode} pane: content element connected to the Tab, displayed when Tab is activated
 * @param {domnode} domNode: HTML node of the Tab, usually a LI element
 * @param {String} actClass: CSS class name for highlighting the active tab
 * @param {boolean} loaded: indicates whether the tab is already loaded or not
 * @param {String} cpClass: CSS class name that indicates that it's an Ajax Tab
 * @param {String} cpUri: URI for Ajax Request
 * @param {boolean} isCp: indicates whether the tab can be loaded via Ajax
 * @param {dojox.layout.ContentPane} cp: ContentPane loading Tab content
 */
dojo.declare("sha.contentelements.tab", null, {
	id:"",
	pane:"",
	domNode:"",
	actClass:"",
	loaded:false,
	cpClass:"sha_cp_tab",
	cpUri:"#",
	isCp:false,
	cp:"",
	
	/**
	 * Initializes a Tab Object, setting its onclick behaviour and hiding the associated content
	 * @param {Object} obj - all parameters for building the Tab Container, i.e. {tabIds:["sha_tab_desc","sha_tab_tec","sha_tab_tests"]}
	 */
	constructor: function(obj) {
		
		dojo.mixin(this, obj);
		this.pane = dojo.byId(obj.pane);
		dojo.connect(this.domNode, "onclick", this , "onClick");
		if(dojo.hasClass(this.domNode,this.cpClass)){
			this.cpUri = dojo.query("a",this.domNode)[0].href;
			if(this.cpUri!=window.location.href && this.cpUri != window.location.href+"#"){
				this.cp = new sha.contentelements.contentpane({nodeId:obj.pane, replaceSifr:true, showLoadMsg:true, redrawShadows:true, loadFunc:"reposElems"});
				this.isCp = true;
			}
		} 
		
		// print.css defines attribute {background-repeat:no-repeat}, indicates to show in printview
		var s = dojo.style(this.pane, 'backgroundRepeat');
		if(s!="no-repeat") dojo.style(this.pane, "display", "none"); // hides only if not in printview
	},
	/**
	 * Activates a Tab Object by assigning highlight class, showing associated content and repositioning shadows
	 * @param {Object} obj - i.e. {redrawSifr:true} to update sIFR headlines on tab switch
	 */
	activate: function(obj){
		
		dojo.addClass(this.domNode,this.actClass);
		dojo.style(this.pane, "display", "block");
		if(this.isCp && !this.loaded){
			this.cp.updateContent(this.cpUri);
			this.loaded = true;
		}
		if(obj.redrawSifr) sha.sifrReplacement.run();
		else dojo.publish(sha.EVT_REPOSELEM);
	},
	/**
	 * Deactivates a Tab Object by removing highlight class and hiding associated content
	 */
	deactivate: function(){
		dojo.style(this.pane, "display", "none");
		dojo.removeClass(this.domNode,this.actClass);
	},
	/**
	 * Event Handler for Tab Object Clicks, notifying Tab Container to manage switch and preventing link persecution
	 * @param {Event} evt - Mouse Click event on Tab Link
	 */
	onClick: function(evt){
		dojo.stopEvent(evt);
		dojo.publish(sha.EVT_SWTAB,new Array(this.id));
	}
});

sha.contentelements.shaWindowMgr = {
	devHeight: 245,
	devWidth: 446, 
	actHeight: null,
	actWidth: null,
	windowRef:null,
	
	/**
	 * opens a given url within a new browser window
	 * @param {Object} obj - containing parameters like url and window size
	 */
	openWindow: function(obj){
		this.actHeight = obj.height ? obj.height : this.devHeight;
		this.actWidth = obj.width ? obj.width : this.devWidth;
		
		if( obj.url!='' ){
			windowRef = window.open( obj.url, "shaWindowOpner", "width="+this.actWidth+",height="+this.actHeight+",scrollbars=no,location=no,toolbar=no,status=1,status=yes,resizable=1,resizable=yes" );
			windowRef.focus();
		}
	}
	
}

/**
 * @classDescription Define a Modal Dialog element for large image display
 * 
 * @param {String} id: id of the Link Object calling the modal dialog
 * @param {dijit.Dialog} md: dijit.Dialog object
 * @param {String} title: title to display in the headline of the modal dialog
 * @param {boolean} closable: determines whether the dialog contains a close  button or not
 * @param {String} hoverClass: className for hover on close button
 * @param {String} templateString: HTML stub for the modal dialog
 * @param {String} mdSuffix: suffix for modal dialog to generate its ID
 * @param {boolean} initialized: indicates whether the dialog is already built
 * @param {String} closeText: text to be displayed as close button for dialog
 */
sha.contentelements.modal = {
	id:"sha_md_01",
	md: null,
	actionUri: "", // URI to send xmlhttprequests, 
	title:"",
	closable: true,
	hoverClass: "dijitDialogCloseIconHover",
	templateString:'<div class="dijitDialog"><div dojoAttachPoint="titleBar" class="dijitDialogTitleBar" tabindex="0" waiRole="dialog"><span dojoAttachPoint="titleNode" class="dijitDialogTitle">${title}</span><span dojoAttachPoint="closeButtonNode" class="dijitDialogCloseIcon" dojoAttachEvent="onclick: hide"><span dojoAttachPoint="closeText" class="closeText">close</span></span></div><div dojoAttachPoint="containerNode" class="dijitDialogPaneContent"></div><span dojoAttachPoint="tabEnd" dojoAttachEvent="onfocus:_cycleFocus" tabindex="0"></span></div>',
	initialized: false,
	closeText: "close",
	
	/**
	 * Displays the modal dialog (closing is handled by the dojo widget internally)
	 * @param {Object} obj - containing parameters for ajax call, necessary are 'href' and 'id'
	 */
	display: function(obj) {
		this.actionUri = obj.getAttribute("href") ? obj.getAttribute("href") : this.actionUri;
		this.title = obj.getAttribute("_title") ? obj.getAttribute("_title") : this.title;
		if(!this.initialized){
			this.closeText =  obj.getAttribute("_closetext") ? obj.getAttribute("_closetext") : this.closeText;
			var _mdNode = document.createElement("div");
			_mdNode.setAttribute("id",this.id);
			dojo.body().appendChild(_mdNode);
			this.md = new sha.contentelements.Dialog({title: this.title, closable: this.closable, templateString: this.templateString},dojo.byId(this.id));
			this.md.closeText.firstChild.nodeValue = this.closeText;
			this.md.closeButtonNode.parent = this;
			this.md.closeButtonNode.onmouseover = function(){dojo.addClass(this,this.parent.hoverClass)};
			this.md.closeButtonNode.onmouseout = function(){dojo.removeClass(this,this.parent.hoverClass)};
			dojo.connect(this.md, "hide", this , "clear");
			this.md.startup();
			this.initialized = true;
		}
		this.md.titleNode.innerHTML = this.title;
		this.md.setHref(this.actionUri);
		this.md.show();
		
		this.shaPositionHandler();
	},
	
	/**
	 * forces the dialog to relayout itself
	 */
	shaPositionHandler: function(){
		window.setTimeout(function(){
			var res = dojo.query("div.dijitDialogPaneContent img")[0];
			if( res ){
				if( res.complete ){
					sha.contentelements.modal.md.layout();
					if( parseInt( sha.contentelements.modal.md.domNode.style.top )<0 ) sha.contentelements.modal.md.domNode.style.top = '10px'; 
				}else{
					dojo.connect( res, "onload", this, function(){
						sha.contentelements.modal.md.layout();
						if( parseInt( sha.contentelements.modal.md.domNode.style.top )<0 ) sha.contentelements.modal.md.domNode.style.top = '10px'; 
					});
				}
				dojo.connect( res, "onclick", this, function(){
					sha.contentelements.modal.md.hide();
				});
			}
		},500);
	},
	
	/**
	 * Removes content of the modal dialog (needed to stop flash films i.e. with sound in IE)
	 */
	clear: function() {
		window.setTimeout(function(){
			sha.contentelements.modal.md.containerNode.innerHTML = "";
		},500);
	}
}
sha.contentelements.tooltip = {
	tt: null,
	ttId:"",
	ttCloseHoverClass: "",
	ttShdNodeId: "",
	ttHdlNodeId: "",
	ttTextNodeId: "",
	ttCloseNodeId: "",
	ttCloseNode: null,
	ttShadowed: false,
	ttFramed: false,
	ttIfr: null,
	getEvt: null,
	viewPort:null,
	ttWidth:300,
	ttRMargin:25,
	
	/**
	 * Sets the id's and classes needed to handle tooltip "widget"
	 * @param {Object} obj - attributes needed: ttId: id of main tooltip container replaced by content pane, ttShdNodeId: id of shadowed container, ttHdlNodeId: headline node id, ttTextNodeId: textblock id,
	 * 	ttCloseNodeId: id of closing element, ttCloseHoverClass: class to add on close element hover
	 */
	defineNodes: function(obj){
		for(var i in obj){
			this[i] = obj[i];
		}
	},
	/**
	 * Initializes the tooltip creating the content pane
	 */
	init: function(){
		this.tt = new sha.contentelements.contentpane({nodeId:this.ttId, actionUri:"", redrawShadows:true, showLoadMsg:false});
		dojo.connect(this.tt.cp, "onLoad", this, "setBehavior");
		if(dojo.byId(sha.contentelements.flexFacettId)) dojo.connect(this, "displayFrFlex", this, "setBehavior");
		// hide tooltips when loading new products
		this.getEvt = dojo.subscribe(sha.EVT_GETCONTENT, this, this.hide);
		// hide tooltip when go back to productlist
		this.getEvt = dojo.subscribe(sha.EVT_BACKTOPRODLSTDETL, this, this.hide); //#252
	},
	/**
	 * Displays the tooltip box with updated content via ajax
	 * @param {Object} obj - attributes needed: href as complete URL with parameter, object itself must be a domnode to get its position
	 */
	display: function(obj) {
		this.ttFramed = false;
		this.tt.updateContent(obj.href);
		if(obj.xpos != null){
			this.flexCoords = dojo.coords(sha.contentelements.flexFacettId,true);
			obj.pos = {x:obj.xpos +this.flexCoords.x, y:obj.ypos +this.flexCoords.y};
		} else {
			obj.pos = dojo.coords(obj,true);
			if( dojo.isIE ){ // pos swap img #80
				obj.pos.y += 145;
			}
		}
		
		this.viewPort = dijit.getViewport();
		if( (obj.pos.x+this.ttWidth+this.ttRMargin)>this.viewPort.w  ){ // pos #80
			obj.pos.x = this.viewPort.w - (this.ttWidth+this.ttRMargin);
		}
		
		dojo.style(this.tt.cp.domNode,"left",obj.pos.x+15+"px");
		dojo.style(this.tt.cp.domNode,"top",obj.pos.y+15+"px");
		dojo.removeClass(this.tt.cp.domNode,sha.contentelements.hideClass);
		if(!this.ttShadowed) this.ttShadowed = true;
	},
	/**
	 * Displays the tooltip box with updated content via flex
	 * @param {Object} obj - attributes: headline, text, xpos, ypos
	 */
	displayFrFlex: function(obj) {
		
		if(!dojo.byId(sha.contentelements.flexFacettId)) return;
		dojo.byId(this.ttHdlNodeId).innerHTML = obj.headline;
		dojo.byId(this.ttTextNodeId).innerHTML = obj.text;
		if(!this.ttShadowed){
			dojo.addClass(dojo.byId(this.ttShdNodeId),sha.contentelements.shadowClass);
			this.tt.drawShadows();
			this.ttShadowed = true;
		}
		this.flexCoords = dojo.coords(sha.contentelements.flexFacettId,true);
		
		obj.xpos = obj.xpos +this.flexCoords.x;
		obj.ypos = obj.ypos +this.flexCoords.y;
		
		this.viewPort = dijit.getViewport();
		if( (obj.xpos+this.ttWidth+this.ttRMargin)>this.viewPort.w ){ // pos #80
			obj.xpos = this.viewPort.w - (this.ttWidth+this.ttRMargin);
		}
		
		dojo.style(this.tt.cp.domNode,"left",obj.xpos+15+"px");
		dojo.style(this.tt.cp.domNode,"top",obj.ypos+15+"px");
		dojo.removeClass(this.tt.cp.domNode,sha.contentelements.hideClass);
	},
	/**
	 * Add hover class for close button
	 */
	addTtHoverClass: function(){
		dojo.addClass(this.ttCloseNode, this.ttCloseHoverClass);
	},
	/**
	 * Remove hover class for close button
	 */
	removeTtHoverClass: function(){
		dojo.removeClass(this.ttCloseNode, this.ttCloseHoverClass);
	},
	/**
	 * Close tooltip
	 */
	hide: function(){
		dojo.addClass(this.tt.nodeId, sha.contentelements.hideClass);
	},
	/**
	 * Add functionality for close button and protecting iframe for IE6
	 */
	setBehavior: function(){
		this.ttCloseNode = dojo.byId(this.ttCloseNodeId);
		dojo.connect(this.ttCloseNode,"onmouseover",this,"addTtHoverClass");
		dojo.connect(this.ttCloseNode,"onmouseout",this,"removeTtHoverClass");
		dojo.connect(this.ttCloseNode,"onclick",this,"hide");
		if(dojo.isIE && dojo.isIE<7 && !this.ttFramed){
			this.ttIfr = new dijit.BackgroundIframe(this.tt.cp.domNode);
			this.ttIfr.iframe.style.setExpression("width", "dojo.doc.getElementById('" + this.tt.nodeId + "').offsetWidth +4");
			this.ttIfr.iframe.style.setExpression("height", "dojo.doc.getElementById('" + this.tt.nodeId + "').offsetHeight -6");
			this.ttFramed = true;
		}
		dojo.publish(sha.EVT_REPOSELEM);
	}
}
sha.contentelements.imageSwitcher = {
	images: new Array(),
	imgMidId: "sha_prod_img_mid",
	imgMidLink: null,
	imgMidContainer: null,
	imgSmallContainerClass: "sha_prod_imgs_sm",
	pointer:"",
	templateNode: null,
	templateNodeClass: "sha_prod_img_sm",
	templateANodeClass: "sha_prod_img_sm",
	largeImageLinkId: "sha_large_image_link",
	loadingClass: "sha_load",
	loadingMessage: "Loading...",
	imgSmallLst: new Array(),
	counter:0,
	maxItems:3,
	itemCount:0,
	
	countItem: function( arr ){
		this.itemCount = 0;
		for(var i=0; i<arr.length; i++){
			if(arr[i]) this.itemCount++;
		}
	},
	
	init: function(prodImgs){
		this.countItem(prodImgs);
		this.imgSmallContainer = dojo.query("."+this.imgSmallContainerClass)[0];
		this.imgMid = dojo.byId(this.imgMidId);
		this.imgMidLink = this.imgMid.parentNode;
		this.largeImageLink = dojo.byId(this.largeImageLinkId);
		if(this.imgSmallContainer){
			this.imgMidContainer = this.imgMid.parentNode.parentNode;
			this.imgMid.parent = this;
			this.imgMid.onload = function(evt){
				dojo.stopEvent(evt);
				dojo.addClass(this.parent.templateLNode, sha.contentelements.hideClass);
				dojo.style(this.parent.templateLNode,"left","");
				dojo.style(this.parent.templateLNode,"top","");
				dojo.style(this.parent.imgMidContainer,"height","");
			};
			this.templateLNode = document.createElement("div");
			dojo.addClass(this.templateLNode, this.loadingClass);
			dojo.addClass(this.templateLNode, sha.contentelements.hideClass);
			this.templateLNode.innerHTML = this.loadingMessage;
			this.imgMidContainer.appendChild(this.templateLNode);
			this.counter=0;
			dojo.forEach(prodImgs, function(bundle) {
				if(bundle){
					this.templateNode = document.createElement("div");
					if(this.counter>=this.maxItems) dojo.style(this.templateNode,'display','none');
					dojo.addClass(this.templateNode, this.templateNodeClass);
					this.templateANode = document.createElement("a");
					this.templateANode.setAttribute("href",bundle.small);
					this.templateANode.parent = bundle;
					this.templateANode.onclick = function(evt){
						dojo.stopEvent(evt);
						sha.contentelements.imageSwitcher.setImages(this.parent);
					};
					this.templateINode = document.createElement("img");
					this.templateINode.setAttribute("alt",bundle.alt);
					this.templateINode.setAttribute("src",bundle.small);
					this.templateANode.appendChild(this.templateINode);
					this.templateNode.appendChild(this.templateANode);
					this.imgSmallContainer.appendChild(this.templateNode);
					bundle.node = this.templateNode;
					this.imgSmallLst.push( this.templateNode );
					this.counter++;
				}
			},this);
		}
	},
	setImages: function(bundle){
		for(i=0; i<this.imgSmallLst.length; i++ ){
			if(this.imgSmallLst[i]) dojo.style(this.imgSmallLst[i],'display','');
		}
		if(this.itemCount>this.maxItems) dojo.style(bundle.node,'display','none');
		var tlDimensions = dojo.coords(this.imgMidContainer,true);
		dojo.style(this.imgMidContainer,"height",tlDimensions.h +"px");
		dojo.style(this.templateLNode,"height",tlDimensions.h +"px");
		dojo.style(this.templateLNode,"width",tlDimensions.w +"px");
		dojo.style(this.templateLNode,"left","0");
		dojo.style(this.templateLNode,"top","0");
		dojo.removeClass(this.templateLNode, sha.contentelements.hideClass);
		this.imgMid.setAttribute("src",bundle.mid);
		if(this.imgMidLink.tagName == "A"){
			this.imgMidLink.setAttribute("href",bundle.large);
			this.imgMidLink.setAttribute("_title",bundle.desc);
			this.imgMidLink.parent = bundle;
			this.largeImageLink.parent = this;
			this.largeImageLink.setAttribute("href",bundle.large);
			this.largeImageLink.onclick = function(evt){
				dojo.stopEvent(evt);
				sha.contentelements.modal.display(this);
			};
			this.imgMidLink.onclick = function(evt){
				dojo.stopEvent(evt);
				sha.contentelements.modal.display(this);
			};
		}
	}
}

/**
 * @classDescription Define a checkbox manager to handle a set of checkboxes and their dependencies on a master checkbox
 * 
 * @param {String} id: id of the parent dom node containing all checkboxes
 * @param {domNode} domNode: node of the parent element
 * @param {Array} boxes: all checkboxes (dom nodes) within parent dom node
 * @param {Array} boxObjects: all managed checkbox Objects (without master box) of type sha.contentelements.checkbox
 * @param {String} masterBoxId: id of the master checkbox
 * @param {domNode} masterBox: the master checkbox
 * @param {int} count: counter for active boxes
 */
dojo.declare("sha.contentelements.checkboxManager", null, {
	id:"",
	domNode:"",
	boxes: null,
	boxObjects: [],
	masterBoxId: "",
	masterBox: null,
	count: 0,
	checkedCount: 0,
	
	constructor: function(obj) {
		dojo.mixin(this, obj);
		if(!this.id || !this.masterBoxId) return false;
		this.domNode = dojo.byId(this.id);
		this.masterBox = dojo.byId(this.masterBoxId);
		this.boxes = dojo.query('input[type="checkbox"]',this.domNode);
		this.boxObjects = new Array();
		this.count = 0;
		// create checkbox object for each checkbox, filtering out the master checkbox
		if(this.boxes.length>0){
			var i,j = 0;
			for(var i=0;i<this.boxes.length;i++){
				if(this.boxes[i].id != this.masterBoxId){
					this.boxObjects[j] = new sha.contentelements.checkbox({domNode: this.boxes[i], active: this.boxes[i].getAttribute("checked") ? true : false, manager: this});
					if(this.boxObjects[j].active) this.count++;
					j++;
				}
			}
		}
		// defining behavior of master checkbox
		dojo.connect(this.masterBox, "onclick", this , "checkActivation");
		dojo.connect(this.masterBox, "onkeypress", this , "checkActivation");
		this.boxes = null;
	},
	/**
	 * Check state of master checkbox and trigger depending action
	 * @param {Event} evt: DOM event passed
	 */
	checkActivation: function(evt){
		(this.masterBox.checked) ? this.handleAll({activate:true, evt:evt}) : this.handleAll({activate:false, evt:evt});
	},
	/**
	 * Increases amount of active checkboxes and checks master checkbox if all single ones are checked
	 */
	addActive: function(){
		this.count += 1;
		if(this.count == this.boxObjects.length){
			this.masterBox.checked = true;
		}
	},
	/**
	 * Decreases amount of active checkboxes and unchecks master checkbox
	 */
	removeActive: function(){
		this.count -= 1;
		this.masterBox.checked = false;
	},
	/**
	 * Iterates over all checkboxes setting each state
	 * @param {Object} obj: attributes: countActive - defines whether active checkbox counter is updated or not
	 */
	handleAll: function(obj){
		(obj.activate) ? this.count = this.boxObjects.length : this.count = 0;
		for(var i=0;i<this.boxObjects.length;i++){
			(obj.activate) ? this.boxObjects[i].activate({countActive:false}) : this.boxObjects[i].deactivate({countActive:false});
		}
	}
});

/**
 * @classDescription Define a checkbox object able to be managed by a checkbox manager
 * 
 * @param {domNode} domNode: checkbox element node
 * @param {sha.contentelements.checkboxManager} manager: the manager of the set this box belongs to
 * @param {boolean} active: current state of the checkbox - active if checkbox is checked
 */
dojo.declare("sha.contentelements.checkbox", null, {
	domNode: null,
	manager: null,
	active: false,
	
	constructor: function(obj) {
		dojo.mixin(this, obj);
		dojo.connect(this.domNode, "onclick", this , "toggleState");
		dojo.connect(this.domNode, "onkeypress", this , "toggleState");
	},
	/**
	 * Iterates over all checkboxes setting each state
	 * @param {Event} evt: DOM event passed
	 */
	toggleState: function(evt){
		if(this.domNode.checked && !this.active) {
			this.activate({countActive:true});
		} else if(!this.domNode.checked && this.active){
			this.deactivate({countActive:true});
		}
	},
	/**
	 * Checks a checkbox and can update manager counter
	 * @param {Object} obj: attributes: countActive - defines whether active checkbox counter is updated or not
	 */
	activate: function(obj){
		if(obj.countActive) this.manager.addActive();
		this.domNode.checked = true;
		this.active = true;
	},
	/**
	 * Unchecks a checkbox and can update manager counter
	 * @param {Object} obj: attributes: countActive - defines whether active checkbox counter is updated or not
	 */
	deactivate: function(obj){
		if(obj.countActive) this.manager.removeActive();
		this.domNode.checked = false;
		this.active = false;
	}
});
dojo.declare("sha.contentelements.validator", null, {
	formId:null,
	messageBoxId:null,
	formProfile : null,
	scrollToError:true,
	errorClass:"sha_error",
	
	constructor: function(p) {
		dojo.mixin(this, p);
	},
	validate: function() {
		var f = dojo.byId(this.formId);
		if (!f) return false;
		var results = dojox.validate.check(f, this.formProfile);
		var oldErrors = dojo.query("."+this.errorClass,f);
		dojo.forEach(oldErrors, function(field) {
			dojo.removeClass(field,this.errorClass);
		},this);
		if (!this._processResults(f, results, this.formProfile)) {
			this._summarizeErrors(f, results, this.formProfile);
		} else {
			this._clearMessage();
			f.submit();
		}
	},
	validate_clear: function() {
		var f = dojo.byId(this.formId);
		if (!f) return false;
		var results = dojox.validate.check(f, this.formProfile);
		var oldErrors = dojo.query("."+this.errorClass,f);
		dojo.forEach(oldErrors, function(field) {
			dojo.removeClass(field,this.errorClass);
		},this);
		if (!this._processResults(f, results, this.formProfile)) {
			this._summarizeErrors(f, results, this.formProfile);
		} else {
			this._clearMessage();
			sha.contentelements.modal.md.hide();
			sha.contentelements.modal.clear(); 
			f.submit();
		}
	},
	_processResults: function(f, r, profile) {
		if (r.isSuccessful()) return true;
		if (r.hasMissing) {
			var fields = r.getMissing();
			var queryString = "";
			dojo.forEach(fields, function(field) {
				if( dojo.byId(field) ){
					dojo.addClass(dojo.byId(field),this.errorClass);
					queryString = "label[for="+field+"]";
					if( dojo.query(queryString,f).length ){
						dojo.addClass(dojo.query(queryString,f)[0],this.errorClass);
					}
				}
			},this);
		}
		if (r.hasInvalid) {
			var fields = r.getInvalid();
			dojo.forEach(fields, function(field) {
				if( dojo.byId(field) ){
					dojo.addClass(dojo.byId(field),this.errorClass);
					queryString = "label[for="+field+"]";
					if( dojo.query(queryString,f).length ){
						dojo.addClass(dojo.query(queryString,f)[0],this.errorClass);
					}
				}
			},this);
		}
		return false;
	},
	_summarizeErrors: function(f, r, p) {
		var merrs=[];
		var ierrs=[];
		if (r.hasMissing()){
			if (p.singleRequiredMissingMessage) {
				merrs.push(p.singleRequiredMissingMessage);
			} else { 
				var fields=r.getMissing();
				for (var i=0; i<fields.length; i++){
					if (p[fields[i]] && p[fields[i]]["required"]){
						if (dojo.isArray(p[fields[i]]["required"])) {
							for (var z=0; z < p[fields[i]]["required"].length; z++)
								merrs.push(p[fields[i]]["required"][z]);
						} else
							merrs.push(p[fields[i]]["required"]);
					}
				}
			}
		}
		if (r.hasInvalid()){
			var fields=r.getInvalid();
			for (var i=0; i<fields.length; i++){
				if (p[fields[i]] && p[fields[i]]["constraints"]){
					if (dojo.isArray(p[fields[i]]["constraints"])) {
						for (var z=0; z < p[fields[i]]["constraints"].length; z++)
							ierrs.push(p[fields[i]]["constraints"][z]);
					} else
						ierrs.push(p[fields[i]]["constraints"]);
				}
			}
		}
		
		var msg="";
		if (merrs.length > 0) {
			msg+='<ul class="missingList">';
			for (var i=0; i<merrs.length;i++) {
				msg+="<li>"+merrs[i]+"</li>";
			}
			msg+="</ul>";
		}
		if (ierrs.length > 0) {
			msg+='<ul class="invalidList">';
			for (var i=0; i<ierrs.length;i++) {
				msg+="<li>"+ierrs[i]+"</li>";
			}
			msg+="</ul>";
		}
		this._showMessage(msg);
	},
	_showMessage: function(msg) {
		var msgBox = dojo.byId(this.messageBoxId);
		if (msgBox) {
			if (dojo.isIE && dojo.isIE < 8) {
				var newdiv = document.createElement("span");
				newdiv.innerHTML = msg;
				if (msgBox.firstChild) {
					while(msgBox.firstChild) dojo._destroyElement(msgBox.firstChild);
				}
				msgBox.appendChild(newdiv);
			} else {
				msgBox.innerHTML = msg;
			}
			dojo.removeClass(dojo.byId(this.messageBoxId), sha.contentelements.hideClass);
			dojo.publish(sha.EVT_REPOSELEM);
			if (this.scrollToError) {
				var coords = dojo.coords(msgBox, true);
				window.scrollTo(0, coords.y - 20);
			}
		}
	},
	_clearMessage: function() {
		var msgBox = dojo.byId(this.messageBoxId);
		if (msgBox.tagName != "P" || msgBox.tagName != "p") {
			msgBox = msgBox.getElementsByTagName("P")[0];
		}
		if (msgBox) {
		//TODO: Externalize in generic message handler
			if (dojo.isIE && dojo.isIE < 7 && msgBox.firstChild) {
				while(msgBox.firstChild) dojo._destroyElement(msgBox.firstChild);
			} else {
				msgBox.innerHTML = "";
			}
			dojo.addClass(dojo.byId(this.messageBoxId), sha.contentelements.hideClass);
		}
	}
	
	
});
// Resizer for FLEX objects ========================================================
sha.resizeFlexContainer = {
	flaObj: new Object(), // the flash movie
	divObj: new Object(), // the holding DIV container
	evtObj: null,
	evtScroll: null,
	evtScrollToTop1: null,
	evtScrollToTop2: null,
	evtScrollToTop3: null,
	evtScrollToTop4: null,
	maxH: 2900, // maximum height of Flash MC, see http://www.thinkswedish.com/blog/fi/886/The_Flash_height_problem_and_how_to_solve_it
	minH: 280, // minimum height of the facet
	realH: 0, // real measured height of the list
	viewportHeight: 0, // height of viewport
	divObjTop: 0, // absolute ypos of FLEX layer
	
	init: function(obj) {
		this.flaObj = dojo.byId(obj.flaID);
		this.divObj = dojo.byId(obj.divID);
		
		if(!this.evtObj) {
			this.evtObj = dojo.subscribe(sha.EVT_RESIZE, this, this._calcHeight);
			
			// screen switch trigger scroll back to top
			this.evtScrollToTop1 = dojo.subscribe(sha.EVT_BACKTOPRODLSTFRCOMP, this, this._scrollToTop);
			this.evtScrollToTop2 = dojo.subscribe(sha.EVT_BACKTOPRODLSTDETL, this, this._scrollToTop);
			this.evtScrollToTop3 = dojo.subscribe(sha.EVT_STARTCOMPARELAYER, this, this._scrollToTop);
			this.evtScrollToTop4 = dojo.subscribe(sha.EVT_GETCONTENT, this, this._scrollToTop);
		}
	},
	
	_doit: function(h, w) {
		this.flaObj.style.height = h + "px"; // give the flashObj the height
		dojo.publish(sha.EVT_REPOSELEM); // reset the footer for IE6
	},
	
	_calcHeight: function(h, w) {
		dojo.disconnect(this.evtScroll);
		this.realH = h;
		this.viewportHeight = dijit.getViewport().h;
		this.divObjTop = dojo.coords(this.divObj, true).y;
		
		if(h > this.maxH) {
			this.flaObj.style.height = this.maxH + "px"; // give the flashObj the height
			this.evtScroll = dojo.connect(window, 'onscroll', this, this._verticalShift);
		}
		else if(h < this.minH) {
			this.flaObj.style.height = this.minH + "px"; // give the flashObj a minimum height
		}
		else {
			this.flaObj.style.height = this.realH + "px"; // give the flashObj the height
		}
		
		dojo.publish(sha.EVT_REPOSELEM); // reset the footer for IE6
		
		// fix for FLEX timer triggered drawing of boxes
		this._verticalShift();
	},
	
	_verticalShift: function() {		
		var a = dijit.getViewport().t;
		// var b = dijit.getViewport().h;
		// var c = dojo.coords(this.divObj, true).y; // start scrolling if top is out of viewport
		
		// top is still visible => do not shift
		if(a <= this.divObjTop) {
			dY = 0;
		}
		// linear shifting
		else if((a > this.divObjTop) && (a < (this.maxH - this.viewportHeight))) {
			// Geradengleichung: dY = y1 + (y2 - y1) / (x2 - x1) * (X - x1)
			var dY = (this.realH - this.maxH)/(this.maxH - this.viewportHeight - this.divObjTop) * (a - this.divObjTop);
			dY = Math.ceil(dY);
		}
		// bottom is visible, do not shift
		else if(a >= (this.maxH - this.viewportHeight)) {
			var dY = this.realH - this.maxH;
			dY = Math.ceil(dY);
		}
		
		// shift the MC, FLASH mc = ExternalInterface.call()
		this.flaObj.verticalShiftFunc(dY);
	},
	
	/*
	 * on screen switch from details view or compare view back to product list, scroll the viewport back to top
	 */
	_scrollToTop: function() {
		window.scrollTo(0,0); // scroll up to top
		dojo.publish(sha.EVT_REPOSELEM); // reset the footer for IE6
		this.flaObj.verticalShiftFunc(0); // trigger the flash to scroll back too
	}
}

// compare layer floating ================================================

/**
 * floating layer behaviour for compare layer, WT03, WT08
 */
sha.floatCompareLayer = {
	nodeID: null, // id of floating layer
	nodeObj: new Object(), // floating layer itself
	topObj: new Object(), // top corner for IE6-
	leftObj: new Object(), // left corner for IE6-
	parentObjTop: 0,
	nodeObjHeight: 100, // initial value
	offsetX: 19, // offset for shadow image
	hideX: -9999, // initial hide coord
	hideY: 0, // initial hide coord
	evtScroll: null,
	evtResize: null,
	evtResize2: null,
	prodListOpen: false,
	prodListClass: "sha_complayer_prodlist",
	
	/**
	 * initial init to create the layer
	 * called from template
	 * @param {Object} obj
	 */
	init: function(obj) {
		this.nodeID = obj.id;
		this.nodeObj = dojo.byId(this.nodeID);
		this.topObj = dojo.byId(obj.topID);
		this.leftObj = dojo.byId(obj.leftID);
		this.parentObjTop = dojo.coords(this.nodeObj.parentNode, true).y;
		//this.hideX = dojo.coords(this.nodeObj, true).x;
		//this.hideY = dojo.coords(this.nodeObj, true).y;
		
		/**
		 * set the node absolute at the end of body node to apply float behaviour
		 */
		if(!this.nodeObj.parentNode || String(this.nodeObj.parentNode.tagName).toLowerCase() != "body"){
			dojo.body().appendChild(this.nodeObj);
		}
		
		/**
		 * calc width with margin via JS as box model is wrong in CSS
		 * attach a resize event
		 */
		if((dojo.isIE && dojo.isIE <= 6) || dojo.isOpera) {
			this._calcWidth();
			this.evtResize2 = dojo.connect(window, 'onresize', this, this._calcWidth);
		}
		
		/**
		 * attach the alphaImageLoader to backgroundimages
		 */
		if(dojo.isIE <= 6) {
			dojo.style(this.topObj,"filter","progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+sha.complayerpath_top+"', sizingMethod='crop')");
			dojo.style(this.leftObj,"filter","progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+sha.complayerpath_left+"', sizingMethod='crop')");
		}
		
		/**
		 * register to the events fired from the FLEX object
		 */
		dojo.subscribe(sha.EVT_OPENCOMPARELAYER, this, this.initProdList);
		dojo.subscribe(sha.EVT_BACKTOPRODLSTFRCOMP, this, this.initProdList);
		dojo.subscribe(sha.EVT_BACKTOPRODLSTFRDETL, this, this.initProdList);
		dojo.subscribe(sha.EVT_CLOSECOMPARELAYER, this, this.closeCompareLayer);
		dojo.subscribe(sha.EVT_STARTCOMPARELAYER, this, this.initCompare);
		dojo.subscribe(sha.EVT_DETAILTOCOMPARE, this, this.initCompare);
		dojo.subscribe(sha.EVT_COMPARETODETAIL, this, this.initProdList);
		
		// mozilla bug FLASH obj to instanciate if not in viewport, TODO: try with MoBuKi
		if(dojo.isMozilla || dojo.isOpera) {
			this.initProdList();
			dojo.subscribe(sha.EVT_LOCCONSUBSCRIBER, this, this.closeCompareLayer);
		}
	},
	
	closeCompareLayer: function() {
		this._placeOnDoc({x:this.hideX, y:this.hideY});
		this.prodListOpen = false;
	},
	
	/**
	 * reInit to switch position method top/bottom
	 */
	initProdList: function() {
		// Layer already there? performance tweak
		if(this.prodListOpen) return;
		else this.prodListOpen = true;
		
		// reset the event listeners
		if(this.evtScroll) dojo.disconnect(this.evtScroll);
		if(this.evtResize) dojo.disconnect(this.evtResize);
		
		// set the background
		dojo.addClass(this.nodeObj, this.prodListClass);
		
		/**
		 * for IE6- only, does not know position:fixed
		 */
		if(dojo.isIE && dojo.isIE <= 6) {
			this.nodeObj.style.position = "absolute";
			
			this._placeIEbottom();
			this.evtScroll = dojo.connect(window, 'onscroll', this, this._placeIEbottom);
			this.evtResize = dojo.connect(window, 'onresize', this, this._placeIEbottom);
		}

		/**
		 * for all other browsers IE7+, FF, Opera, Safari
		 */
		else {
			this.nodeObj.style.position = "fixed";
			this._placeFFbottom();
			this.evtResize = dojo.connect(window, 'onresize', this, this._placeFFbottom);
		}
	},
	
	initCompare: function() {
		// no longer the prodlist
		this.prodListOpen = false;
		
		// reset the event listeners
		if(this.evtScroll) dojo.disconnect(this.evtScroll);
		if(this.evtResize) dojo.disconnect(this.evtResize);
		
		// set the background
		dojo.removeClass(this.nodeObj, this.prodListClass);
		
		/**
		 * for IE6- only, does not know position:fixed
		 */
		if(dojo.isIE && dojo.isIE <= 6) {
			this.nodeObj.style.position = "absolute";
			
			this._placeIEtop();
			this.evtScroll = dojo.connect(window, 'onscroll', this, this._placeIEtop);
			this.evtResize = dojo.connect(window, 'onresize', this, this._placeIEtop);
		}

		/**
		 * for all other browsers IE7+, FF, Opera, Safari
		 */
		else {
			this.nodeObj.style.position = "fixed";
			
			this._placeFFtop();
			this.evtScroll = dojo.connect(window, 'onscroll', this, this._placeFFtop);
			this.evtResize = dojo.connect(window, 'onresize', this, this._placeFFtop);
		}
	},
	
	/**
	 * Moz/FF/IE7/Opera top positioning
	 */
	_placeFFtop: function() {
		if(this._getViewPort().t < this.parentObjTop) {
			this._placeOnDoc({x:this.offsetX, y:this.parentObjTop - this._getViewPort().t}); // remember: pos:fixed
		}
		else {
			this.nodeObj.style.top = "0px";
		}
	},
	
	/**
	 * Moz/FF/IE7/Opera bottom positioning
	 */
	_placeFFbottom: function() {
		if(!this.prodListOpen) return;
		this._placeOnDoc({x:this.offsetX, y:this._getViewPort().h - this.nodeObjHeight}); // as pos=fixed take placeOnDoc
	},
	
	/**
	 * IE6- top positioning
	 */
	_placeIEtop: function() {
		if(this._getViewPort().t < this.parentObjTop) {
			this._placeOnDoc({x:this.offsetX, y:this.parentObjTop}); // pos:absolute
		}
		else {
			this._placeOnScreen({x:19, y:0});	
		}
	},
	
	/**
	 * IE6- bottom positioning
	 */
	_placeIEbottom: function() {
		if(!this.prodListOpen) return;
		this._placeOnScreen({x:this.offsetX, y:this._getViewPort().h - this.nodeObjHeight});
	},
	
	/**
	 * function based on dijit.placeOnScreen in dojo/dijit/_base/place.js
	 * place it on the viewport
	 * @param {Object} obj
	 */
	_placeOnScreen: function(obj) {
		var _x = obj.x;
		var _y = obj.y;
		
		// place the node element
		this.nodeObj.style.left = (this._getViewPort().l + _x) + "px";
		this.nodeObj.style.top = (this._getViewPort().t + _y) + "px";
	},
	
	/**
	 * place it on the document itself (nearly like position:absolute behaviour
	 * but simulated here with position fixed due to switch position fixed/absolute bug in FF flash reInit
	 * @param {Object} obj
	 */
	_placeOnDoc: function(obj) {
		var _x = obj.x;
		var _y = obj.y;
		
		// place the node element
		this.nodeObj.style.left = _x + "px";
		this.nodeObj.style.top = _y + "px";
	},
	
	/**
	 * wrapper for viewport calc
	 */
	_getViewPort: function() {
		return dijit.getViewport();
	},
	
	/**
	 * wrapper for layer height
	 */
	_getObjHeight: function() {
		return dojo.marginBox(this.nodeObj).h;
	},
	
	/**
	 * calc width with margin via JS as box model is wrong in CSS
	 */
	_calcWidth: function() {
		if((dojo.isIE && dojo.isIE <= 6) || dojo.isOpera) { 
			this.nodeObj.style.width = this._getViewPort().w - this.offsetX;
		}
	}
};
/* following part is taken from dojox.regexp and patched to reject a domain name with a single letter in email validation
 */
dojox.regexp.host = function(/*Object?*/flags){
	flags = (typeof flags == "object") ? flags : {};
	if(typeof flags.allowIP != "boolean"){ flags.allowIP = true; }
	if(typeof flags.allowLocal != "boolean"){ flags.allowLocal = false; }
	if(typeof flags.allowPort != "boolean"){ flags.allowPort = true; }
	var domainNameRE = "([0-9a-zA-Z]([-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?\\.)+" + dojox.regexp.tld(flags);  // **** C4SI modified, this is the only mod. ****
	var portRE = ( flags.allowPort ) ? "(\\:" + dojox.regexp.integer({signed: false}) + ")?" : "";
	var hostNameRE = domainNameRE;
	if(flags.allowIP){ hostNameRE += "|" +  dojox.regexp.ipAddress(flags); }
	if(flags.allowLocal){ hostNameRE += "|localhost"; }
	return "(" + hostNameRE + ")" + portRE; // String
}
/* following declare part is taken from dijit.dialog and modified, because dijit.dialog does not support script execution
 * within its content pane, so the dojox.contentpane is used as superclass instead
 */

dojo.declare(
	"sha.contentelements.Dialog",
	[dojox.layout.ContentPane, dijit._Templated, dijit.form._FormMixin], // **** C4SI modified, this is the only mod. ****
	{
		// summary:
		//		Pops up a modal dialog window, blocking access to the screen
		//		and also graying out the screen Dialog is extended from
		//		ContentPane so it supports all the same parameters (href, etc.)

		templateString: null,
		templatePath: dojo.moduleUrl("dijit", "templates/Dialog.html"),

		// open: Boolean
		//		is True or False depending on state of dialog
		open: false,

		// duration: Integer
		//		The time in milliseconds it takes the dialog to fade in and out
		duration: 400,

		_lastFocusItem:null,

		attributeMap: dojo.mixin(dojo.clone(dijit._Widget.prototype.attributeMap),
			{title: "titleBar"}),

		postCreate: function(){
			dojo.body().appendChild(this.domNode);
			this.inherited("postCreate",arguments);
			this.domNode.style.display="none";
			this.connect(this, "onExecute", "hide");
			this.connect(this, "onCancel", "hide");
		},

		onLoad: function(){
			// summary: 
			//		when href is specified we need to reposition the dialog after the data is loaded
			this._position();
			this.inherited("onLoad",arguments);
		},

		_setup: function(){
			// summary:
			//		stuff we need to do before showing the Dialog for the first
			//		time (but we defer it until right beforehand, for
			//		performance reasons)

			this._modalconnects = [];

			if(this.titleBar){
				this._moveable = new dojo.dnd.Moveable(this.domNode, { handle: this.titleBar });
			}

			this._underlay = new dijit.DialogUnderlay();

			var node = this.domNode;
			this._fadeIn = dojo.fx.combine(
				[dojo.fadeIn({
					node: node,
					duration: this.duration
				 }),
				 dojo.fadeIn({
					node: this._underlay.domNode,
					duration: this.duration,
					onBegin: dojo.hitch(this._underlay, "show")
				 })
				]
			);

			this._fadeOut = dojo.fx.combine(
				[dojo.fadeOut({
					node: node,
					duration: this.duration,
					onEnd: function(){
						node.style.display="none";
					}
				 }),
				 dojo.fadeOut({
					node: this._underlay.domNode,
					duration: this.duration,
					onEnd: dojo.hitch(this._underlay, "hide")
				 })
				]
			);
		},

		uninitialize: function(){
			if(this._underlay){
				this._underlay.destroy();
			}
		},

		_position: function(){
			// summary: position modal dialog in center of screen
			
			if(dojo.hasClass(dojo.body(),"dojoMove")){ return; }
			var viewport = dijit.getViewport();
			var mb = dojo.marginBox(this.domNode);

			var style = this.domNode.style;
			style.left = Math.floor((viewport.l + (viewport.w - mb.w)/2)) + "px";
			style.top = Math.floor((viewport.t + (viewport.h - mb.h)/2)) + "px";
		},

		_findLastFocus: function(/*Event*/ evt){
			// summary:  called from onblur of dialog container to determine the last focusable item
			this._lastFocused = evt.target;
		},

		_cycleFocus: function(/*Event*/ evt){
			// summary: when tabEnd receives focus, advance focus around to titleBar

			// on first focus to tabEnd, store the last focused item in dialog
			if(!this._lastFocusItem){
				this._lastFocusItem = this._lastFocused;
			}
			this.titleBar.focus();
		},

		_onKey: function(/*Event*/ evt){
			if(evt.keyCode){
				var node = evt.target;
				// see if we are shift-tabbing from titleBar
				if(node == this.titleBar && evt.shiftKey && evt.keyCode == dojo.keys.TAB){
					if(this._lastFocusItem){
						this._lastFocusItem.focus(); // send focus to last item in dialog if known
					}
					dojo.stopEvent(evt);
				}else{
					// see if the key is for the dialog
					while(node){
						if(node == this.domNode){
							if(evt.keyCode == dojo.keys.ESCAPE){
								this.hide(); 
							}else{
								return; // just let it go
							}
						}
						node = node.parentNode;
					}
					// this key is for the disabled document window
					if(evt.keyCode != dojo.keys.TAB){ // allow tabbing into the dialog for a11y
						dojo.stopEvent(evt);
					// opera won't tab to a div
					}else if (!dojo.isOpera){
						try{
							this.titleBar.focus();
						}catch(e){/*squelch*/}
					}
				}
			}
		},

		show: function(){
			// summary: display the dialog

			// first time we show the dialog, there's some initialization stuff to do			
			if(!this._alreadyInitialized){
				this._setup();
				this._alreadyInitialized=true;
			}

			if(this._fadeOut.status() == "playing"){
				this._fadeOut.stop();
			}

			this._modalconnects.push(dojo.connect(window, "onscroll", this, "layout"));
			this._modalconnects.push(dojo.connect(document.documentElement, "onkeypress", this, "_onKey"));

			// IE doesn't bubble onblur events - use ondeactivate instead
			var ev = typeof(document.ondeactivate) == "object" ? "ondeactivate" : "onblur";
			this._modalconnects.push(dojo.connect(this.containerNode, ev, this, "_findLastFocus"));

			dojo.style(this.domNode, "opacity", 0);
			this.domNode.style.display="block";
			this.open = true;
			this._loadCheck(); // lazy load trigger

			this._position();

			this._fadeIn.play();

			this._savedFocus = dijit.getFocus(this);

			// set timeout to allow the browser to render dialog
			setTimeout(dojo.hitch(this, function(){
				dijit.focus(this.titleBar);
			}), 50);
		},

		hide: function(){
			// summary
			//		Hide the dialog

			// if we haven't been initialized yet then we aren't showing and we can just return		
			if(!this._alreadyInitialized){
				return;
			}

			if(this._fadeIn.status() == "playing"){
				this._fadeIn.stop();
			}
			this._fadeOut.play();

			if (this._scrollConnected){
				this._scrollConnected = false;
			}
			dojo.forEach(this._modalconnects, dojo.disconnect);
			this._modalconnects = [];

			this.connect(this._fadeOut,"onEnd",dojo.hitch(this,function(){
				dijit.focus(this._savedFocus);
			}));
			this.open = false;
		},

		layout: function() {
			// summary: position the Dialog and the underlay
			if(this.domNode.style.display == "block"){
				this._underlay.layout();
				this._position();
			}
		}
	}
);

// START: print popup window =============================================
sha.popup = {
	wObj: null,
	h: 600,
	w: 700,
	t: 20,
	l: 50,
	
	init: function() {
		dojo.subscribe(sha.EVT_PRINTPAGE, this, this.open);
	},
	
	open: function(src) {
		// not higher than the nrowser viewport
		this.h = dijit.getViewport().h - 80;
		// get the browser position and place it there
		this.t = (dojo.isIE) ? (window.screenTop + this.t) : (window.screenY + this.t);
		this.l = (dojo.isIE) ? (window.screenLeft + this.l) : (window.screenX + this.l);
		
		if(!src || src==null || src=="") {
			var src = document.location.href;
			src = (src.indexOf("?") != -1) ? (src+"&pview=true") : (src+"?pview=true");
		}
		
		if (this.wObj!=null && !this.wObj.closed) {
			this.wObj.location.href = src;
			this.wObj.focus();
		} else {
			this.wObj = window.open(src, "newPopupWin", "width=" +this.w+ ",height=" +this.h+ ",top=" +this.t+ ",left=" +this.l+ ",toolbar=no,scrollbars=yes,resizable=yes,menubar=no,location=no,dependent=no");
			if(this.wObj!=null && this.wObj!="") this.wObj.focus();
		}
		
		/*
		 * Safari fix for popup blocker
		 * http://www.webmaster-talk.com/javascript-forum/105303-about-window-open-in-safari.html
		 * Safari blocks window.open from nested functions
		 * so check if this.wObj is undefined and just call the print directly
		 */
		if(dojo.isSafari && (this.wObj==null || this.wObj=="")) {
			window.print();
		}
	}
};
sha.popup.init();

// START: on doc page load =============================================== 
dojo.addOnLoad(
	function() {
		// tooltip container initialization
		sha.contentelements.tooltip.init();
		
		// main navigation initialisation
		sha.topnav.initMenu();
		
		// sIFR replace headlines
		sha.sifrReplacement.run();
		
		// delay a little to give sIFR the time to build the headlines first
		window.setTimeout("sha.shadowManager.init()", 300); // TODO: 0.3sec can be too short for snail PCs
		
		// let the footer listen to custom event
		sha.footerEl.evtSub();
	}
);
// END: on doc page load