/**
 * Creates a new window object.
 * 
 * @class <code>IWInfoBalloon</code> is an example implementation of the <code>IWWindowOverlay</code> interface.
 *        <code>IWInfoBalloon</code> can be used to display informations in front of the map.
 * @extends IWWindowOverlay
 * 
 * @constructor
 * 
 * @param {IWMap}
 *            map
 * @param {IWCoordinate}
 *            coordinate
 * @param {Object}
 *            [content] DOMElement or String
 * 
 * @author JAN, KUN
 * @since 0.66
 */
function DPInfoBalloon(map, coordinate, content)		
{
	// ********************************************************************
	// First we call the superclass constructor
	// ********************************************************************
	
	IWWindowOverlay.call(this, map, coordinate);

	// ********************************************************************
	// * Private attributes
	// ********************************************************************

	var self = this;
	var size = new IWSize(240, 180);
	

	var panMap = true;
	var borderWidth = 20;
	var borderHeight = 32;
	var arrowHeigth = 18;
	var arrowWidth=31;

	// ********************************************************************
	// * GUI Elements
	// ********************************************************************
	var container = this.getContainer();	
	var divMain = iw.create('div');	
	var divContent = iw.create('div');	
	var divImageArrow = iw.create('div');
	var imgClose = iw.create('div');
	var logger = log4javascript.getLogger('IWInfoBalloon');	

	// ********************************************************************
	// * Setup for multi language support
	// ********************************************************************

	var pack = new IWLanguagePack();
	pack.addLanguage(new IWLanguage('de', iwconst.LOCAL_APP_URL + 'lang/IWInfoBalloon.lang.de'));
	pack.addLanguage(new IWLanguage('en', iwconst.LOCAL_APP_URL + 'lang/IWInfoBalloon.lang.en'));
	pack.addLanguage(new IWLanguage('es', iwconst.LOCAL_APP_URL + 'lang/IWInfoBalloon.lang.es'));
	pack.addLanguage(new IWLanguage('fr', iwconst.LOCAL_APP_URL + 'lang/IWInfoBalloon.lang.fr'));
	pack.addLanguage(new IWLanguage('tr', iwconst.LOCAL_APP_URL + 'lang/IWInfoBalloon.lang.tr'));
	pack.addLanguage(new IWLanguage('it', iwconst.LOCAL_APP_URL + 'lang/IWInfoBalloon.lang.it'));

	IWMultiLanguageSupport.call(this, map, pack);

	// ********************************************************************
	// * Public methods
	// ********************************************************************

	/**
	 * If the whole popup should be visible in the map-viewport after appending, set "true". If not, set "false". Then
	 * its possible that the popup intersects the map-viewport-bounds. Default is "true".
	 * 
	 * @param {Bool}
	 *            panMapBool
	 * @return {void}
	 */
	this.setAutoPan = function(panMapBool)
	{
		panMap = panMapBool;
	};

	/**
	 * Returns the content of the infoballoon.
	 * 
	 * @return {Object}
	 */
	this.getContent = function()
	{
		return content;
	};

	/**
	 * Sets the content of the infoballoon.
	 * 
	 * @param {Object}
	 *            newContent the new content of the infoballoon
	 * @return {void}
	 */
	this.setContent = function(newContent)
	{
		content = newContent;
	};

	/**
	 * We use the callback method for positioning the map and displaying the info balloon.
	 * 
	 * @return {void}
	 */
	this.afterAppend = function()
	{
		logger.info('Calling afterAppend.');
		try{
			if(PIE.attach){
				PIE.attach(divMain);
				PIE.attach(divImageArrow);
			}
		}
		catch(Exception){			
		}
		
		
		container.style.visibility = 'visible';
		
		if (panMap)
		{
			var position = iw.absolute(container, map.getContainer());

			// ********************************************************************
			// * If the coordinate is inside the visible map area we use the panBy
			// * method to adjust the infoballoon at the screen. Otherwise we use
			// * the setCenter method to center the infoballoon.
			// ********************************************************************

			if (map.getBounds().containsCoordinate(coordinate))
			{
				var offsetRight = position.getX() + size.getWidth() + borderWidth + borderWidth 
						- map.getOptions().getSize().getWidth();
				var offsetLeft = position.getX();
				var offsetTop = position.getY() ;
				var offsetBottom = position.getY() + size.getHeight() + borderHeight + borderHeight 
						- map.getOptions().getSize().getHeight();

				if (offsetRight > 0 || offsetLeft < 0 || offsetTop < 0 || offsetBottom > 0)
				{
					var x = 0;
					var y = 0;

					if (offsetRight > 0)
					{
						x = -offsetRight;
					}
					else
						if (offsetLeft < 0)
						{
							x = -offsetLeft;
						}

					if (offsetTop < 0)
					{
						y = -offsetTop;
					}
					else
						if (offsetBottom > 0)
						{
							y = -offsetBottom;
						}

					map.panBy(new IWPoint(x, y), true);
				}
			}
			else
			{
				// ********************************************************************
				// * We adjust the infoballoon at the screen by calculating a new
				// * center coordinate.
				// ********************************************************************

				var projection = map.getCurrentMapType().getProjection();

				var pixelCoordinate = projection.meterToPixel(coordinate);

				// We calculate the y offset in pixel
				var pixelOffsetY = this.getSize().getHeight() / 2;
				var centerX = pixelCoordinate.getX();
				var centerY = pixelCoordinate.getY() - pixelOffsetY;
				var pixelCenter = new IWPoint(centerX, centerY);
				map.setCenter(projection.pixelToMeter(pixelCenter));
			}
		}
	};

	/**
	 * Resizes the balloon to the specified size.
	 * 
	 * @param {IWSize}
	 *            size the new size of the infoballoon
	 * @return {void}
	 */
	this.setSize = function(newSize)
	{
		logger.info('Calling setSize with ' + size);

		iw.strict( [ IWSize ], [ size ]);
		size = newSize;

		resize();

		this.setAnchor(new IWPoint(-(size.getWidth() / 2 + arrowWidth/2),
				-(size.getHeight() + borderHeight + borderHeight + arrowHeigth)));
	};

	/**
	 * Returns the size of the infoballoon.
	 * 
	 * @return {IWSize}
	 */
	this.getSize = function()
	{
		return size;
	};

	/**
	 * Destroys the infoballoon. Releases all DOM references and event listeners.
	 * 
	 * Call this method after the infoballoon has been removed from the map by calling the
	 * <code>removeWindowOverlay</code> method.
	 * 
	 * @return {void}
	 */
	this.destroy = function()
	{
		logger.info('Calling destroy');
		try{
			if(PIE.detach){
				PIE.detach(divMain);				
				PIE.detach(divImageArrow);
			}
		}
		catch(Exception){			
		}
		IWEventManager.clearInstanceListeners(this);

		this.destroyMultiLanguageSupport();
		this.destroyWindowOverlay();

		content = null;
		divMain = null;
		divContent = null;		
		divImageArrow = null;
		imgClose = null;
		container = null;
	};

	/**
	 * Returns a string representation of this infoballoon.
	 * 
	 * @return {String}
	 */
	this.toString = function()
	{
		return '[DPInfoBalloon]';
	};

	// ********************************************************************
	// * Private methods
	// ********************************************************************

	/**
	 * Creates the GUI.
	 * 
	 * @private
	 * @return {void}
	 */
	function buildGUI()
	{
		logger.debug('Calling buildGUI');		
		container.style.height = size.getHeight() + borderHeight + borderHeight + 'px';
		container.style.width = size.getWidth() + borderWidth + borderWidth + 'px';
		container.style.visibility = 'hidden';

		// ********************************************************************
		// * Append the main DIV to our container
		// ********************************************************************
			
		iw.append(container, divMain);		
		divMain.style.position = 'absolute';
		divMain.style.top = '0px';
		divMain.style.left = '0px';
		divMain.style.width = size.getWidth() + 'px';
		divMain.style.height = size.getHeight() + 'px';
		divMain.className='infolayer-content';
		

		// ********************************************************************
		// * Append the content DIV
		// ********************************************************************

		divContent.id = 'divContent';
		iw.append(divMain, divContent);
		divContent.style.position = 'absolute';
		divContent.style.top = borderHeight + 'px';
		divContent.style.left = borderWidth + 'px';
		divContent.style.width = size.getWidth() + 'px';
		divContent.style.height = size.getHeight() + 'px';
		divContent.style.overflow = 'hidden';

		// ********************************************************************
		// * Append the user content DIV
		// ********************************************************************

		var div = iw.create('div');
		div.style.overflow = 'hidden';
		content.style.paddingTop = '2px';
		
		iw.append(divContent, div);
		iw.append(div, content);

		// ********************************************************************
		// * Append the close image
		// ********************************************************************
		
		iw.append(divMain, imgClose);
		imgClose.title = imgClose.alt = iExtension.getLanguage().get('plzsuche_popup_close');
		imgClose.className='imgclose imgclosegrund';

		// ********************************************************************
		// * Append the arrow image		
		// ********************************************************************

		iw.append(container, divImageArrow);
		divImageArrow.className='infolayer-pointer';	
		
		divImageArrow.style.position = 'absolute';
		divImageArrow.style.top = '0px';
		divImageArrow.style.height = arrowHeigth + 'px';
		divImageArrow.style.width = '31px';
		divImageArrow.style.left = Math.round(size.getWidth() / 2) + 'px';

		imgClose.onclick = function()
		{
			map.removeWindowOverlay(self);
		};
		imgClose.onmousedown = function()
		{
			imgClose.className='imgclose imgclosedown';
		};
		imgClose.onmouseup = function()
		{
			imgClose.className='imgclose imgclosegrund';
		};
	}

	/**
	 * Resizes the GUI.
	 * 
	 * @private
	 * @return {void}
	 */
	function resize()
	{
		logger.debug('Calling resize.');

		var w = size.getWidth();
		var h = size.getHeight();

		container.style.height = h + borderHeight + borderHeight + 'px';
		container.style.width = w + borderWidth + borderWidth + 'px';

		divMain.style.width = w + borderWidth + borderWidth + 'px';
		divMain.style.height = h + borderHeight + borderHeight + 'px';

		divContent.style.width = w + 'px';
		divContent.style.height = h + 'px';	

		// substract one pixel to overlay the border
		divImageArrow.style.top = h + borderHeight + borderHeight + 'px';
		divImageArrow.style.left = Math.round(w / 2) + 'px';

	}

	// ********************************************************************
	// * Constructor implementation
	// ********************************************************************
	
	buildGUI();

	// ********************************************************************
	// * Sets the default anchor for this overlay
	// ********************************************************************

	this.setAnchor(new IWPoint(-(size.getWidth() / 2), -(size.getHeight())));	

	// ********************************************************************
	// * Loads the language pack for the control
	// ********************************************************************

	this.loadLanguagePack(map.getOptions().getLanguage());
}
