/**
 * PromoIconBox constructor
 * @constructor
 * @param {String} title The title of the promociconbox
 * @param {String} content The content of the promociconbox
 * @param {Boolean} singleInstance Set to true or false for one or multiple promociconboxes at the same time
 */
function PromoIconBox(title, content, singleInstance)
{
	// Private
	var dom				= new DOM(),
		cursorOffsetX	= 0,
		cursorOffsetY	= 0,
		scrollBarWidth	= 30;
	/**
	 * active promoiconbox true or false
	 * @type Boolean
	 * @field
	 */	
	var active			= false;
	/**
	 * AttachedTo the object the promoiconbox is attached to
	 * @type Object
	 * @field
	 */
    var attachedTo		= null;

	// Public
	this.setPosition	= setPosition;
	this.setTitle		= setTitle;
	this.setContent		= setContent;
	this.getAttachedTo	= getAttachedTo;
	this.show			= show;
	this.close			= close;

	if (PromoIconBox.instance != undefined)
	{
		PromoIconBox.instance.close();

		delete PromoIconBox.instance;
	}

	if (singleInstance == true)
	{
		PromoIconBox.instance = this;
	}

	/**
	 * Reference to a created promoiconbox
	 * @field
	 */
	var promoiconBox = dom.create(
		"div",
		{
			className : "promoiconbox"
		},
		[
			dom.create(
				"div",
				{
					className : "promoiconbox_title"
				},
				[
					dom.create(
						"h2",
						null,
						[title]
					),
					dom.create(
						"a",
						{
							href	: "#",
							onclick	: close
						},
						["Sluiten"]
					)
				]
			),
			dom.create(
				"div",
				{
					className : "promoiconbox_content"
				},
				[
					dom.create(
						"div",
						{
							className : "promoiconbox_content_wrapper"
						},
						content
					)
				]
			)
		]
	);

	// Promoiconbox width
	var width = Number(promoiconBox.getStyle("width").match(/[0-9]+/))
			  + Number(promoiconBox.getStyle("paddingLeft").match(/[0-9]+/))
			  + Number(promoiconBox.getStyle("paddingRight").match(/[0-9]+/));

	/**
	 * Set the position of the Promoiconbox
	 * @param {Number} positionX The position of the Promoiconbox on the X axis.
	 * @param {Number} positionY The position of the Promoiconbox on the Y axis.
	 */
	function setPosition(positionX, positionY)
	{
		var flip = false;

		if((document.body.clientWidth - scrollBarWidth) > 1280)
		{
			usedWidth = 1280 - scrollBarWidth;
		}
		else
		{
			usedWidth = document.body.clientWidth - scrollBarWidth;
		}
		// If there's no room left on the right of the cursor, position the info box on the left side
		if ((width + positionX) > usedWidth)
		{
			flip = true;

			promoiconBox.addClass("flip");
		}
		else
		{
			flip = true;

			promoiconBox.removeClass("flip");
		}

		// Set position
		promoiconBox.style.top		= positionY - 10 + "px";
		promoiconBox.style.left	= (flip == true ? positionX - width - 8 : positionX + 8) + "px";
	}

	/**
	 * Set the title of the Promoiconbox
	 * @throws {Invalid Argument} When title is missing or not a string
	 * @param {String} title The title of the Promoiconbox as a string.
	 */
	function setTitle(title)
	{
		if (typeof title != "string") 
		{
			throw new Error("Invalid argument: title is missing or not a string");
		}

		promoiconBox.getFirstByTagName("h2").firstChild.nodeValue = title;
	}

	/**
	 * Set the content of the Promoiconbox
	 * @param {String} content The content of the Promoiconbox as a string.
	 * @param {Boolean} useDom By default, the content is supplied as a string. Set this parameter to true for use of DOM objects (as an array)
	 */
	function setContent(content, useDom)
	{
		if (typeof useDom != "boolean") 
		{
			useDom = false;
		}

		if (typeof content != "string" && useDom == false) 
		{
			throw new Error("Invalid argument: content is missing or not a string");
		}

		var contentWrapper = promoiconBox.getByClassName("promoiconbox_content_wrapper", "div")[0];
		
		if (useDom == true)
		{
			var contentWrapperReplacement = dom.create(
				"div",
				{
					className : "promoiconbox_content_wrapper"
				},
				content
			);
		}
		else
		{
			var contentWrapperReplacement = dom.create(
				"div",
				{
					className : "promoiconbox_content_wrapper"
				}
			);

			contentWrapperReplacement.innerHTML = content;
		}

		contentWrapper.parentNode.replaceChild(contentWrapperReplacement, contentWrapper);
	}

	/**
	 * Get the element to which the Promoiconbox is attached
	 * @return {Object} The element to which the Promoiconbox is attached.
	 */
	function getAttachedTo()
	{
		return attachedTo;
	}

	/**
	 * Close the Promoiconbox when a click outside of the Promoiconbox is detected
	 * @param {Event} event The event dispatched by the listener.
	 * @event
	 */
	function outsideClickListener(event)
	{
		if (event == undefined)
		{
			event = window.event;
		}

		if (event.target == undefined)
		{
			event.target = event.srcElement;
		}

		var target = event.target;

		while (target != null && target != promoiconBox && target != attachedTo && target.parentNode != null)
		{
			target = target.parentNode;
		}

		if (target != promoiconBox && target != attachedTo)
		{
			close();
		}
	}

	/**
	 * Show the Promoiconbox
	 * @param {Object} attachTo The object the promoiconbox is attached to
	 * @return {Boolean} false
	 */
	function show(attachTo)
	{
		if (active == false)
		{
			active	= true;
			attachedTo	= attachTo;

			dom.getById("layout_content_wrapper").appendChild(promoiconBox);

			// Update the width, as IE browsers need the element to be in a DOM document to able to get the computed style
			width = promoiconBox.offsetWidth;

			dom.getFirstByTagName("body").addEventListener("click", outsideClickListener, false);
			window.addEventListener("resize", outsideClickListener, false);
		}
	}

	/**
	 * Close the Promoiconbox
	 * @return {Boolean} false
	 */
	function close()
	{
		if (active == true)
		{
			active		= false;
			attachedTo	= null;

			dom.getFirstByTagName("body").removeEventListener("click", outsideClickListener, false);
			window.removeEventListener("resize", outsideClickListener, false);

			promoiconBox.remove();
		}

		return false;
	}
}