// registry, used to store the design configs
var pc3PopupDesignData = {};
var pc3PopupData = new Array();
var pc3Accordions = {};
var pc3Scrollers = {};

function pc3WidgetInit(){
	if ( typeof( pc3Widget ) == "undefined" ){
		pc3Widget = new pc3WidgetManagement();
		pc3Widget.init();
	} else {
		pc3Widget.updateAll();
	}
}

function pc3WidgetManagement(){
	var self = this;
	this.mousePosition = {x:0,y:0};
	this.popupManagement = '';
	this.scrollers = $H({});
	this.body = $(document.body);
	this.backgrounds = $H({});
	this.blurs = $H({});
	this.outerDimensionElements = $H({});
		
	this.init = function(){
		Event.observe(document, "mousemove", this.handleMouseMove.bindAsEventListener(this));
		Event.observe(document, "click", this.handleClick.bindAsEventListener(this));
		Event.observe(document, "mouseup", this.handleMouseUp.bindAsEventListener(this));
		Event.observe(window, "resize", this.handleResize.bindAsEventListener(this));
		Event.observe(window, "scroll", this.handleScroll.bindAsEventListener(this));

		this.extendBrowserInfo();
		
		this.initAccordions();
		this.initScrollers();
		this.initPopupManagement();
	}

	this.updateAll = function(){
		if ( typeof( pc3DatepickerManagement ) != "undefined" ) pc3DatepickerManagement.update();
		
		this.initAccordions();
		this.updateScrollers();
		this.initScrollers();
		if ( !this.popupManagement ) this.initPopupManagement();
		else this.popupManagement.init();
	}

	this.update = function(){ return true; }

	//Widget managements
		//accordions
			this.initAccordions = function(){
				for( var accordionId in pc3Accordions ){ var accordion = new pc3Accordion(accordionId, pc3Accordions[accordionId]); }
				pc3Accordions = {};
			}
		//-----
		//scrollers
			this.initScrollers = function(){
				for( var scrollerId in pc3Scrollers ){
					var bars = new Array();
					if ( pc3Scrollers[scrollerId]['bars'] ) bars = pc3Scrollers[scrollerId]['bars'];				
					var arrows = new Array();
					if ( pc3Scrollers[scrollerId]['arrows'] ) arrows = pc3Scrollers[scrollerId]['arrows'];
					this.scrollers.set(scrollerId, new pc3Scroller(scrollerId, pc3Scrollers[scrollerId]['scroller'], bars, arrows));
				}
				pc3Scrollers = {};
			}
	
			this.updateScrollers = function(){ this.scrollers.each(function(scroller){ scroller.value.update(); }); }
			
			this.updateScroller = function(scrollerId){ if ( this.scrollers.get(scrollerId) ) this.scrollers.get(scrollerId).update(); }
		
			this.scrollTo = function(scrollerId, x, y, elementId, alignment){
				if ( this.scrollers.get(scrollerId) ) this.scrollers.get(scrollerId).scrollTo({x:x,y:y}, elementId, alignment);
			}
		//-----
		//popups
			this.initPopupManagement = function(){ if ( $H(pc3PopupDesignData).size() && $H(pc3PopupData).size() ) this.popupManagement = new pc3PopupManagement(); }
			
			this.closePopup = function(trigger){ if ( this.popupManagement ) this.popupManagement.closePopup(trigger); }

			this.updatePopup = function(trigger){ if ( this.popupManagement ) this.popupManagement.updatePopup(trigger); }
		//-----
		
		
		this.getParentWidget = function(element){
			parentWidget = $(element).up('[pc3Widget]');
			if ( parentWidget ) return parentWidget.popup;		
			else return this;
		}
		
	//---------------



	// Utilities
		this.setDocumentDimension = function( fast ){
			if ( window.innerHeight && window.scrollMaxY ) var scrollY = window.innerHeight + window.scrollMaxY;
			else if ( document.body.scrollHeight > document.body.offsetHeight ) var scrollY = document.body.scrollHeight;
			else var scrollY = document.body.offsetHeight;
			
			if ( self.innerHeight ) var windowHeight = self.innerHeight;
			else if ( document.documentElement && document.documentElement.clientHeight ) var windowHeight = document.documentElement.clientHeight;
			else if ( document.body ) var windowHeight = document.body.clientHeight;
				
			if ( scrollY < windowHeight ) var height = windowHeight;
			else var height = scrollY;
			
			if ( fast && this.documentDimension ){
				var width = this.documentDimension.width;
			} else {
				var dummyContent = new Element('div').setStyle({position:'absolute', left:'0px', top:'0px', width:'auto', height:'auto'});
				var html = this.body.innerHTML;
				dummyContent.innerHTML = html.stripScripts();
				dummyContent.hide();
				this.body.appendChild(dummyContent);
				var width = document.viewport.getScrollOffsets().left + document.viewport.getWidth();
				if (dummyContent.getWidth() > width ) width = dummyContent.getWidth();
				dummyContent.remove();
			}
			this.documentDimension = {left:0,top:0,width:width,height:height,right:width,bottom:height};
		}
	
		this.getDocumentDimension = function(){
			if ( !this.documentDimension ) this.setDocumentDimension(false);
			return this.documentDimension; 
		}
		
		this.getElementDimension = function(element){
			var dummyContent = element.cloneNode(true);
			dummyContent.hide();
			dummyContent.innerHTML = dummyContent.innerHTML.stripScripts();
			this.body.appendChild(dummyContent);
			dummyContent.setStyle({position:'absolute',left:'100000px', top:'100000px', width:'auto', height:'auto'});
			var width = dummyContent.getWidth();
			dummyContent.setStyle({left:'0px', top:'0px'});
			var height = dummyContent.getHeight();
			dummyContent.remove();
			return {width:width,height:height};
		}

		this.getOuterDimension = function(element, inline){
			var dummyElement = element;
			if ( !inline ){
				//var dimension = this.outerDimensionElements.get(element);
				//if ( dimension ) return dimension;
				dummyElement = element.cloneNode(true);
				dummyElement.setStyle({position:'absolute',left:'0px', top:'0px',width:'1000px', height:'1000px'});
				dummyElement.hide();
				dummyElement.innerHTML = dummyElement.innerHTML.stripScripts();
				this.body.appendChild(dummyElement);
			}
			
			var dimension = {};
			['Left','Top','Right','Bottom'].each(function(location){
				dimension['offset'+location] = (dummyElement.getStyle('border'+location+'Style')=='none'?0:parseInt((dummyElement.getStyle('border'+location+'Width')?dummyElement.getStyle('border'+location+'Width'):0))) + parseInt((dummyElement.getStyle('padding'+location)?dummyElement.getStyle('padding'+location):0));
			});
			
			dimension.offsetsX = dimension.offsetLeft + dimension.offsetRight;
			dimension.offsetsY = dimension.offsetTop + dimension.offsetBottom;
			dimension.width = (element.getWidth()<0?0:element.getWidth());
			dimension.innerWidth = dimension.width - dimension.offsetsX;
			dimension.height = (element.getHeight()<0?0:element.getHeight());
			dimension.innerHeight = dimension.height - dimension.offsetsY;
			var positions = element.positionedOffset();
			dimension.left = positions.left;
			dimension.top = positions.top;
			if ( !inline ){
				dummyElement.remove();
				this.outerDimensionElements.set(element, dimension);
			}
			return dimension;
		}

		this.mouseIsInside = function(event, element){
			var pointerX = event.pointerX();
			var pointerY = event.pointerY();
			if ( Prototype.Browser.IE ){
				pointerX = pointerX - 2;
				pointerY = pointerY - 2;
			}
			var position = element.cumulativeOffset();
			var triggerArea = {left:position.left,top:position.top,right:(position.left + element.getWidth()),bottom:(position.top + element.getHeight())};
			if ( (pointerX >= triggerArea.left && pointerX < triggerArea.right) && (pointerY >= triggerArea.top && pointerY < triggerArea.bottom) ) return true;
			return false;
		}

		this.findElementById = function(parent, id){
			var needle = '';
			parent.childElements().each(function(element){
				if ( element.id == id ){
					needle = element;
					throw $break;
				} else {
					needle = self.findElementById(element, id);
					if ( needle ) throw $break;
				}
			});
			return needle;
		}
		
		this.getOpacity = function(element){
			var opacity = element.getStyle('filter');
			if ( opacity && opacity != 'none' ) return opacity.slice((opacity.indexOf('=')+1),(opacity.length-1))/100;
			return element.getStyle('opacity');
		}
		
		this.addBackground = function(parentElement, color, opacity){
			if ( this.backgrounds.get(parentElement) ) return false;
			this.backgrounds.set(parentElement, new pc3Background(this, parentElement, color, opacity));
			return this.backgrounds.get(parentElement);
		}
		
		this.removeBackground = function(parentElement){
			if ( this.backgrounds.get(parentElement) ){
				var element = this.backgrounds.get(parentElement);
				delete element;
				this.backgrounds.unset(parentElement);
			}
		}

		this.extendBrowserInfo = function(){
			Prototype.Browser.IE6 = ( Prototype.Browser.IE && parseInt(navigator.userAgent.substring(navigator.userAgent.indexOf("MSIE")+5)) == 6 );
			Prototype.Browser.IE7 = ( Prototype.Browser.IE && parseInt(navigator.userAgent.substring(navigator.userAgent.indexOf("MSIE")+5)) == 7 );
			Prototype.Browser.IE8 = ( Prototype.Browser.IE && parseInt(navigator.userAgent.substring(navigator.userAgent.indexOf("MSIE")+5)) == 8 );
		}
		
		
		this.blur = function(radius){
			var blur = this.blurs.get(radius);
			if ( blur ) return blur;
			var breakOff = (1+radius);
			var dimension = 2 * breakOff;
			var bluredMatrix = {};
			$A($R(2, dimension)).each(function(row){
				$A($R(2, dimension)).each(function(column){
					var counter = 0;
					var sum = 0;
					$A($R(Math.max(parseInt(row-radius), 1), Math.min(parseInt(row)+radius, dimension))).each(function(sectionRow){
						$A($R(Math.max(parseInt(column-radius), 1), Math.min(parseInt(column)+radius, dimension))).each(function(sectionColumn){
							if ( sectionColumn > breakOff && sectionRow > breakOff ) sum = sum + 1;
							counter++;
						});
					});
					var average = sum/counter;
					if ( column == 2 ) var columns = {1:average};
					else var columns = bluredMatrix[row-1];
					if ( column == 2 ) bluredMatrix[row-1] = columns;
					else columns[column-1] = average;
					
				});
			});
			this.blurs.set(radius, bluredMatrix);
			return bluredMatrix;
		}

	//---------------
	


	// Event handlers
		this.handleMouseMove = function(event){
			this.mousePosition.x = event.pointerX();
			this.mousePosition.y = event.pointerY();
			if ( this.popupManagement ) this.popupManagement.handleMouseMove();
			this.scrollers.each(function(scroller){ scroller.value.handleMouseMove(event); });
		}
	
		this.handleClick = function(event){
			if ( this.popupManagement ) this.popupManagement.handleClick(event);
		}

		this.handleMouseUp = function(event){
			this.scrollers.each(function(scroller){ scroller.value.handleMouseUp(event); });
		}
	
		this.handleResize = function(event){
			if ( this.backgrounds.size() > 0 ) this.setDocumentDimension(false);
			this.backgrounds.each(function(background){ background.value.resize() });
			if ( this.popupManagement ) this.popupManagement.handleResize();
		}
	
		this.handleScroll = function(event){
			if ( this.popupManagement ){
				this.setDocumentDimension(true);
				this.popupManagement.handleScroll();
			}
		}
	//---------------
	
}

function pc3Background(management, parent, color, opacity){
	var self = this;
	this.management = management;
	this.parent = parent;
	
	this.background = '';
	this.effects = $H({});
	this.state = '';

	this.init = function(color, opacity){
		this.background = new Element('div').setStyle({position:'absolute', zIndex:999, backgroundColor:(color?color:'none')});
		this.opacity = (opacity?opacity:75);
		this.background.hide();
		this.parent.appendChild(this.background);
	}
	
	this.open = function(delay, effect, duration){
		if ( delay > 0 ) this.waitingToOpen = this.openBackground.bind(this, effect, duration).delay(delay);
		else this.openBackground(effect, duration);
	}

	this.openBackground = function(effect, duration){
		this.waitingToOpen = '';
		this.state = 'opening';
		if ( this.parent == pc3Widget.body ){
			var boundingBox = pc3Widget.getDocumentDimension();
		} else {
			var boundingBox = {
				left:0,
				top:0,
				right:this.parent.getWidth(),
				bottom:this.parent.getHeight()
			};
		}

		this.background.setStyle({
			left:boundingBox.left +'px',
			top:boundingBox.top +'px',
			width:(boundingBox.right - boundingBox.left) +'px',
			height:(boundingBox.bottom - boundingBox.top) +'px'
		});
		
		// fadeIn
		if ( effect == 'fadeIn' ){
			this.setOpacity({value:0});
			var duration = (duration?parseFloat(duration)*1000:0);
			this.effects.set('opacity', new pc3Tween('opacity', 0, this.opacity, duration, 'EaseNone', this.setOpacity.bind(self), this.removeEffect.bind(self)));
		} else {
			this.setOpacity({value:this.opacity});
		}
		this.background.show();
		this.animate();
	}
	
	this.close = function(delay, effect, duration){
		if ( delay > 0 ) this.waitingToClose = this.closeBackground.bind(this, effect, duration).delay(delay);
		else this.closeBackground(effect, duration);
	}
	
	this.closeBackground = function(effect, duration){
		this.waitingToClose = '';
		this.state = 'closing';
		// fadeOut
		if ( effect == 'fadeOut' ){
			var duration = (duration?parseFloat(duration)*1000:0);
			this.effects.set('opacity', new pc3Tween('opacity', this.opacity, 0, duration, 'EaseNone', this.setOpacity.bind(self), this.removeEffect.bind(self)));
		}
		this.animate();
	}
	
	this.removeEffect = function(effect){ this.effects.unset(effect.name); }
	
	this.setOpacity = function(effect){ this.background.setOpacity(effect.value/100); }

	this.animate = function(){
		var finished = true;
		for ( var name in this.effects ) finished = false;
		
		if ( this.effects.size() ){
			this.animate.bind(this).delay(0.02)
		} else {
			if ( this.state == 'closing' ){
				this.state = 'closed';
				this.background.remove();
				this.management.removeBackground(this.parent);
			} else {
				this.state = 'opened';
			}
		}
	}

	this.resize = function(){
		if ( this.parent != pc3Widget.body ) return;
		var boundingBox = this.management.getDocumentDimension();
		this.background.setStyle({
			left:boundingBox.left +'px',
			top:boundingBox.top +'px',
			width:(boundingBox.right - boundingBox.left) +'px',
			height:(boundingBox.bottom - boundingBox.top) +'px'
		
		});
	}
	
	this.init(color, opacity);
}


function pc3Tween(name, start, end, duration, transition, onUpdate, onComplete){
	var self = this;
	this.name = name;
	this.value = start;
	this.end = end;
	this.onCompleteFunction = onComplete;
	this.onUpdateFunction = onUpdate;

	this.onUpdate = function(value){
		this.value = value;
		this.onUpdateFunction(this);
	}
	
	this.onComplete = function(){
		this.value = this.end;
		this.onUpdateFunction(this);
		this.onCompleteFunction(this);
	};
	
	this.init = function(duration, transition){
		Tweener.AddTween(
			{ value:this.value },
			{ value:this.end },
			{
				Duration: duration,
				Transition: Tweener.Transitions[transition],
				OnComplete: this.onComplete.bind(self),
				OnUpdate: function(tweener){
					if ( tweener.ScopeClean.value ) self.onUpdate.bind(self)(tweener.ScopeClean.value); 
				}
			}
		);
	}

	this.init(duration, transition);
}


function pc3Shadow(element, offsets, images, cornerSize, color, opacity, blurRadius, animated, fade){
	var self = this;
	this.element = element;
	this.shadows = {};
	this.zoomFactor = 100;

	this.maxExpansion = 2000;
		
	this.init = function(){
		var parent = this.element.ancestors()[0];
		var useImages = false;
		if ( images.left && images.top && images.right && images.bottom ) useImages = true;
		if ( Prototype.Browser.IE6 ) useImages = false;
		if ( Prototype.Browser.IE7 && fade ) useImages = false;
		if ( useImages ){
			this.cornerSize = cornerSize;
			var dimension = this.cornerSize;
		} else {
			this.cornerSize = Math.max(offsets.left,offsets.top,offsets.right,offsets.bottom);
			if ( animated && Prototype.Browser.IE6 ) blurRadius = Math.min(2, blurRadius);
			var corner = pc3Widget.blur(blurRadius);
			var dimension = (2*blurRadius)+1;
			opacity = opacity/100;
		}
		
		['left','top','right','bottom'].each(function(position){
			var outerBox = '';
			var shadows = {};
			if ( offsets[position] > 0 ){
				outerBox = new Element('div').setStyle({position:'absolute',overflow:'hidden'}).hide();
				parent.appendChild(outerBox);
				var filler = '';
				if ( position == 'left' && offsets.top < 0 ) filler = new Element('div').setStyle({overflow:'hidden',left:'0px', width:offsets[position]+'px'});
				if ( position == 'top' && offsets.left < 0 ) filler = new Element('div').setStyle({overflow:'hidden',float:'left', top:'0px', height:offsets[position]+'px'});
				if ( position == 'right' && offsets.top < 0 ) filler = new Element('div').setStyle({overflow:'hidden',right:'0px', width:offsets[position]+'px'});
				if ( position == 'bottom' && offsets.left < 0 ) filler = new Element('div').setStyle({overflow:'hidden',float:'left', bottom:'0px', height:offsets[position]+'px'});
				if ( filler ) outerBox.appendChild(filler);
				
				['element1', 'element2'].each( function(element) {
					var columnRange = new Array();
					var rowRange = new Array();
					var expanedWidth = 0;
					var expanedHeight = 0;
					var width = 1;
					var height = 1;
					var addPixels = false;
					var box = new Element('div').setStyle({overflow:'hidden',position:'relative'});
					var shadow = new Element('div').setStyle({overflow:'hidden',position:'absolute'});
					if ( useImages ){
						var image = $(new Image());
						image.src = images[position];
					}
					if ( offsets[position] < 1 ) return;
					switch( position ){
						case 'left':
							switch( element ){
								case 'element1':
									if ( useImages ){
										var top = -Math.max(0,offsets.top);
										shadow.setStyle({width:image.width+'px',height:image.height+'px',top:top+'px'});
										width = offsets[position];
										height = self.cornerSize;
									} else {
										width = offsets[position];
										height = Math.max(0, dimension - Math.max(0,offsets.top));
										columnRange = $A($R(1, Math.min((dimension + 1), width)));
										rowRange = $A($R(1+Math.max(0,offsets.top), dimension));
										expanedWidth = width - dimension;
										expanedHeight = 1;
										shadow.setStyle({width:width+'px',height:height+'px'});
									}
								break;
								case 'element2':
									if ( useImages ){
										var bottom = -Math.max(0,offsets.bottom);
										shadow.setStyle({width:image.width+'px',height:image.height+'px',bottom:bottom+'px'});
										width = offsets[position];
										height = image.height - self.cornerSize;
									} else {
										width = offsets[position];
										height = self.maxExpansion;
										columnRange = $A($R(1, Math.min((dimension + 1), width)));
										var startRange = Math.min((1 + Math.max(0,offsets.bottom)),dimension + 1);
										rowRange = $A($R(startRange, dimension + 1));
										rowRange.reverse();
										expanedWidth = width - dimension;
										expanedHeight = self.maxExpansion - (dimension - startRange);
										shadow.setStyle({width:width+'px',height:height+'px',bottom:'0px'});
									}
								break;
							}
						break;
						case 'top':
							switch( element ){
								case 'element1':
									if ( useImages ){
										shadow.setStyle({width:image.width+'px',height:image.height+'px'});
										width = self.cornerSize;
										height = offsets[position];
									} else {
										width = dimension;
										height = offsets[position];
										columnRange = $A($R(1, Math.min((dimension + 1), width)));
										rowRange = $A($R(1, Math.min((dimension + 1), height)));
										expanedWidth = 1;
										expanedHeight = self.cornerSize - dimension;
										shadow.setStyle({width:width+'px',height:height+'px'});
									}
								break;
								case 'element2':
									if ( useImages ){
										shadow.setStyle({width:image.width+'px',height:image.height+'px', right:'0px'});
										width = self.cornerSize;
										height = offsets[position];
									} else {
										width = self.maxExpansion;
										height = offsets[position];
										columnRange = $A($R(1, dimension+1));
										columnRange.reverse();
										rowRange = $A($R(1, Math.min((dimension + 1), height)));
										expanedWidth = self.maxExpansion - dimension;
										expanedHeight = height - dimension;
										shadow.setStyle({width:width+'px',height:height+'px', right:'0px'});
									}
								break;
							}
						break;
						case 'right':
							switch( element ){
								case 'element1':
									if ( useImages ){
										var top = -Math.max(0,offsets.top);
										shadow.setStyle({width:image.width+'px',height:image.height+'px',top:top+'px',right:'0px'});
										width = offsets[position];
										height = self.cornerSize;
									} else {
										width = offsets[position];
										height = Math.max(0, dimension - Math.max(0,offsets.top));
										columnRange = $A($R(1, Math.min((dimension + 1), width)));
										columnRange.reverse();
										rowRange = $A($R(1+Math.max(0,offsets.top), dimension));
										expanedWidth = width - dimension;
										expanedHeight = 1;
										shadow.setStyle({width:width+'px',height:height+'px'});
									}
								break;
								case 'element2':
									if ( useImages ){
										var bottom = -Math.max(0,offsets.bottom);
										shadow.setStyle({width:image.width+'px',height:image.height+'px',bottom:bottom+'px',right:'0px'});
										width = offsets[position];
										height = image.height - self.cornerSize;
									} else {
										width = offsets[position];
										height = self.maxExpansion;
										columnRange = $A($R(1, Math.min((dimension + 1), width)));
										columnRange.reverse();
										var startRange = Math.min((1 + Math.max(0,offsets.bottom)),dimension + 1);
										rowRange = $A($R(startRange, dimension + 1));
										rowRange.reverse();
										expanedWidth = width - dimension;
										expanedHeight = self.maxExpansion - (dimension - startRange);
										shadow.setStyle({width:width+'px',height:height+'px',bottom:'0px'});
									}
								break;
							}
						break;
						case 'bottom':
							switch( element ){
								case 'element1':
									if ( useImages ){
										shadow.setStyle({width:image.width+'px',height:image.height+'px',bottom:'0px'});
										width = self.cornerSize;
										height = offsets[position];
									} else {
										width = dimension;
										height = offsets[position];
										columnRange = $A($R(1, Math.min((dimension + 1), width)));
										rowRange = $A($R(1, Math.min((dimension + 1), height)));
										rowRange.reverse();
										expanedWidth = width - dimension;
										expanedHeight = height - dimension;
										shadow.setStyle({width:width+'px',height:height+'px', bottom:'0px'});
									}
								break;
								case 'element2':
									if ( useImages ){
										shadow.setStyle({width:image.width+'px',height:image.height+'px', right:'0px', bottom:'0px'});
										width = self.cornerSize;
										height = offsets[position];
									} else {
										width = self.maxExpansion;
										height = offsets[position];
										columnRange = $A($R(1, dimension+1));
										columnRange.reverse();
										rowRange = $A($R(1, Math.min((dimension + 1), height)));
										rowRange.reverse();
										expanedWidth = self.maxExpansion - dimension;
										expanedHeight = height - dimension;
										shadow.setStyle({width:width+'px',height:height+'px', bottom:'0px', right:'0px'});
									}
								break;
							}
						break;
			
					}

					box.setStyle({float:'left',width:width+'px',height:height+'px'});
					outerBox.appendChild(box);
					box.appendChild(shadow);
					shadows[element] = {element:box,width:width,height:height};
					
					if ( useImages ){
						shadow.appendChild(image);
					} else {
						rowRange.each(function(row){
							columnRange.each(function(column){
								var pixelWidth = 1;
								var pixelHeight = 1;
								var pixelOpacity = 0;
								
								if ( column <= dimension ){
									if ( row <= dimension ){
										pixelOpacity = corner[row][column];
									} else {
										pixelOpacity = corner[dimension][column];
										pixelHeight = expanedHeight;
									}
								} else {
									if ( row <= dimension ){
										pixelOpacity = corner[row][dimension];
										pixelWidth = expanedWidth;
									} else {
										pixelOpacity = corner[dimension][dimension];
										pixelWidth = expanedWidth;
										pixelHeight = expanedHeight;
									}
								}
								
								if ( column <= dimension + 1 && row <= dimension + 1 ){
									var pixel = new Element('div').setStyle({float:'left',overflow:'hidden',width:pixelWidth+'px',height:pixelHeight+'px',backgroundColor:color});
									pixel.setOpacity(pixelOpacity * opacity);
									shadow.appendChild(pixel);
								}
							});
						});
					}
				});
			}
			self.shadows[position] = {element:outerBox,style:{},offsets:{},offset:offsets[position],filler:filler,shadows:shadows};
		});
		
		this.status = 'hidden';
	}


	this.hide = function(){
		if ( this.status == 'hidden' ) return;
		['top', 'bottom', 'right', 'left'].each( function(position) { if ( self.shadows[position].element ) self.shadows[position].element.hide(); });
		this.status = 'hidden'
	}

	this.unhide = function(){
		if ( this.status == 'shown' ) return;
		['top', 'bottom', 'right', 'left'].each( function(position) { if ( self.shadows[position].element ) self.shadows[position].element.show(); });
		this.status = 'shown'
	}

	this.setZoomFactor = function(zoomFactor){
		if ( zoomFactor > 100 ) this.zoomFactor = 100;
		else this.zoomFactor = zoomFactor;
	}

	this.getOuterDimension = function(){
		var dimension = {};
		['Left','Top','Right','Bottom'].each(function(location){
			dimension['offset'+location] = (self.shadows[location.toLowerCase()]?((self.shadows[location.toLowerCase()].offset * self.zoomFactor)/100).round():0);
		});
		dimension.offsetsX = dimension.offsetLeft + dimension.offsetRight;
		dimension.offsetsY = dimension.offsetTop + dimension.offsetBottom;
		var outerDimension = pc3Widget.getOuterDimension(this.element, false);
		dimension.width = outerDimension.width + dimension.offsetsX;
		dimension.height = outerDimension.height + dimension.offsetsY;
		dimension.left = outerDimension.left - dimension.offsetLeft;
		dimension.top = outerDimension.top - dimension.offsetTop;
		return dimension;
	}
	
	
	this.show = function(){
		if ( this.cornerSize < 1 ) return;
		var outerDimension = this.getOuterDimension();
		var minSizeReached = true;
		if ( outerDimension.width  < (2 * this.cornerSize) ) minSizeReached = false;
		if ( outerDimension.height < (2 * this.cornerSize) ) minSizeReached = false;

		var popupDimension = pc3Widget.getOuterDimension(this.element, false);
		
		if ( !minSizeReached ){
			this.hide();
		} else {
			this.status = 'shown';
			['top', 'bottom', 'right', 'left'].each( function(position) {
				if ( self.shadows[position] ){
					self.shadows[position].style = {display:'none'};
					self.shadows[position].offsets = {x:0,y:0};
				}
			});
			
			

			var getStyle = function(left, top, width, height){ return {display:'block',left:left +'px',top:top +'px',width:width +'px',height:height +'px'}; };

			if ( outerDimension.offsetTop > 0 || outerDimension.offsetBottom > 0 ){
				var shadowWidth = popupDimension.width + Math.max(outerDimension.offsetLeft, 0) + Math.max(outerDimension.offsetRight, 0);

				if ( outerDimension.offsetTop > 0 ){
					var left = Math.min(popupDimension.left, (popupDimension.left - outerDimension.offsetLeft));
					var width = shadowWidth;
					var top = popupDimension.top - outerDimension.offsetTop;
					var height = outerDimension.offsetTop;
					this.shadows.top.style = getStyle(left, top, width, height);
					if ( this.shadows.top.filler ) this.shadows.top.filler.setStyle({width:Math.abs(this.shadows.left.offset)+'px'});
					width = width - (this.shadows.top.filler?Math.abs(this.shadows.left.offset):0) - this.shadows.top.shadows.element1.width + (this.shadows.right.offset<0?this.shadows.right.offset:0);
					this.shadows.top.shadows.element2.element.setStyle({width:width+'px'});
				}

				if ( outerDimension.offsetBottom > 0 ){
					var left = Math.min(popupDimension.left, (popupDimension.left - outerDimension.offsetLeft));
					var width = shadowWidth;
					var top = popupDimension.top + popupDimension.height;
					var height = outerDimension.offsetBottom;
					this.shadows.bottom.style = getStyle(left, top, width, height);
					if ( this.shadows.bottom.filler ) this.shadows.bottom.filler.setStyle({width:Math.abs(outerDimension.offsetLeft)+'px'});
					width = width - (this.shadows.bottom.filler?Math.abs(outerDimension.offsetLeft):0) - this.shadows.bottom.shadows.element1.width + (this.shadows.right.offset<0?this.shadows.right.offset:0);
					this.shadows.bottom.shadows.element2.element.setStyle({width:width+'px'});
				}
			}
			
			if ( outerDimension.offsetRight > 0 || outerDimension.offsetLeft > 0 ){

				if ( outerDimension.offsetLeft > 0 ){
					var left = Math.min(popupDimension.left, (popupDimension.left - outerDimension.offsetLeft));
					var width = outerDimension.offsetLeft;
					var top = popupDimension.top;
					var height = popupDimension.height;
					this.shadows.left.style = getStyle(left, top, width, height);
					if ( this.shadows.left.filler ) this.shadows.left.filler.setStyle({height:Math.abs(outerDimension.offsetTop)+'px'});
					height = height - (this.shadows.left.filler?Math.abs(outerDimension.offsetTop):0) - this.shadows.left.shadows.element1.height + (this.shadows.bottom.offset<0?this.shadows.bottom.offset:0);
					this.shadows.left.shadows.element2.element.setStyle({height:height+'px'});
				}

				if ( outerDimension.offsetRight > 0 ){
					var left = popupDimension.left + popupDimension.width;
					var width = outerDimension.offsetRight;
					var top = popupDimension.top;
					var height = popupDimension.height;
					this.shadows.right.style = getStyle(left, top, width, height);
					if ( this.shadows.right.filler ) this.shadows.right.filler.setStyle({height:Math.abs(outerDimension.offsetTop)+'px'});
					height = height - (this.shadows.right.filler?Math.abs(outerDimension.offsetTop):0) - this.shadows.right.shadows.element1.height + (this.shadows.bottom.offset<0?this.shadows.bottom.offset:0);
					this.shadows.right.shadows.element2.element.setStyle({height:height+'px'});
				}
			}
	
			['top', 'bottom', 'right', 'left'].each( function(position) {
				if ( self.shadows[position].element ){ self.shadows[position].element.setStyle(self.shadows[position].style); }
			});

		}
	}

	this.init();
}
