/* -------------------------------------------------------------------------- *
 *   Experience Javascript Library (version 1.0b)
 *  (c) 2007 Ahmed Saad <ahmeds@users.sourceforge.net>
 *
 *  Experience is freely distributable under the terms of an MIT-style license.
 *  For details, see project website at http://experience.sf.net
 * -------------------------------------------------------------------------- */

// Panorama component
experience.panorama  =  {

    Version : '0.2',

    //// MNEMONICS ////////////////////////////////////////////

    ZOOM_IN : 1,
    ZOOM_OUT : -1,
    ZOOM_ONE2ONE : 0,
    MOVE_DOWN : 1,
    MOVE_UP :  2,
    MOVE_RIGHT : 3,
    MOVE_LEFT : 4,
    BUTTON_PRESSED : 1,
    BUTTON_RELAXED : 0,

    Viewer : function(userParams) {
    
        //// PRIVATE FIELDS //////////////////////////////////////

        this.Params = $H({
            ZoomFactor : 0.05, // %
            MoveBy : 2, // px
            MoveRate :  15, // ms
            ReversePanning : false,
            ReverseScrolling : true,
			// this is a default, is normally set in main web page (view.html)
            InnerUpperOffset : 40, // px 
            ShowStatus : true, 
            ShowNavigator : false, //true,
            ShowZoomSelectBox : true,
            IconDirectory : 'icons',
            IconExtension : '.gif', 
            RenderIn: null // an element or an id
        }),

        this.isBeingDragged = false;
        this.lastLeft = this.lastTop = this.lastX = this.lastY = null;
        this.originalWidth = this.originalHeight = null;
        this.timeOutId = null;
        this.isMaximizedInstance = false;
        this.onFullWindowListeners = [];
        this.onUnFullWindowListeners = [];

        //// PUBLIC METHODS //////////////////////////////////////////////////////

        this.show = experience.panorama.show;
        this.hide = experience.panorama.hide;
        this.setImage = experience.panorama.setImage;
        this.getImage = experience.panorama.getImage;
        this.addOnFullWindowListener = experience.panorama.addOnFullWindowListener;
        this.removeOnFullWindowListener = experience.panorama.removeOnFullWindowListener;
        this.addOnUnFullWindowListener = experience.panorama.addOnUnFullWindowListener;
        this.removeOnUnFullWindowListener = experience.panorama.removeOnUnFullWindowListener;

        //// PRIVATE METHODS /////////////////////////////////////////////////////

        this.getImageResource = experience.panorama.getImageResource;
        this.panLimit = experience.panorama.panLimit;
		this.zoom_ideal = experience.panorama.zoom_ideal;
		this.position_console = experience.panorama.position_console;
        this.positionImage = experience.panorama.positionImage;
        this.positionCanvas = experience.panorama.positionCanvas;
        this.setStatus = experience.panorama.setStatus;
        this.fireListeners = experience.panorama.fireListeners;

        //// VALIDATION //////////////////////////////////////////////////////////
        if (
              typeof(userParams['ImageURL']) != 'undefined' &&
              (
                typeof(userParams['ImageWidth']) == 'undefined' || 
                typeof(userParams['ImageHeight']) == 'undefined'
              )
           )
        {
            throw new Error("Experience::Panorama: You have to specify ImageWidth and ImageHeight when calling " +
                              "initialize() passing an ImageURL");
        }

        //// INITIALIZATION /////////////////////////////////////////////

        this.Params.merge(userParams);

        // construct canvas and all
        this.canvas = document.createElement('div');
        this.canvas.className = "panoramaCanvas";
        this.canvas.style.cursor = experience.panorama.getGrabCursor();
		this.canvas.style.backgroundImage =
				"url(" + theme_path + geo.background_image + ")";
        this.positionCanvas(this.Params.RenderIn != null);

        // A queue for childern to be added to the canvas
        var childernQueue = [];

// this should be conditional on something??? should only be viewable if a viewer.show was called
//        var closeImg = this.closeImg  = document.createElement('img');
//        closeImg.className = 'panoramaCloseIcon';
//        closeImg.title = experience.tr("Close", experience.panorama.Locales);

//        if (this.Params.RenderIn){
//            Event.observe(closeImg, 'click', experience.panorama.toggleFullWindow.bindAsEventListener(this));
//            closeImg.src = this.getImageResource('go_fullwindow');
//            closeImg.title = closeImg.alt = experience.tr("Go Full-Window", experience.panorama.Locales);
//        } else {
//            Event.observe(closeImg, 'click', experience.panorama.hide.bindAsEventListener(this));
//            closeImg.src = this.getImageResource('close');
//            closeImg.title = closeImg.alt = experience.tr("Close", experience.panorama.Locales);
//        }

//        childernQueue.push(closeImg);

/*        var aboutIcon = document.createElement('img');
        aboutIcon.className = 'panoramaAboutIcon';
        aboutIcon.src = this.getImageResource('about');
        aboutIcon.title = aboutIcon.alt = experience.tr("Help", experience.panorama.Locales);
        Event.observe(aboutIcon, 'click', experience.panorama.showHelp.bindAsEventListener(this));
        childernQueue.push(aboutIcon);
*/

//        var zoomInIcon = document.createElement('img');
//        zoomInIcon.className = 'panoramaZoomInIcon';
//        zoomInIcon.src = this.getImageResource('zoom_in');
//        zoomInIcon.title = zoomInIcon.alt = experience.tr("Zoom In", experience.panorama.Locales);
//        Event.observe(zoomInIcon, 'click', 
//                experience.panorama.zoom.bindAsEventListener(this, experience.panorama.ZOOM_IN));
//        childernQueue.push(zoomInIcon);


/*        var zoomOutIcon = document.createElement('img');
        zoomOutIcon.className = 'panoramaZoomOutIcon';
        zoomOutIcon.src = this.getImageResource('zoom_out');;
        zoomOutIcon.title = zoomOutIcon.alt = experience.tr("Zoom Out", experience.panorama.Locales);
        Event.observe(zoomOutIcon, 'click', 
                experience.panorama.zoom.bindAsEventListener(this, experience.panorama.ZOOM_OUT));
        childernQueue.push(zoomOutIcon);
*/

/*        var restoreSizeIcon = document.createElement('img');
        restoreSizeIcon.className = 'panoramaRestoreSizeIcon';
        restoreSizeIcon.src = this.getImageResource('restore_size');;
        restoreSizeIcon.title = restoreSizeIcon.alt =  
                experience.tr("View 100%", experience.panorama.Locales);
        Event.observe(restoreSizeIcon, 'click', 
                experience.panorama.zoom.bindAsEventListener(this, experience.panorama.ZOOM_RESTORE_SIZE));
        childernQueue.push(restoreSizeIcon);
*/


/*        var restorePositionIcon = document.createElement('img');
        restorePositionIcon.className = 'panoramaRestorePositionIcon';
        restorePositionIcon.src = this.getImageResource('restore_position');
        restorePositionIcon.title = restorePositionIcon.alt = 
            experience.tr("Restore Original Position", experience.panorama.Locales);
        Event.observe(restorePositionIcon, 'click', 
            experience.panorama.positionImage.bindAsEventListener(this));
        childernQueue.push(restorePositionIcon);
*/


		/* graphic console */
        var b_z_all_p = document.createElement('img');
        b_z_all_p.className = 'panoramaNavButton';
		b_z_all_p.src = theme_path + geo.button_z_all_press_image;
		b_z_all_p.style.visibility = 'hidden';

        var b_z_all = document.createElement('img');
		this.b_z_all = b_z_all;
        b_z_all.className = 'panoramaNavButton';
        b_z_all.src = theme_path + geo.button_z_all_image;
		b_z_all.style.visibility = 'hidden';
        Event.observe(b_z_all, 'click', 
                experience.panorama.positionImage.bindAsEventListener(this));
        Event.observe(b_z_all, 'mousedown',
                experience.panorama.button_look.bindAsEventListener(this, 'all', experience.panorama.BUTTON_PRESSED));
        Event.observe(b_z_all, 'mouseup',
                experience.panorama.button_look.bindAsEventListener(this, 'all', experience.panorama.BUTTON_RELAXED));
        Event.observe(b_z_all, 'mouseout',
                experience.panorama.button_look.bindAsEventListener(this, 'all', experience.panorama.BUTTON_RELAXED));
        childernQueue.push(b_z_all);





        var b_z_one_p = document.createElement('img');
        b_z_one_p.className = 'panoramaNavButton';
		b_z_one_p.src = theme_path + geo.button_z_one_press_image;
		b_z_one_p.style.visibility = 'hidden';

        var b_z_one = document.createElement('img');
		this.b_z_one = b_z_one;
        b_z_one.className = 'panoramaNavButton';
        b_z_one.src = theme_path + geo.button_z_one_image;
		b_z_one.style.visibility = 'hidden';
        Event.observe(b_z_one, 'click', 
                experience.panorama.zoom.bindAsEventListener(this, experience.panorama.ZOOM_ONE2ONE));
        Event.observe(b_z_one, 'mousedown',
                experience.panorama.button_look.bindAsEventListener(this, 'one', experience.panorama.BUTTON_PRESSED));
        Event.observe(b_z_one, 'mouseup',
                experience.panorama.button_look.bindAsEventListener(this, 'one', experience.panorama.BUTTON_RELAXED));
        Event.observe(b_z_one, 'mouseout',
                experience.panorama.button_look.bindAsEventListener(this, 'one', experience.panorama.BUTTON_RELAXED));
        childernQueue.push(b_z_one);




        var b_z_in_p = document.createElement('img');
        b_z_in_p.className = 'panoramaNavButton';
		b_z_in_p.src = theme_path + geo.button_z_in_press_image;
		b_z_in_p.style.visibility = 'hidden';

        var b_z_in = document.createElement('img');
		this.b_z_in = b_z_in;
        b_z_in.className = 'panoramaNavButton';
        b_z_in.src = theme_path + geo.button_z_in_image;
		b_z_in.style.visibility = 'hidden';
        Event.observe(b_z_in, 'click', 
                experience.panorama.zoom.bindAsEventListener(this, experience.panorama.ZOOM_IN));
        Event.observe(b_z_in, 'mousedown',
                experience.panorama.button_look.bindAsEventListener(this, 'in', experience.panorama.BUTTON_PRESSED));
        Event.observe(b_z_in, 'mouseup',
                experience.panorama.button_look.bindAsEventListener(this, 'in', experience.panorama.BUTTON_RELAXED));
        Event.observe(b_z_in, 'mouseout',
                experience.panorama.button_look.bindAsEventListener(this, 'in', experience.panorama.BUTTON_RELAXED));
        childernQueue.push(b_z_in);




        var b_z_out_p = document.createElement('img');
        b_z_out_p.className = 'panoramaNavButton';
		b_z_out_p.src = theme_path + geo.button_z_out_press_image;
		b_z_out_p.style.visibility = 'hidden';

        var b_z_out = document.createElement('img');
		this.b_z_out = b_z_out;
        b_z_out.className = 'panoramaNavButton';
        b_z_out.src = theme_path + geo.button_z_out_image;
		b_z_out.style.visibility = 'hidden';
        Event.observe(b_z_out, 'click', 
                experience.panorama.zoom.bindAsEventListener(this, experience.panorama.ZOOM_OUT));
        Event.observe(b_z_out, 'mousedown',
                experience.panorama.button_look.bindAsEventListener(this, 'out', experience.panorama.BUTTON_PRESSED));
        Event.observe(b_z_out, 'mouseup',
                experience.panorama.button_look.bindAsEventListener(this, 'out', experience.panorama.BUTTON_RELAXED));
        Event.observe(b_z_out, 'mouseout',
                experience.panorama.button_look.bindAsEventListener(this, 'out', experience.panorama.BUTTON_RELAXED));
        childernQueue.push(b_z_out);







        var b_help_p = document.createElement('img');
        b_help_p.className = 'panoramaNavButton';
		b_help_p.src = theme_path + geo.button_help_press_image;
		b_help_p.style.visibility = 'hidden';

        var b_help = document.createElement('img');
		this.b_help = b_help;
        b_help.className = 'panoramaNavButton';
        b_help.src = theme_path + geo.button_help_image;
		b_help.style.visibility = 'hidden';
        Event.observe(b_help, 'click', experience.panorama.showHelp.bindAsEventListener(this));
        Event.observe(b_help, 'mousedown',
                experience.panorama.button_look.bindAsEventListener(this, 'help', experience.panorama.BUTTON_PRESSED));
        Event.observe(b_help, 'mouseup',
                experience.panorama.button_look.bindAsEventListener(this, 'help', experience.panorama.BUTTON_RELAXED));
        Event.observe(b_help, 'mouseout',
                experience.panorama.button_look.bindAsEventListener(this, 'help', experience.panorama.BUTTON_RELAXED));
        childernQueue.push(b_help);





        var console = document.createElement('img');
		this.console = console;
        console.className = 'panoramaNavButton';
		console.style.visibility = 'hidden';


		if ( this.Params.DetailsURL && geo.console_details_image )
			console.src = theme_path + geo.console_details_image;
		else
			console.src = theme_path + geo.console_image;


// make this monitor load to show at least 3 seconds before hiding
		if ( this.Params.DetailsURL )
			Event.observe(console, 'click',
					experience.panorama.load_url.bindAsEventListener(this,
					this.Params.DetailsURL ));
		else
	        Event.observe(console, 'click',
					experience.panorama.load_url.bindAsEventListener(this,
					geo.console_url ));

		Event.observe(console, 'mousemove',
				experience.panorama.handleMouseMove.bindAsEventListener(this));
//        Event.observe(console, 'mouseout',
//                experience.panorama.button_look.bindAsEventListener(this, 'unhover', 0 ));
        childernQueue.push(console);



        var console_mini = document.createElement('img');
		this.console_mini = console_mini;
        console_mini.className = 'panoramaNavButton';
        console_mini.src = theme_path + geo.console_mini_image;
		console_mini.style.visibility = 'hidden';
//        Event.observe(console_mini, 'click',
//				experience.panorama.load_url.bindAsEventListener(this,
//				'http://www.see-it.net/' ));
//        Event.observe(console_mini, 'mouseout',
//                experience.panorama.button_look.bindAsEventListener(this, 'unhover', 0 ));
        Event.observe(console_mini, 'mousemove', 
                experience.panorama.handleMouseMove.bindAsEventListener(this));
        childernQueue.push(console_mini);




		/* build frame, scottb */
		/* corners */
        var frameTL = document.createElement('img');
		this.frameTL = frameTL;
        frameTL.className = 'panoramaFrame';
        frameTL.src = theme_path + geo.frame_TL_image;
        childernQueue.push(frameTL);

        var frameTR = document.createElement('img');
		this.frameTR = frameTR;
        frameTR.className = 'panoramaFrame';
        frameTR.src = theme_path + geo.frame_TR_image;
        childernQueue.push(frameTR);

        var frameBL = document.createElement('img');
		this.frameBL = frameBL;
        frameBL.className = 'panoramaFrame';
        frameBL.src = theme_path + geo.frame_BL_image;
        Event.observe(frameBL, 'mousemove', 
                experience.panorama.handleMouseMove.bindAsEventListener(this));
        childernQueue.push(frameBL);

        var frameBR = document.createElement('img');
		this.frameBR = frameBR;
        frameBR.className = 'panoramaFrame';
        frameBR.src = theme_path + geo.frame_BR_image;
        childernQueue.push(frameBR);


		/* sides */
        var frameL = document.createElement('img');
		this.frameL = frameL;
        frameL.className = 'panoramaFrame';
        frameL.src = theme_path + geo.frame_L_image;
        Event.observe(frameL, 'mousemove', 
                experience.panorama.handleMouseMove.bindAsEventListener(this));
        childernQueue.push(frameL);

        var frameT = document.createElement('img');
		this.frameT = frameT;
        frameT.className = 'panoramaFrame';
        frameT.src = theme_path + geo.frame_T_image;
        childernQueue.push(frameT);

        var frameR = document.createElement('img');
		this.frameR = frameR;
        frameR.className = 'panoramaFrame';
        frameR.src = theme_path + geo.frame_R_image;
        childernQueue.push(frameR);

        var frameB = document.createElement('img');
		this.frameB = frameB;
        frameB.className = 'panoramaFrame';
        frameB.src = theme_path + geo.frame_B_image;
        Event.observe(frameB, 'mousemove', 
                experience.panorama.handleMouseMove.bindAsEventListener(this));
        childernQueue.push(frameB);





        if (this.Params.ShowNavigator){

            var goDownIcon = document.createElement('img');
            goDownIcon.className = 'panoramaGoDownIcon';
            goDownIcon.src = this.getImageResource('go_down');
            goDownIcon.title = goDownIcon.alt =  
                experience.tr("Scrolling .. ", experience.panorama.Locales);
            Event.observe(goDownIcon, 'mouseover', 
                experience.panorama.move.bindAsEventListener(this, 
                    this.Params.ReverseScrolling? experience.panorama.MOVE_UP : experience.panorama.MOVE_DOWN));
            Event.observe(goDownIcon, 'mouseout', 
                experience.panorama.clearMoveTimeout.bindAsEventListener(this));
            childernQueue.push(goDownIcon);
            
            var goUpIcon = document.createElement('img');
            goUpIcon.className = 'panoramaGoUpIcon';
            goUpIcon.src = this.getImageResource('go_up');
            goUpIcon.title = goUpIcon.alt = 
                experience.tr("Scrolling .. ", experience.panorama.Locales);
            Event.observe(goUpIcon, 'mouseover', 
                experience.panorama.move.bindAsEventListener(this, 
                    this.Params.ReverseScrolling? experience.panorama.MOVE_DOWN : experience.panorama.MOVE_UP));
            Event.observe(goUpIcon, 'mouseout', 
                experience.panorama.clearMoveTimeout.bindAsEventListener(this));
            childernQueue.push(goUpIcon);
            

            var goRightIcon = document.createElement('img');
            goRightIcon.className = 'panoramaGoRightIcon';
            goRightIcon.src = this.getImageResource('go_right');
            goRightIcon.title = goRightIcon.alt = experience.tr("Scrolling .. ", experience.panorama.Locales);
            Event.observe(goRightIcon, 'mouseover', experience.panorama.move.bindAsEventListener(this, 
                    this.Params.ReverseScrolling? experience.panorama.MOVE_LEFT : experience.panorama.MOVE_RIGHT));
            Event.observe(goRightIcon, 'mouseout', 
                    experience.panorama.clearMoveTimeout.bindAsEventListener(this));
            childernQueue.push(goRightIcon);
            

            var goLeftIcon = document.createElement('img');
            goLeftIcon.className = 'panoramaGoLeftIcon';
            goLeftIcon.src = this.getImageResource('go_left');
            goLeftIcon.title = goLeftIcon.alt =  
                    experience.tr("Scrolling .. ", experience.panorama.Locales);
            Event.observe(goLeftIcon, 'mouseover', 
                    experience.panorama.move.bindAsEventListener(this, 
                        this.Params.ReverseScrolling? experience.panorama.MOVE_RIGHT : experience.panorama.LEFT));
            Event.observe(goLeftIcon, 'mouseout', 
                    experience.panorama.clearMoveTimeout.bindAsEventListener(this));
            childernQueue.push(goLeftIcon);
        }

        if (this.Params.ShowZoomSelectBox){
            var zoomDropDown = document.createElement('select');
            zoomDropDown.className = 'panoramaZoomDropdown';
            this.indicatorOption = document.createElement('option');
            this.indicatorOption.className = 'panoramaIndicator';
            this.indicatorOption.innerHTML = '% 100';
            this.indicatorOption.value = '#';
            this.indicatorOption.selected = true;
            zoomDropDown.appendChild(this.indicatorOption);
  //          var zoomPercentages = [5, 10, 15, 25, 50, 75, 90, 100, 200];
  //          for(var x = 0; x < zoomPercentages.length; x++){
  //              var opt = document.createElement('option');
  //              opt.innerHTML = zoomPercentages[x];
  //              opt.value = zoomPercentages[x]/100;
  //              zoomDropDown.appendChild(opt);
   //         }
//            Event.observe(zoomDropDown, 'change', 
//                experience.panorama.handleZoomPercentageChange.bindAsEventListener(this));
            childernQueue.push(zoomDropDown);
        }

        if (this.Params.ShowStatus){
            this.status = document.createElement('span');
            this.status.className = "panoramaStatus";
            childernQueue.push(this.status);
// put back in when we get a better graphic
//            this.setStatus(null, "<img src='" + theme_path + geo.loading_image + "' />");
        }

		/* main image */
        this.image = document.createElement('img');
        this.image.className = "panoramaImage";
        this.image.src = this.Params.ImageURL;
        this.image.alt = this.Params.ImageURL;
        this.image.style.position = "relative";
        this.image.style.width  =  this.Params.ImageWidth + "px";
        this.image.style.height =  this.Params.ImageHeight + "px";
        this.positionImage();
        childernQueue.push(this.image);



		if ( geo.background_link_image )
		{
	        var back_link = document.createElement('img');
			back_link.className = 'panoramaNavButton';
			back_link.src = theme_path + geo.background_link_image;
			Event.observe(back_link, 'click',
					experience.panorama.load_url.bindAsEventListener(this,
					'http://www.see-it.net/' )); //geo.background_link_url ));
			childernQueue.push(back_link);
		}




		this.load_finished = 0;
        Event.observe(this.image, 'load', experience.panorama.setStatus.bindAsEventListener(this, ""));
        Event.observe(this.image, 'error', 
                        experience.panorama.setStatus.bindAsEventListener(this, 
                                experience.tr("Could not load image.", experience.panorama.Locales)));

        // Misc. handlers ..
        Event.observe(this.canvas, 'mousedown', 
                experience.panorama.handleMouseDown.bindAsEventListener(this));
        Event.observe(this.canvas, 'mousemove', 
                experience.panorama.handleMouseMove.bindAsEventListener(this));
        Event.observe(document, 'mouseup', 
                experience.panorama.handleMouseUp.bindAsEventListener(this));

        var wheelHandler = experience.panorama.handleMouseWheel.bindAsEventListener(this);
        Event.observe(this.canvas, "DOMMouseScroll", wheelHandler, false); // Mozilla
        Event.observe(this.canvas, "mousewheel", wheelHandler, false);

        // add elements to the canvas (in reverse for proper z-Index ordering)
        for(var i = childernQueue.length - 1; i >= 0; i--){
            this.canvas.appendChild(childernQueue[i]);
        } 



		/* position stuff */
		var canvasWidth  = Element.getWidth(this.canvas);
		var canvasHeight = Element.getHeight(this.canvas);

        var imLeft = parseFloat(this.image.style.left);


		/* geometry */
		this.console_width = geo.console_width; //319;
		this.console_height = geo.console_height; //105;

		this.button_width = geo.button_width; //50;
		this.button_height = geo.button_height; //40;

		this.console_mini_width = geo.console_mini_width; //269;
		this.console_mini_height = geo.console_mini_height; //21;

		 /* geometry position, static */
		this.console_mini_x = geo.console_mini_x; //0; /* relative to console */
		this.button_x = geo.button_x; //57; /* relative to console */


		/* set dynamic */
		this.last_canvasWidth = canvasWidth;
		this.last_canvasHeight = canvasHeight;
		this.position_console ( imLeft, canvasWidth, canvasHeight );

		/* now that their in the right spot, unhide them */
		this.console.style.visibility = 'visible';
		this.b_help.style.visibility = 'visible';
		this.b_z_out.style.visibility = 'visible';
		this.b_z_in.style.visibility = 'visible';
		this.b_z_one.style.visibility = 'visible';
		this.b_z_all.style.visibility = 'visible';
		this.console_showing = 1;

		// will hide it after five seconds, sooner if the user hovers
		var d = new Date();
		this.console_show_till = d.getTime ( ) + 5000;
    },

    //// PUBLIC METHODS ///////////////////////////////////////////////////////    

    show : function(){
        if(!this.Params.RenderIn){
            this.fireListeners(this.onFullWindowListeners);
        }

        this.canvas.style.visibility = 'visible';
    },

    hide : function(){
        if(!this.Params.RenderIn){
            this.fireListeners(this.onUnFullWindowListeners);
        }

        this.canvas.style.visibility = 'hidden';
    },



    toggleFullWindow : function(e){
        //experience.Console.log(this.isMaximizedInstance);

        if (this.isMaximizedInstance){ // minimize
            this.closeImg.src = this.getImageResource('go_fullwindow');
            this.closeImg.title = this.closeImg.alt = experience.tr("Go Full-Window", experience.panorama.Locales);

            this.positionCanvas(true);
            this.isMaximizedInstance = false;
        } else { // maximize
            this.closeImg.src = this.getImageResource('unfullwindow');
            this.closeImg.title = this.closeImg.alt = experience.tr("Restore", experience.panorama.Locales);

            this.positionCanvas(false);
            this.isMaximizedInstance = true;
        }
    },

    getImage : function (){
        return [this.Params.ImageURL, this.Params.ImageWidth, this.Params.ImageHeight];
    },

    setImage : function(url, width, height){
        this.image.src = this.Params.ImageURL = url;
        this.image.style.width = this.Params.ImageWidth  = width + "px";
        this.image.style.height = this.Params.ImageHeight = height + "px";
        this.positionImage();
    },

    addOnFullWindowListener : function(listener){
        this.onFullWindowListeners[this.onFullWindowListeners.length] = listener;
    },

    removeOnFullWindowListener : function(listener){
        if (this.onFullWindowListeners.include(listener)){
            this.onFullWindowListeners.splice(this.onFullWindowListeners.indexOf(listener), 1);
        }
    },

    addOnUnFullWindowListener : function(listener){
        this.onUnFullWindowListeners[this.onUnFullWindowListeners.length] = listener;
    },

    removeOnUnFullWindowListener : function(listener){
        if (this.onUnFullWindowListeners.include(listener)){
            this.onUnFullWindowListeners.splice(this.onUnFullWindowListeners.indexOf(listener), 1);
        }
    },

    //// PRIVATE METHODS ///////////////////////////////////////////////////////

    fireListeners : function(listeners){
        for(var i =0; i < listeners.length; i++){
            listeners[i]();
        }
    }, 

    setStatus : function(e, html)
	{
		if ( html == '' )
			this.load_finished = 1;

        if (this.Params.ShowStatus){
            this.status.innerHTML = html;
        }
    },

    showHelp : function(e){
        alert(experience.tr("HelpText", experience.panorama.Locales));
    },


	load_url : function(e, url )
	{
		location.assign ( url );
	},


	button_look : function(e, button, look )
	{
//		if ( button == 'unhover' )
//		{
//			alert ( 'elvis has left the building' );
	//		var x = Event.pointerX(e);
//alert ( x );
//			var y = Event.pointerY(e);
//		}
//		else 
		if ( button == 'all' )
		{
			if ( look )
				this.b_z_all.src = theme_path + 'button_z_all_press.jpg';
			else
				this.b_z_all.src = theme_path + 'button_z_all.jpg';
		}
		else if ( button == 'one' )
		{
			if ( look )
				this.b_z_one.src = theme_path + 'button_z_one_press.jpg';
			else
				this.b_z_one.src = theme_path + 'button_z_one.jpg';
		}
		else if ( button == 'in' )
		{
			if ( look )
				this.b_z_in.src = theme_path + 'button_z_in_press.jpg';
			else
				this.b_z_in.src = theme_path + 'button_z_in.jpg';
		}
		else if ( button == 'out' )
		{
			if ( look )
				this.b_z_out.src = theme_path + 'button_z_out_press.jpg';
			else
				this.b_z_out.src = theme_path + 'button_z_out.jpg';
		}
		else if ( button == 'help' )
		{
			if ( look )
				this.b_help.src = theme_path + 'button_help_press.jpg';
			else
				this.b_help.src = theme_path + 'button_help.jpg';
		}


//		alert ( 'button_look called with ' + look );
//        if(!this.Params.RenderIn){
//            this.fireListeners(this.onUnFullWindowListeners);
 //       }

  //      this.canvas.style.visibility = 'hidden';
    },





	position_console : function( imLeft, canvasWidth, canvasHeight )
	{
		/* dynamic position */
		this.console_mini_y = canvasHeight - this.console_mini_height; /* absolute */
		this.button_y = canvasHeight - this.button_height; /* absolute */


		/* put it just inside the corner */
		this.console_x = imLeft + 
				geo.frame_BL_width - geo.frame_thickness + 10;

		/* bump 2/3 point back to the centerline */
		if ( this.console_x + this.console_width * .66 > canvasWidth / 2 )
			this.console_x = canvasWidth / 2 - this.console_width;

		/* bump back on screen */
		if ( this.console_x < 0 )
			this.console_x = 0;

		/* bump back on screen the other way */
		if ( this.console_x + this.console_width > canvasWidth )
			this.console_x = canvasWidth - this.console_width;


		this.console_y = canvasHeight - ( this.console_height + geo.console_y );


		this.console_mini.style.top = this.console_mini_y + 'px';
		this.console_mini.style.left = this.console_x + this.console_mini_x + "px";

		this.console.style.top = this.console_y + 'px';
		this.console.style.left = this.console_x + "px";


		this.b_help.style.top = canvasHeight - this.button_height + "px";
		this.b_help.style.left = this.console_x + this.button_x + "px";

		this.b_z_out.style.top = canvasHeight - this.button_height + "px";
		this.b_z_out.style.left = this.console_x + this.button_x + this.button_width + "px";

		this.b_z_in.style.top = canvasHeight - this.button_height + "px";
		this.b_z_in.style.left = this.console_x + this.button_x + this.button_width * 2 + "px";

		this.b_z_one.style.top = canvasHeight - this.button_height + "px";
		this.b_z_one.style.left = this.console_x + this.button_x + this.button_width * 3 + "px";

		this.b_z_all.style.top = canvasHeight - this.button_height + "px";
		this.b_z_all.style.left = this.console_x + this.button_x + this.button_width * 4 + "px";
    },



    panLimit : function( left, top, width, height )
	{
		var image = this.image;

		var canvasWidth  = Element.getWidth(this.canvas);
		var canvasHeight = Element.getHeight(this.canvas);
		var x_extra = this.Params.InnerUpperOffset * 2;
		var y_extra = this.Params.InnerUpperOffset * 2;
		if ( x_extra < ( canvasWidth - width ))
			x_extra = ( canvasWidth - width );
		if ( y_extra < ( canvasHeight - height ))
			y_extra = ( canvasHeight - height );

		if ( left + width < canvasWidth - ( x_extra / 2 ))
			left = ( canvasWidth - ( x_extra / 2 )) - width;
		if ( top + height < canvasHeight - ( y_extra / 2 ))
			top = ( canvasHeight - ( y_extra / 2 )) - height;

		if ( left > x_extra / 2 )
			left = x_extra / 2;
		if ( top > y_extra / 2 )
			top = y_extra / 2;

		this.image.style.width  = width  + "px";
		this.image.style.height = height + "px";
		this.image.style.left =  left + "px"; 
		this.image.style.top  =  top + "px"; 


		/* adjust frame */
		var thickness = geo.frame_thickness;

		this.frameTL.style.top = top - thickness + "px";
		this.frameTL.style.left = left - thickness + "px";
		this.frameTL.style.width = geo.frame_TL_width + "px";
		this.frameTL.style.height = geo.frame_TL_height + 'px';

		this.frameT.style.top = top - thickness + "px";
		this.frameT.style.left = left + "px";
		this.frameT.style.width = width + "px";
		this.frameT.style.height = thickness + 'px';

//        var i = parseFloat(this.frameTR.style.width);
		this.frameTR.style.top = top - thickness + "px";
		this.frameTR.style.left = left + width + thickness - geo.frame_TR_width + "px";
		this.frameTR.style.width = geo.frame_TR_width + "px";
		this.frameTR.style.height = geo.frame_TR_height + 'px';

		this.frameR.style.top = top + "px";
		this.frameR.style.left = left + width + "px";
		this.frameR.style.width = thickness + "px";
		this.frameR.style.height = height + 'px';

		this.frameBR.style.top = top + height + thickness - geo.frame_BR_height + "px";
		this.frameBR.style.left = left + width + thickness - geo.frame_BR_width + "px";
		this.frameBR.style.width = geo.frame_BR_width + "px";
		this.frameBR.style.height = geo.frame_BR_height + 'px';

		this.frameB.style.top = top + height + "px";
		this.frameB.style.left = left + "px";
		this.frameB.style.width = width + "px";
		this.frameB.style.height = thickness + 'px';

		this.frameBL.style.top = top + height + thickness - geo.frame_BL_height + "px";
		this.frameBL.style.left = left - thickness + "px";
		this.frameBL.style.width = geo.frame_BL_width + "px";
		this.frameBL.style.height = geo.frame_BL_height + 'px';

		this.frameL.style.top = top + "px";
		this.frameL.style.left = left - thickness + "px";
		this.frameL.style.width = thickness + "px";
		this.frameL.style.height = height + 'px';
	},






    positionImage :  function (e)
	{
        var image = this.image;

		// detecting canvas width and height doesn't work in KHTML (and WebKit?)
			// scottb: works with safari
				// try screen.availWidth and screen.availHeight
//        if (experience.detectEngine() == "khtml"){
//            image.style.top = image.style.left = this.Params.InnerUpperOffset + "px";
  //          return;
    //    }

        var canvasWidth  = Element.getWidth(this.canvas);
        var canvasHeight = Element.getHeight(this.canvas);

        /* scottb, make the default zoom out if it's bigger than the canvas */
        /* shrink if it over fills */
        var imWidth = parseFloat(image.style.width);
        var imHeight = parseFloat(image.style.height);


        var zoom = this.zoom_ideal ( );

        /* reset using new zoom */
		imWidth = zoom * this.Params.ImageWidth;
		imHeight = zoom * this.Params.ImageHeight;


  //      image.style.width  = imWidth + "px";
  //      image.style.height = imHeight + "px";

        var percentage = ( imWidth / this.Params.ImageWidth ).toFixed(3);
        this.indicatorOption.innerHTML = "% " + (percentage * 100).toFixed(1);

		var imLeft;
		var imTop;

        // center if it doesn't fill
        if ( imWidth > canvasWidth)
		{
			imLeft = this.Params.InnerUpperOffset;
        }
		else
		{
            imLeft =  (canvasWidth / 2) -  ( imWidth / 2);
        }
//		image.style.left = imLeft + "px";


        if ( imHeight > canvasHeight)
		{
			imTop = this.Params.InnerUpperOffset;
		}
		else
		{
			imTop = (canvasHeight / 2) -  ( imHeight / 2);
        }
//		image.style.top = imTop + "px"

		this.panLimit( imLeft, imTop, imWidth, imHeight );
	},



    positionCanvas : function (isRenderIn)
	{

        if(this.canvas.parentNode){
            this.canvas.parentNode.removeChild(this.canvas);
        }

        if(isRenderIn){
            if(this.isMaximizedInstance){
                this.fireListeners(this.onUnFullWindowListeners);
            }

            $(this.Params.RenderIn).style.position = "relative";
            this.canvas.style.position = "absolute";
            this.canvas.style.left = 
                this.canvas.style.right =
                this.canvas.style.top = 
                this.canvas.style.bottom = "0px";
            this.canvas.style.height = this.canvas.style.width = "100%";
            this.canvas.style.visibility  = 'visible';

            $(this.Params.RenderIn).appendChild(this.canvas);
        } else {
            if(this.Params.RenderIn){
                this.fireListeners(this.onFullWindowListeners);
            }

            document.getElementsByTagName('body')[0].appendChild(this.canvas);

            if (experience.detectBrowser() == "ie5" || experience.detectBrowser() == "ie6"){
                this.canvas.style.position = "absolute";
                this.canvas.style.setExpression("top", 
                    "(ignoreMe = document.documentElement.scrollTop? " + 
                        "document.documentElement.scrollTop : document.body.scrollTop) + 'px'");
                this.canvas.style.setExpression("height",
                     "experience.panorama.getInnerWindowDimensions()['height']");
                this.canvas.style.setExpression("width",
                     "experience.panorama.getInnerWindowDimensions()['width']");
            } else {
                this.canvas.style.position = "fixed"
            }
        }

        //experience.Console.log(this.canvas.parentNode.tagName + "," + isRenderIn);
    },

    /**
      * Thanks to http://www.quirksmode.org/viewport/compatibility.html 
      */
    getInnerWindowDimensions: function (){
        var x,y;
        if (self.innerHeight) // all except Explorer
        {
            x = self.innerWidth;
            y = self.innerHeight;
        }
        else if (document.documentElement && document.documentElement.clientHeight)
            // Explorer 6 Strict Mode
        {
            x = document.documentElement.clientWidth;
            y = document.documentElement.clientHeight;
        }
        else if (document.body) // other Explorers
        {
            x = document.body.clientWidth;
            y = document.body.clientHeight;
        }

        return {width: x, height: y};
    },



	zoom_ideal : function( )
	{
		/* calculate ideal zooms */

        var canvasWidth  = Element.getWidth(this.canvas);
        var canvasHeight = Element.getHeight(this.canvas);

		var xZoom = ( canvasWidth - ( this.Params.InnerUpperOffset * 2 )) / this.Params.ImageWidth;
		var yZoom = ( canvasHeight - ( this.Params.InnerUpperOffset * 2 )) / this.Params.ImageHeight;

		/* choose the smaller */
		var zoom;
		if ( xZoom < yZoom )
			zoom = xZoom;
		else
			zoom = yZoom;

		return zoom;
	},



    zoom : function(e, delta)
	{

        var zoomFactor = this.Params.ZoomFactor;
        var newWidth, newHeight, newLeft, newTop = null;

        // parse current pixel dimensions to floats
        var pWidth = parseFloat(this.image.style.width);
        var pHeight = parseFloat(this.image.style.height);

        var canvasWidth  = Element.getWidth(this.canvas);
        var canvasHeight = Element.getHeight(this.canvas);

		/* calculate center point as percentage of image size */
        var xPan = (( canvasWidth / 2 ) - parseFloat ( this.image.style.left )) / pWidth;
        var yPan = (( canvasHeight / 2 ) - parseFloat ( this.image.style.top )) / pHeight;

        if (0 == delta){ // restore original size
            newWidth = eval ( this.Params.ImageWidth );
            newHeight = eval ( this.Params.ImageHeight );

            // distribute size change
        //    newLeft = (parseFloat(this.image.style.left) - ((newWidth - pWidth) / 2));
        //    newTop  = (parseFloat(this.image.style.top) - ((newHeight - pHeight) / 2)); 
        } else if (delta > 0){ // zoom in
            newWidth = (pWidth + (pWidth * zoomFactor));
            newHeight = (pHeight + (pHeight * zoomFactor));
            
            // distribute size change
        //    newLeft = (parseFloat(this.image.style.left) - ((pWidth * zoomFactor) / 2));
        //    newTop = (parseFloat(this.image.style.top) - ((pHeight * zoomFactor) / 2)); 
        } else if (delta < 0){ // zoom out

			// make zoom in exactly reversible
			var inverse_factor = 1 / ( 1 + zoomFactor );

            newWidth = pWidth * inverse_factor;
            newHeight = pHeight * inverse_factor;

            // distribute size change
        //    newLeft = (parseFloat(this.image.style.left) + ((pWidth * zoomFactor) / 2));
        //    newTop  = (parseFloat(this.image.style.top)  + ((pHeight * zoomFactor) / 2)); 
        } else {
            alert("Invalid delta value:" +  delta);
            return;
        }





		/* apply limits to zoom range: */
        var percentage = newWidth / this.Params.ImageWidth;
				// make parameter?
		if ( percentage > 2 )
		{
			/* apply maximum */
			newWidth = this.Params.ImageWidth * 2;
			newHeight = this.Params.ImageHeight * 2;
		}
		else
		{
			/* figure out minimum */
			/* first based on filling at least half the width and half the height */
//			var canvasWidth  = Element.getWidth(this.canvas);
//			var canvasHeight = Element.getHeight(this.canvas);
//			var xZoomMin = ( canvasWidth / 2 ) / this.Params.ImageWidth;
//			var yZoomMin = ( canvasHeight / 2 ) / this.Params.ImageHeight;
//			var zoomMin;
//	        if ( xZoomMin > yZoomMin )
  //  	        zoomMin = xZoomMin;
    //	    else
      //  	    zoomMin = yZoomMin;
// this went too small


	        /* twice the margin as ideal */
	        var xZoom = ( canvasWidth - ( this.Params.InnerUpperOffset * 2 )) / this.Params.ImageWidth;
	        var yZoom = ( canvasHeight - ( this.Params.InnerUpperOffset * 2 )) / this.Params.ImageHeight;

	        /* choose the smaller */
	        var zoomMin;
	        if ( xZoom < yZoom )
    	        zoomMin = xZoom;
    	    else
        	    zoomMin = yZoom;



			var zoom = this.zoom_ideal ( );


			/* allow smaller zoom if half fill minimum is less forgiving than ideal */
			if ( zoomMin > zoom /* ideal zoom */ )
				zoomMin = zoom;

			/* in the case of a very small image, do not force blowup */
			if ( zoomMin > 1 )
				zoomMin = 1;

			/* finally apply it */
			if ( percentage < zoomMin )
			{
				newWidth = this.Params.ImageWidth * zoomMin;
				newHeight = this.Params.ImageHeight * zoomMin;
			}
		}


		/* restore original center of view, panLimit will deal with edge boundries */
		newLeft = ( canvasWidth / 2 ) - ( xPan * newWidth );
		newTop = ( canvasHeight / 2 ) - ( yPan * newHeight );


		/* update indicator */
		percentage = (newWidth/this.Params.ImageWidth).toFixed(3);
		this.indicatorOption.innerHTML = "% " + (percentage * 100).toFixed(1);


		this.panLimit( newLeft, newTop, newWidth, newHeight );
//alert ( parseFloat ( this.image.style.left ));
    },


    move : function (e, toWhere){
        if (!this.isBeingDragged){
            var MOVE_BY = this.Params.MoveBy;
    
            switch(toWhere){
                case experience.panorama.MOVE_DOWN:
                    this.image.style.top = (parseFloat(this.image.style.top) + MOVE_BY) + "px";
                    break;
                case experience.panorama.MOVE_UP:
                    this.image.style.top = (parseFloat(this.image.style.top) - MOVE_BY) + "px";
                    break;
                case experience.panorama.MOVE_RIGHT:
                    this.image.style.left = (parseFloat(this.image.style.left) + MOVE_BY) + "px";
                    break;
                case experience.panorama.MOVE_LEFT:
                    this.image.style.left = (parseFloat(this.image.style.left) - MOVE_BY) + "px";
                    break;
                default:
                    experience.Console.log("Unrecognized 'toWhere' value '" + toWhere + "'");
                    return;
            }
    
            this.timeOutId = 
                setTimeout(experience.panorama.move.bind(this, null, toWhere), this.Params.MoveRate);
        }
    },

    clearMoveTimeout : function (e){
         clearTimeout(this.timeOutId);
    },

    handleZoomPercentageChange : function(e){
        var percentage = Event.element(e).value;

        if (percentage != '#'){
            var newWidth, newHeight, newLeft, newTop;
            
            newWidth  = this.Params.ImageWidth * percentage;
            newHeight = this.Params.ImageHeight * percentage;
            
            // distribute size change
            newLeft = parseFloat(this.image.style.left) - 
                            ((newWidth - parseFloat(this.image.style.width)) / 2);
            newTop  = parseFloat(this.image.style.top) - 
                            ((newHeight - parseFloat(this.image.style.height)) / 2); 
            
            // apply new size
            this.image.style.width  = newWidth  + "px";
            this.image.style.height = newHeight + "px";
            this.image.style.left   = newLeft   + "px";
            this.image.style.top    = newTop    + "px";
            
            Event.element(e).selectedIndex = 0;
            Event.element(e).options[0].innerHTML = "% " + (percentage * 100);
        }
    },

    handleMouseDown : function(e){
        if (
            (
                Event.element(e) == this.canvas ||
                Event.element(e) == this.image
            ) && Event.isLeftClick(e)
           ){

            this.isBeingDragged = true;
            this.canvas.style.cursor = experience.panorama.getGrabbingCursor();
            this.lastLeft = parseFloat(this.image.style.left);
            this.lastTop  = parseFloat(this.image.style.top);
            this.lastX = Event.pointerX(e);
            this.lastY = Event.pointerY(e);

            // I love Prototype!
            Event.stop(e);
        }
    },



	handleMouseMove : function (e)
	{
		if ( Event.element(e) == this.console )
			/* dismiss timer early cause they found the console */
			this.console_show_till = -1;


		if ( Event.element(e) == this.canvas ||
				Event.element(e) == this.image ||
				Event.element(e) == this.console_mini ||
				Event.element(e) == this.frameBL ||
				Event.element(e) == this.frameB ||
				Event.element(e) == this.frameL )
		{
			/* detect canvas resize (can we do this directly instead of here?) */
			var canvasWidth  = Element.getWidth(this.canvas);
			var canvasHeight = Element.getHeight(this.canvas);

			if ( this.last_canvasWidth != canvasWidth ||
					this.last_canvasHeight != canvasHeight )
			{
				this.last_canvasWidth = canvasWidth;
				this.last_canvasHeight = canvasHeight;

				/* determine zoomed out imLeft */
				var imLeft = ( canvasWidth -
						( this.zoom_ideal ( ) * this.Params.ImageWidth )) / 2;
				this.position_console ( imLeft, canvasWidth, canvasHeight );
			}


			if ( this.console_show_till != -1 )
			{
				var d = new Date();
				if ( d.getTime ( ) > this.console_show_till && this.load_finished )
					this.console_show_till = -1;
			}




			/* handle mousemove */
			var mouse_x = Event.pointerX(e);
			var mouse_y = Event.pointerY(e);

			if (this.isBeingDragged)
			{
											// make this a parameter?
				var sign = this.Params.ReversePanning? -3.25 : 3.25;

					/* set limits (scottb) */
				var left =  this.lastLeft + ( sign * ( mouse_x - this.lastX ));
				var top  =  this.lastTop  + ( sign * ( mouse_y - this.lastY ));

				this.panLimit( left, top, parseFloat(this.image.style.width), parseFloat(this.image.style.height));
			}
			else
			{

				if ( mouse_x < this.console_x || mouse_x > this.console_x + this.console_width ||
						mouse_y < this.console_y || mouse_y > this.console_y + this.console_height )
				{
					if ( this.console_showing == 1 && this.console_show_till == -1 )
					{
						this.console_showing = 0;
						this.console_mini.style.visibility = 'visible';
						this.console.style.visibility = 'hidden';
						this.b_help.style.visibility = 'hidden';
						this.b_z_out.style.visibility = 'hidden';
						this.b_z_in.style.visibility = 'hidden';
						this.b_z_one.style.visibility = 'hidden';
						this.b_z_all.style.visibility = 'hidden';
					}
				}
				else
				{
					if ( this.console_showing == 0 )
					{
						this.console_showing = 1;
						this.console_mini.style.visibility = 'hidden';
						this.console.style.visibility = 'visible';
						this.b_help.style.visibility = 'visible';
						this.b_z_out.style.visibility = 'visible';
						this.b_z_in.style.visibility = 'visible';
						this.b_z_one.style.visibility = 'visible';
						this.b_z_all.style.visibility = 'visible';
					}
				}
			}

			Event.stop(e);
        }
    },

    handleMouseUp : function(e){
        this.isBeingDragged = false;
        this.canvas.style.cursor = experience.panorama.getGrabCursor();
    },

    getGrabCursor : function(e) {
        if(experience.detectEngine() == "gecko"){
            return '-moz-grab';
        } else {
            return 'move';
        }
    },

    getGrabbingCursor : function(e){
        if(experience.detectEngine() == "gecko"){
            return '-moz-grabbing';
        } else {
            return 'move';
        }
    },

    /**
     * See also 
     *  http://adomas.org/javascript-mouse-wheel/
     *  http://www.ogonek.net/mousewheel/demo.html
     */
    handleMouseWheel: function(event){
        var delta = 0;

        if (event.wheelDelta) { // IE/Opera. 
            delta = event.wheelDelta/120;
            //In Opera 9, delta differs in sign as compared to IE.
            if (window.opera)
                delta = -delta;
        } else if (event.detail) { // Mozilla case. 
                // In Mozilla, sign of delta is different than in IE.
                // Also, delta is multiple of 3.
                delta = -event.detail/3;
        }

        delta = Math.round(delta); //Safari Round

        // If delta is nonzero, handle it.
        // Basically, delta is now positive if wheel was scrolled up,
        // and negative, if wheel was scrolled down.
        if (delta){
                experience.panorama.zoom.bindAsEventListener(this, delta)();
        }

        Event.stop(event);
    },

 // ace this once it's no longer referred to at all
    getImageResource : function (resource)
	{
		return theme_path + resource + this.Params.IconExtension;
    },


    Locales : $H({
        'en_US' : {
//            'HelpText' : "Grab (click and drag) the image to move it around. Use your mouse wheel to zoom the image in and out, or, if you don't have a mouse wheel, use the zoom icons in the Control Console (under Zoom Controls). If you hover with your mouse pointer over the zoom icons in the bottom right corner, the image will starting zooming in that direction (automatic zooming)."
            'HelpText' : "Grab (click and drag) the image to move it around. Use your mouse wheel to zoom the image in and out, or, if you don't have a mouse wheel, use the zoom icons in the Control Console (under Zoom Controls)."
        },

        'ar' : {
            'Zoom In' : 'تكبير',
            'Zoom Out' : 'تصغير',
            'Restore Original Size' : 'استعادة الحجم الأصلي',
            'Restore Original Position' : 'استعادة الموقع الأصلي',
            'Close' : 'إغلاق',
            'Scrolling .. ' : 'جاري التحريك ...',
            'Help': 'مساعدة',
            'HelpText' :  'أجذب (أنقر و جر) الصورة كي تحركها. استخدم عجلة الفأرة لتكبير أو تصغير الصورة. إذا لم يكن لديك واحدة، فاستخدم الأيقونات التى على شريط الأدوات. إذا حركت مؤشر الفأرة فوق أحدى أسهم النقال في الجانب الأيمن السفلى، فسوف تتحرك الصورة فى فى ذلك الإتجاه (تحريك تلقائي). \n\n بانوراما هي جزء من مكتبة إكسبريبس البرمجية لجافاسكربت. \n لمزيد من التفاصيل، يرجى زيارة موقع المشروع فى \n http://experience.sf.net',
            'Could not load image' : 'خطأ أثناء تحميل الصورة'
            ,'Go Full-Window' : 'إملء النافذة بأكملها',
            'Restore' : 'استرجاع'
        }
    })
}


