
if (Object.isUndefined(CodeCompany)) { var CodeCompany = {}; }

CodeCompany.ImageMap = Class.create({

	log: function(str) {
		if (!Object.isUndefined(site)) { site.log('ImageMap: '+str); }
	},

	initialize: function(imageElement,options) {
		// Get dimensions from image
		this.width = imageElement.getWidth();
		this.height = imageElement.getHeight();

		//this.log('ImageMap ('+this.width+'x'+this.height+')');

		this.options = Object.extend({
			pointDefaults: {
				infoHtml:		'&nbsp;',
				popupHtml:		'[popup]',
				xPosition:		0,
				yPosition:		0,
				xOffset:		0,
				yOffset:		0,
				appearDuration: 0.5,
				fadeDuration:	0.5
			}
		},options || {});

		// Instantiate appContainer container and wrap imageElement in it
		this.appContainer = new Element('div');
		this.appContainer.addClassName('imagemap_container');
		this.appContainer.style.width = this.width+'px';
		this.appContainer.style.height = this.height+'px';
		imageElement.wrap(this.appContainer);

		// Instantiate pointsContainer and add to appContainer
		this.pointsContainer = new Element('div');
		this.pointsContainer.addClassName('imagemap_points');
		this.pointsContainer.style.position = 'absolute';
		this.appContainer.insert({top: this.pointsContainer});

		// Tweak image
		imageElement.addClassName('imagemap_image');

		// Array of points
		this.points = [];

		//this.log('Initialized');
	},

	addPoint: function(options) {

		if (undefined===options.xPosition) { return; }
		if (undefined===options.yPosition) { return; }

		// We'll be calculating with these, so make sure they're integers
		options.xPosition = parseInt(options.xPosition,10);
		options.yPosition = parseInt(options.yPosition,10);

		if ((options.xPosition<0) || (options.xPosition>=this.width) ||
			(options.yPosition<0) || (options.yPosition>=this.height)) {
			this.log('Point at '+options.xPosition+','+options.yPosition+' outside image ('+this.width+'x'+this.height+')');
			return undefined;
		}

		var point = new CodeCompany.ImageMapPoint(
			this.pointsContainer,
			Object.extend(
				Object.extend(this.options.pointDefaults,options||{}),{
					containerWidth: this.width,
					containerHeight: this.height
				}
			)
		);
		this.points.push(point);
		return point;
	}

});


CodeCompany.ImageMapPoint = Class.create({

	log: function(str) {
		if (!Object.isUndefined(site)) { site.log('ImageMapPoint: '+str); }
	},

	initialize: function(pointsContainer,options) {
		this.options = Object.extend({
			infoHtml:			'',
			popupHtml:			'',
			xPosition:			0,
			yPosition:			0,
			xOffset:			0,
			yOffset:			0,
			appearDuration:		0.5,
			fadeDuration:		0.5,
			rolloutDuration:	0.2,	// Box appear/disappear
			rightEdge:			170,
			rightEdgeOffset:	154,
			rightEdgeClassName:	'imagemap_point_onRightEdge',
			bottomEdge:			100,
			bottomEdgeOffset:	70,
			bottomEdgeClassName:'imagemap_point_onBottomEdge',
			poppedClassName:	'imagemap_point_popped'
		},options || {});

		this.popped = false;

		// Create point container
		this.container = new Element('div');
		this.container.hide();
		this.container.addClassName('imagemap_point');
		this.container.style.position = 'absolute';

		// Create point subcontainer (because IE6 refuses to understand chained CSS classes)
		this.subcontainer = new Element('div');
		this.subcontainer.wrap(this.container);

		this.positionContainer();

		// Create info element
		this.info = new Element('div');
		this.info.addClassName('imagemap_point_info');
		this.info.update(this.options.infoHtml);
		this.infoContainer = new Element('div');
		this.infoContainer.setStyle({
			'margin': 0 /* Required to override general CSS rule in doc_fryd.css:80 */
		});
		this.infoContainer.addClassName('imagemap_point_infocontainer');
		this.info.wrap(this.infoContainer);
		this.subcontainer.insert({bottom: this.infoContainer});

		// Create popup element
		this.popup = new Element('div');
		this.popup.hide();
		this.popup.addClassName('imagemap_point_popup');
		this.popup.update(
			'<div class="imagemap_point_popup_inner">'+
				this.options.popupHtml+
			'</div>'
		);
		this.popupContainer = new Element('div');
		this.popupContainer.addClassName('imagemap_point_popupcontainer');
		this.popup.wrap(this.popupContainer);
		this.subcontainer.insert({bottom: this.popupContainer});

		pointsContainer.insert({top: this.container});

		this.container.appear({duration: this.options.appearDuration});

		// Popup effect
		this.popupEffect1 = undefined;
		this.popupEffect2 = undefined;

		// Observers
		this.container.observe('mouseenter',this.onMouseEnter.bindAsEventListener(this));
		this.container.observe('mouseleave',this.onMouseLeave.bindAsEventListener(this));

		this.log('Point added at '+this.options.xPosition+','+this.options.yPosition);
	},

	positionContainer: function() {
		// Initial position coordinates
		var	x = this.options.xPosition + this.options.xOffset;
		var y = this.options.yPosition + this.options.yOffset;

		// Close to right edge?
		 if (this.options.rightEdge !== undefined) {
			if (x>this.options.containerWidth-this.options.rightEdge) {
				// Adjust x position?
				this.log("on right edge");
				if (this.popped && (this.options.rightEdgeOffset !== undefined)) { x -= this.options.rightEdgeOffset; }
				// Add class?
				if (this.options.rightEdgeClassName !== undefined) { this.subcontainer.addClassName(this.options.rightEdgeClassName); }
			} else {
				// Remove class?
				if (this.options.rightEdgeClassName !== undefined) { this.subcontainer.removeClassName(this.options.rightEdgeClassName); }
			}
		}

		// Close to bottom edge?
		if (this.options.bottomEdge !== undefined) {
			if (y>this.options.containerHeight-this.options.bottomEdge) {
				// Adjust y position?
				if (this.popped && (this.options.bottomEdgeOffset !== undefined)) { y -= this.options.bottomEdgeOffset; }
				// Add class?
				if (this.options.bottomEdgeClassName !== undefined) { this.subcontainer.addClassName(this.options.bottomEdgeClassName); }
			} else {
				// Remove class?
				if (this.options.bottomEdgeClassName !== undefined) { this.subcontainer.removeClassName(this.options.bottomEdgeClassName); }
			}
		}

		// Position element
		this.container.setStyle({
			'left':		x+'px',
			'top':		y+'px'
		});
	},

	cancelEffects: function() {
		this.log("Cancelling effects..");
		if (!Object.isUndefined(this.popupEffect1)) { this.popupEffect1.cancel(); }
		if (!Object.isUndefined(this.popupEffect2)) { this.popupEffect2.cancel(); }
	},

	onMouseEnter: function(event) {
		this.log("onMouseEnter()");
		this.cancelEffects();

		this.container.addClassName(this.options.poppedClassName);
		this.popped = true;
		this.positionContainer();

		this.popupEffect2 = new Effect.Appear(this.popup,{
			duration: this.options.rolloutDuration
		});
	},

	onMouseLeave: function(event,point) {
		this.log("onMouseLeave()");
		this.cancelEffects();

		this.popupEffect2 = new Effect.Fade(this.popup,{
			duration: this.options.rolloutDuration,
			afterFinish: this.afterMouseLeaveEffect.bind(this)
		});
	},

	afterMouseLeaveEffect: function() {
		this.container.removeClassName(this.options.poppedClassName);
		this.popped = false;
		this.positionContainer();
	},

	getContainerElement: function() {
		return this.container;
	}

});



if (Object.isUndefined(CodeCompany)) { var CodeCompany = {}; }

CodeCompany.ImageMapLoader = Class.create({

	log: function(str) {
		if (!Object.isUndefined(site)) { site.log('ImageMapLoader: '+str); }
	},

	initialize: function(options) {
		this.options = Object.extend({
			maxTextLength:		15,
			textTruncator:		'&hellip;',
			elementSelector:	'img:not(.overlayable)'
		},options || {});

		// Run through images and match on regular expression
		var count = 0;
		$$(this.options.elementSelector).each(function(element){
			var match = element.src.match(/miljo(\d+)\./);
			if (match!==null) {
				this.createImageMap(element,RegExp.$1);
				count++;
			}
		},this);
		if (count === 0) {
			this.log('No matching images in this page');
		}
	},

	createImageMapFromJSON: function(im,jsonStr) {
		var json;
		try { json=jsonStr.evalJSON(); }
		catch (error) {
			this.log('Malformed JSON: '+jsonStr);
			return;
		}
		json.each(function(point){
			if ((undefined===point.xcoord) || (point.xcoord==='')) { return; }
			if ((undefined===point.ycoord) || (point.ycoord==='')) { return; }
			if (undefined===point.link) { point.link=''; }
			if (undefined===point.text) { point.text=''; }
			point.opennew = (point.opennew===true);

			// Bail out if link is empty
			if (point.link=='') {
				return;
			}

			// Build link text
			var text = '';
			point.text.split('|').each(function(line){
				var title = '';	

				// Truncate text?
				if ((this.options.maxTextLength!==undefined) && (line.length>this.options.maxTextLength)) {
					title = line;
					line = line.substr(0,this.options.maxTextLength-1)+this.options.textTruncator;
				}

				// Escape link text
				line = line
					.replace('>','&gt;')
					.replace('<','&lt;');

				// Escape title
				title = title
					.replace('"','&quot;');

				text += '<span title="'+title+'">'+line+'</span><br />';
			},this);

			// Build popupHTML
			var popupHTML;
			if (point.link != '') {
				popupHTML = '<a href="'+point.link+'"';
				if (point.opennew) { popupHTML += ' target="_blank"'; }
				popupHTML += '>'+text+'</a>';
			} else {
				popupHTML = text;
			}

			// Encapsulate in .coloredlink
			popupHTML = '<div class="coloredlink">'+popupHTML+'</div>';

			// Add point
			im.addPoint(Object.extend({
				'xPosition':	point.xcoord,
				'yPosition':	point.ycoord,
				'xOffset':		-20,
				'yOffset':		-20,
				'popupHtml':	popupHTML
			},this.options.point || {}));

		},this);
	},

	createImageMap: function(element,docId) {
		this.log('Creating ImageMap for element with docId '+docId);

		// Instantiate ImageMap
		var im = new CodeCompany.ImageMap(element);

		var url = '/systemservice/miljo?docId='+docId;
		new Ajax.Request(url,{
			method: 'get',
			onSuccess: (function(transport){
				this.createImageMapFromJSON(im,transport.responseText);
			}).bind(this),
			onError: (function(transport){
				this.log('JSON request failed: '+url);
			}).bind(this)
		});
	}

});




