var g_Object = null; 		//global variable to set the current object

function GetObjectRef(object_name)
{
        if (document.layers){
				//Netscape 4 specific code
				pre = 'document.';
                post = '';
        }
        else if (document.getElementById){
                //Netscape 6 specific code
                pre = 'document.getElementById("';
                post = '").style';
        }
        else if (document.all){
                //IE4+ specific code
                pre = 'document.all.';
                post = '.style';
        }

        return eval(pre + object_name + post);

}

function GetObject(object_name)
{
        if (document.layers){
			    //Netscape 4 specific code
                pre = 'document.';
                post = '';
        }
        else if (document.getElementById){
                //Netscape 6 specific code
                pre = 'document.getElementById("';
                post = '")';
        }
        else if (document.all){
                //IE4+ specific code
                pre = 'document.all.';
                post = '';
        }

        return eval(pre + object_name + post);

}

// set the image of a Image in the page
// para:
// 		IMG_name: 		the Image id or name
// 		file_name: 		the file name of the picture to show
function SetImage(IMG_name, file_name)
{
	GetObject(IMG_name).src = file_name;	
}


//the main class for create the photo viewer code
//para:
// 		name: the unique name for the PhotoViewer, to be used for element in the web form
// 		object_name: the object name in the form, for javascript access
function PhotoViewer(name, object_name) {
	this.m_Name = name;
	this.m_ObjectName=object_name;

	this.m_Language="EN"; 	//default to use english

	//set the name of the img object that to be used to show the pictures
	this.m_IMGControlID = "PhotoViewer_" + this.m_Name + "_IMG";

	//some other variable
	this.m_Title = ""; 		// the title shown at the top after the toolbar
	this.m_ImageAlt = ""; 	//alt text for image
	this.m_Mode="playback"; 	//the mode of the page, only for NS4 since it cannot show div dynamically
	this.m_IsBasemapActive=false; 		//whether the basemap is pressed at this moment, it will be used to track whether a new picture has to be shown for animation
	this.m_IsNotNS4=true; 	//whether the browser is netscape 4 equilvalent
	this.m_CurrentFrame=0;	//0 is the first frame
	this.m_IsPlaying = false;
	this.m_AnimateSpeed = 500;	//0.5 second per frame	
	this.m_LastFrameDelay=2000;	// 2 second delay when the last frame is reached, before rewind to the first frame.  The delay is to be done in the SetTimeout function when last frame is reached.
	this.m_TimerID = -1;	//it stores the id of the timer for animation, for stopping the animation when needed
	this.m_ImageMaxWidth = 0;	//store the largest width of the pictures that are to be shown.
	this.m_ImageMaxHeight = 0;	//store the largest height of the pictures that are to be shown.
	this.m_ButtonList=new Array(); 	//the array to store all buttons
	this.m_ToolbarList = new Array(); 	//the array to store toolbar buttons
	this.m_TabList = new Array();
	this.m_PicLoaded=0; 	//count how many picture has been loaded
	this.m_PicLoadingDone = false; 		//whether all pictures loading is done, will become true when all picures are loaded or timeout.
	this.m_BasemapFile = ""; 		//file path for basemap 
	this.m_TitleBarBGColor = "#A7DFC4";

	this.m_ViewerImageBorderColour="#000000"; 	//colour of the border around the image
	this.m_ViewerImageBorderSize=2; 	//the border size, note that even this is set to 0, there is still a think border, set the border colour to #CCCCCC if black border is not wanted

	this.m_UseFlash = 0; 	//default uses javascript

	this.m_ShowBGInFlash = 0; 	//whether to show a white bg in flash behind an image

	this.m_GeneralImageCache = new Array(); 	//general image cache list
	
	//setttings, either set it here for default to set it through properties
	this.m_BasicButtonIMGFilePath="./button_img/"; 		//the default path for basic button's images
	this.m_BasicButtonPlayFile="button_play.gif"; 		//default file name for button "play" in above basic button path
	this.m_BasicButtonPlayFile_Over="button_play_over.gif"; 		//default file name for button "play" in above basic button path
	this.m_BasicButtonPlayFile_Disabled="button_play_disabled.gif"; 		//default file name for button "play" in above basic button path
	this.m_BasicButtonPlayFile_Down="button_play_down.gif"; 		//default file name for button "play" in above basic button path
	this.m_BasicButtonPauseFile="button_pause.gif"; 		//default file name for button "pause" in above basic button path
	this.m_BasicButtonPauseFile_Over="button_pause_over.gif"; 		//default file name for button "pause" in above basic button path
	this.m_BasicButtonPauseFile_Disabled="button_pause_disabled.gif"; 		//default file name for button "pause" in above basic button path
	this.m_BasicButtonPauseFile_Down="button_pause_down.gif"; 		//default file name for button "pause" in above basic button path
	this.m_BasicButtonStopFile="button_stop.gif"; 		//default file name for button "stop" in above basic button path
	this.m_BasicButtonStopFile_Over="button_stop_over.gif"; 		//default file name for button "stop" in above basic button path
	this.m_BasicButtonStopFile_Disabled="button_stop_disabled.gif"; 		//default file name for button "stop" in above basic button path
	this.m_BasicButtonStopFile_Down="button_stop_down.gif"; 		//default file name for button "stop" in above basic button path
	this.m_BasicButtonForwardFile="button_forward.gif"; 		//default file name for button "forward" in above basic button path
	this.m_BasicButtonForwardFile_Over="button_forward_over.gif"; 		//default file name for button "forward" in above basic button path
	this.m_BasicButtonForwardFile_Disabled="button_forward_disabled.gif"; 		//default file name for button "forward" in above basic button path
	this.m_BasicButtonForwardFile_Down="button_forward_down.gif"; 		//default file name for button "forward" in above basic button path
	this.m_BasicButtonBackFile="button_back.gif"; 		//default file name for button "back" in above basic button path
	this.m_BasicButtonBackFile_Over="button_back_over.gif"; 		//default file name for button "back" in above basic button path
	this.m_BasicButtonBackFile_Disabled="button_back_disabled.gif"; 		//default file name for button "back" in above basic button path
	this.m_BasicButtonBackFile_Down="button_back_down.gif"; 		//default file name for button "back" in above basic button path
	this.m_BasicButtonLatestFile="button_latest.gif"; 		//default file name for button "latest" in above basic button path
	this.m_BasicButtonLatestFile_Over="button_latest_over.gif"; 		//default file name for button "latest" in above basic button path
	this.m_BasicButtonLatestFile_Disabled="button_latest_disabled.gif"; 		//default file name for button "latest" in above basic button path
	this.m_BasicButtonLatestFile_Down="button_latest_down.gif"; 		//default file name for button "latest" in above basic button path

	this.m_BasicButtonAnimateFile_EN="button_animate_en.gif"; 		//default file name for button "animation sequence" in above basic button path
	this.m_BasicButtonAnimateFile_TC="button_animate_tc.gif"; 		//default file name for button "animation sequence" in above basic button path
	this.m_BasicButtonAnimateFile_SC="button_animate_sc.gif"; 		//default file name for button "animation sequence" in above basic button path

	this.m_BasicButtonBasemapFile="button_basemap.gif"; 		//default file name for button "basemap" in above basic button path
	this.m_BasicButtonBasemapDownFile="button_basemap_down.gif"; 		//default file name for button "basemap" in pressed statedin above basic button path

	//toolbar bg picture path
	this.m_ToolbarLeftBorderFile="toolbar_left_border.gif"; 	//the path for the left border for toolbar
	this.m_ToolbarRightBorderFile="toolbar_right_border.gif"; 	//the path for the right border for toolbar
	this.m_ToolbarBGFile="toolbar_bg.gif"; 	//the path for the background image for toolbar
	this.m_ToolbarBGColor="#E6E5E6"; 	//toolbar background color that outside the background image

	//tabs bg
	this.m_TabsBGFile="tab_space.gif"; 	//tabs bg picture
	
	this.m_BasicButtonPlayDesc_EN="Play";
	this.m_BasicButtonPlayDesc_TC="播放";
	this.m_BasicButtonPauseDesc_EN="Pause";
	this.m_BasicButtonPauseDesc_TC="暫停";
	this.m_BasicButtonStopDesc_EN="Stop";
	this.m_BasicButtonStopDesc_TC="停止";
	this.m_BasicButtonBackDesc_EN="Previous";
	this.m_BasicButtonBackDesc_TC="向前";
	this.m_BasicButtonForwardDesc_EN="Next";
	this.m_BasicButtonForwardDesc_TC="向後";
	this.m_BasicButtonLatestDesc_EN="Latest";
	this.m_BasicButtonLatestDesc_TC="最新";

	this.m_BasicButtonAnimateDesc_EN="Animation sequence";
	this.m_BasicButtonAnimateDesc_TC="動畫序列";
		
	this.m_BasicButtonBasemapDesc_EN="Base map";
	this.m_BasicButtonBasemapDesc_TC="底圖";

		
	//check for netscape 4 broswer
	if (document.layers){
		this.m_IsNotNS4=false;
	}

	//check for mode parameter from location
	htmlname = new String(self.location);
	html_array=htmlname.split("?");
	if (html_array[1])
	{
		para_list = html_array[1];

		if (para_list.indexOf("pv_mode=playback")>=0)
		{
			this.m_Mode="playback";
		}
		else
			this.m_Mode="";
	}
	else
	{
		//no para: default mode
		this.m_Mode="";
	}
}

PhotoViewer.prototype = {

	// toggle the mode of show basemap
	ToggleBasemap:function()
	{
		if (this.m_IsBasemapActive)
		{
			this.HideBasemap();

			//if it was playing, resume the animation
			if (this.m_IsPlaying)
				this.Animate();
		}
		else
			this.ShowBasemap();
	},


	// show the basemap in the pic window and also toggle the basemap button image
	ShowBasemap:function()
	{
		//check if there is no basemap
		if (this.m_BasemapFile == "")
			return;
		
		//mark the flag
		this.m_IsBasemapActive = true;

		//change the picture
		GetObject(this.m_IMGControlID).src = this.m_BasemapPic.src;	

		//toggle the basemap button image
		GetObject("PhotoViewer_"+this.m_Name+"_BasemapButton").src = this.m_BasicButtonIMGFilePath + this.m_BasicButtonBasemapDownFile;

		//cancel the timer event if there is, to prevent the animation keep going if the user toggle the basemap too fast.
		if (this.m_IsPlaying && (this.m_TimerID != -1))
			clearTimeout(this.m_TimerID);

		this.m_TimerID = -1;
	},

	// hide the basemap in the pic window and also toggle the basemap button image
	HideBasemap:function()
	{
		//check if there is no basemap
		if (this.m_BasemapFile == "")
			return;
		
		//mark the flag
		this.m_IsBasemapActive = false;

		//toggle the basemap button image
		GetObject("PhotoViewer_"+this.m_Name+"_BasemapButton").src = this.m_BasicButtonIMGFilePath + this.m_BasicButtonBasemapFile;

		//show the current picture
		this.UpdatePicture();
	},

	// Prepare for animation.  The viewer first show a preview picture to save bandwidth, when the user want to show the animation, this function is called.  The pictures for the animation will then be loaded.  The button panel will change as well.
	PrepareForAnimation:function() {

		//hide unneccessary panel for dynamic loading
		if (this.m_IsNotNS4)
		{
			//change to waiting panel
	//		GetObjectRef("PhotoViewer_"+this.m_Name+"_PreviewButtonPanel").visibility="hidden";
	//		GetObjectRef("PhotoViewer_"+this.m_Name+"_PreviewButtonPanel").display="none";

			//show the waiting message
			GetObjectRef("PhotoViewer_"+this.m_Name+"_LoadingMessagePanel").visibility="visible";
			GetObjectRef("PhotoViewer_"+this.m_Name+"_LoadingMessagePanel").display="block";
		}
		
		this.LoadAnimationPictures();

	},

	// toggle play and pause state
	TogglePlay:function()
	{
		//do nth if it is still loading (for NS4)
		if (! this.m_PicLoadingDone)
			return;

		if (this.m_IsPlaying)
		{
			this.Pause();

			this.UpdatePicture();
		}
		else
		{
			this.EnterPlayState();

			this.StartAnimation();
		}
	},

	// called when the play button is pressed, show the pause button image 
	EnterPlayState:function()
	{
		//change the button image
		var i=0;

		//update button state, make all enabled at this moment, may need change for futher needs
		for (i=0; i<this.m_ButtonList.length; i++)
		{
			this.m_ButtonList[i].ButtonEnable();
		}
		
		//find the "Play" button
		for (i=0; i<this.m_ButtonList.length; i++)
		{
			if (this.m_ButtonList[i].m_Name == "PhotoViewer_"+this.m_Name+"_Button_Play")
			{
				if (this.m_Language == "EN")
				{
					this.m_ButtonList[i] = new Button("PhotoViewer_"+this.m_Name+"_Button_Play", this.m_BasicButtonIMGFilePath + this.m_BasicButtonPauseFile, this.m_BasicButtonPlayDesc_EN, this.m_ObjectName + ".TogglePlay()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonPauseFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonPauseFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonPauseFile_Disabled);
					
					//update tooltips
					GetObject("PhotoViewer_"+this.m_Name+"_Button_Play").alt=this.m_BasicButtonPauseDesc_EN;
					GetObject("PhotoViewer_"+this.m_Name+"_Button_Play").title=this.m_BasicButtonPauseDesc_EN;
				}
				else if ((this.m_Language == "TC") || (this.m_Language == "SC"))
				{
					this.m_ButtonList[i] = new Button("PhotoViewer_"+this.m_Name+"_Button_Play", this.m_BasicButtonIMGFilePath + this.m_BasicButtonPauseFile, this.m_BasicButtonPlayDesc_TC, this.m_ObjectName + ".TogglePlay()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonPauseFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonPauseFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonPauseFile_Disabled);

					//update tooltips
					GetObject("PhotoViewer_"+this.m_Name+"_Button_Play").alt=this.m_BasicButtonPauseDesc_TC;
					GetObject("PhotoViewer_"+this.m_Name+"_Button_Play").title=this.m_BasicButtonPauseDesc_TC;
				}
				else
				{
					//unknown language
				}
				
				this.m_ButtonList[i].UpdatePicture();
					
				//there should be only one "play" button
				return;
			}	
		}
	},

	// called when the pause button is pressed, show the play button image 
	EnterPauseState:function()
	{
		//change the button image
		var i=0;
		
		//find the "Pause" button
		for (i=0; i<this.m_ButtonList.length; i++)
		{
			if (this.m_ButtonList[i].m_Name == "PhotoViewer_"+this.m_Name+"_Button_Play")
			{
				if (this.m_Language == "EN")
				{
					this.m_ButtonList[i] = new Button("PhotoViewer_"+this.m_Name+"_Button_Play", this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile, this.m_BasicButtonPlayDesc_EN, this.m_ObjectName + ".TogglePlay()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile_Disabled);

					//update tooltips
					GetObject("PhotoViewer_"+this.m_Name+"_Button_Play").alt=this.m_BasicButtonPlayDesc_EN;
					GetObject("PhotoViewer_"+this.m_Name+"_Button_Play").title=this.m_BasicButtonPlayDesc_EN;
				}
				else if ((this.m_Language == "TC") || (this.m_Language == "SC"))
				{
					this.m_ButtonList[i] = new Button("PhotoViewer_"+this.m_Name+"_Button_Play", this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile, this.m_BasicButtonPlayDesc_TC, this.m_ObjectName + ".TogglePlay()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile_Disabled);

					//update tooltips
					GetObject("PhotoViewer_"+this.m_Name+"_Button_Play").alt=this.m_BasicButtonPlayDesc_TC;
					GetObject("PhotoViewer_"+this.m_Name+"_Button_Play").title=this.m_BasicButtonPlayDesc_TC;
				}
				else
				{
					//unknown language
				}

				this.m_ButtonList[i].UpdatePicture();
					
				//there should be only one "play" button
				return;
			}

		}
	},


	// start the animation, it just added an extra checking to Play() which is: if it is the last frame, go to the first frame and start the animation by calling "Play()"
	StartAnimation:function() {
		//do nth if it is still loading (for NS4)
		if (! this.m_PicLoadingDone)
			return;

		if (this.IsLastFrame()) {
			this.m_CurrentFrame = 0;

			//display the current frame
			this.UpdatePicture();
		}

		this.Play();
	},

	//animate
	Play:function() {
		//do nth if it is already playing AND basemap is not active, otherwise we may reset the timer that make the animation not smooth
		if (this.m_IsPlaying && (!this.m_IsBasemapActive))
			return;

		//do nth if it is still loading (for NS4)
		if (! this.m_PicLoadingDone)
			return;

		//mark the flag
		this.m_IsPlaying = true;

		//start the animation
		this.Animate();
	},

	//stop the animation, stay in the current frame
	Pause:function() {
		//do nth if it is still loading (for NS4)
		if (! this.m_PicLoadingDone)
			return;
		
		//cancel the timer event if there is
		if (this.m_IsPlaying && (this.m_TimerID != -1))
			clearTimeout(this.m_TimerID);

		this.EnterPauseState();

		this.m_TimerID = -1;
		this.m_IsPlaying = false;

		//check for button state, this function is called for every playback button click
		if (this.m_CurrentFrame == 0)
		{
			//find the "Stop" and "Previous" button
			for (i=0; i<this.m_ButtonList.length; i++)
			{
				var button_name = this.m_ButtonList[i].m_Name;
				
				if ( (button_name == "PhotoViewer_"+this.m_Name+"_Button_Stop") || (button_name == "PhotoViewer_"+this.m_Name+"_Button_Back"))
				{	
					this.m_ButtonList[i].ButtonDisable();
				}
				else
				{
					this.m_ButtonList[i].ButtonEnable();
				}
			}
		}
		else if (this.m_CurrentFrame == (this.m_Files.length-1))
		{
			//find the "Latest" and "Latest" button
			for (i=0; i<this.m_ButtonList.length; i++)
			{
				var button_name = this.m_ButtonList[i].m_Name;
				
				if ( (button_name == "PhotoViewer_"+this.m_Name+"_Button_Forward") || (button_name == "PhotoViewer_"+this.m_Name+"_Button_Latest"))
				{	
					this.m_ButtonList[i].ButtonDisable();
				}
				else
				{
					this.m_ButtonList[i].ButtonEnable();
				}
			}
		}
		else
		{
			//enable all buttons
			for (i=0; i<this.m_ButtonList.length; i++)
			{
				this.m_ButtonList[i].ButtonEnable();
			}
		}
	},

	//update the picture that is shown for the current frame. to be called after the frame number is changed.
	UpdatePicture:function() {
		//hide basemap if it is on
		if (this.m_IsBasemapActive)
			this.HideBasemap();

		//check if it is NS4 and it is in playback mode and still loading, show the loading screen
		if ((!this.m_IsNotNS4) && (this.m_Mode=="playback") && (! this.m_PicLoadingDone) )
		{
			GetObject(this.m_IMGControlID).src = "loading.jpg";			

			return;
		}
		
		if (this.FileImageCacheList)
			GetObject(this.m_IMGControlID).src = this.m_FileImageCacheList[this.m_CurrentFrame].src;
		else
			GetObject(this.m_IMGControlID).src = this.m_Files[this.m_CurrentFrame];

		//if it is not netscape 4 browser, animate the time line.
		if (this.m_IsNotNS4)
		{
			//update time line
			var timeline_percent = (this.m_CurrentFrame) * 100.0 / (this.m_Files.length-1);
			GetObjectRef("PhotoViewer_"+this.m_Name+"_TimeLine").width = timeline_percent+"%"; 
		}
	},

	//go the the next frame, if it is the last frame, do nothing
	Forward:function() {
		//do nth if it is still loading (for NS4)
		if (! this.m_PicLoadingDone)
			return;

		if (! this.IsLastFrame()) {
			this.m_CurrentFrame++;
		}
		
		//stop the animation first
		this.Pause();
		
		//display the current frame
		this.UpdatePicture();
	},

	// go back one frame, if it is the first frame, do nothing
	Back:function() {
		//do nth if it is still loading (for NS4)
		if (! this.m_PicLoadingDone)
			return;

		if (this.m_CurrentFrame > 0)
			this.m_CurrentFrame--;

		//stop the animation first
		this.Pause();
			
		//display the current frame
		this.UpdatePicture();
	},

	// return true if it is the last frame, otherwise false
	IsLastFrame:function() {
		if (this.m_CurrentFrame >= (this.m_Files.length-1))
			return true;
		else
			return false;

	},

	// go to the first frame
	Rewind:function() {
		//do nth if it is still loading (for NS4)
		if (! this.m_PicLoadingDone)
			return;

		this.m_CurrentFrame = 0;
		
		//stop the animation first
		this.Pause();

		//display the current frame
		this.UpdatePicture();
	},

	//go to the last frame
	GotoLast:function() {
		//do nth if it is still loading (for NS4)
		if (! this.m_PicLoadingDone)
			return;

		this.m_CurrentFrame = this.m_Files.length-1;

		//stop the animation first
		this.Pause();
		
		//display the current frame
		this.UpdatePicture();
	},

	// make the photo change after a period of time, if the current frame is the last frame, add a certain of delay
	Animate:function() {
		//hide basemap if it is on
		if (this.m_IsBasemapActive)
			this.HideBasemap();
		
		if (this.IsLastFrame())
			this.m_TimerID = setTimeout(this.m_ObjectName + ".AnimationTick()", this.m_AnimateSpeed + this.m_LastFrameDelay);
		else
			this.m_TimerID = setTimeout(this.m_ObjectName + ".AnimationTick()", this.m_AnimateSpeed);
	},

	//method that to be called during every tick of the the animation
	AnimationTick:function() {
		//do nth if basemap is active
		if (this.m_IsBasemapActive)
			return;

		//cancel the timer event if there is
		if (this.m_IsPlaying && (this.m_TimerID != -1))
			clearTimeout(this.m_TimerID);
		
		//stop the naimation temparay
		this.m_IsPlaying=false;
		
		//if it is the last frame, go back to the first frame by rewind
		if (this.IsLastFrame()) {
			this.m_CurrentFrame = 0;
		}
		else {
			//otherwise, go to the next frame.
			this.m_CurrentFrame++;
		}

		//display the current frame
			this.UpdatePicture();

		//keep the animation going.
		this.Play();

	},

	// add the basic buttons: play, pause, forward, back and latest to the viewer
	// para:
	// 		lang: 	the language of the description to use, either "EN", "TC" or "SC" at the moment.
	AddBasicButton:function(lang) {
		this.m_Language=lang.toUpperCase();
		
		if (this.m_Language == "EN")
		{
			this.AddButton("PhotoViewer_"+this.m_Name+"_Button_Play", this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile, this.m_BasicButtonPlayDesc_EN, this.m_ObjectName + ".TogglePlay()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile_Disabled);
			this.AddButton("PhotoViewer_"+this.m_Name+"_Button_Stop", this.m_BasicButtonIMGFilePath + this.m_BasicButtonStopFile, this.m_BasicButtonStopDesc_EN, this.m_ObjectName + ".Rewind()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonStopFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonStopFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonStopFile_Disabled);
			this.AddButton("PhotoViewer_"+this.m_Name+"_Button_Back", this.m_BasicButtonIMGFilePath + this.m_BasicButtonBackFile, this.m_BasicButtonBackDesc_EN, this.m_ObjectName + ".Back()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonBackFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonBackFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonBackFile_Disabled);
			this.AddButton("PhotoViewer_"+this.m_Name+"_Button_Forward", this.m_BasicButtonIMGFilePath + this.m_BasicButtonForwardFile, this.m_BasicButtonForwardDesc_EN, this.m_ObjectName + ".Forward()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonForwardFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonForwardFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonForwardFile_Disabled);
			this.AddButton("PhotoViewer_"+this.m_Name+"_Button_Latest", this.m_BasicButtonIMGFilePath + this.m_BasicButtonLatestFile, this.m_BasicButtonLatestDesc_EN, this.m_ObjectName + ".GotoLast()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonLatestFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonLatestFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonLatestFile_Disabled);
		}
		else if ((this.m_Language == "TC") || (this.m_Language == "SC"))
		{
			this.AddButton("PhotoViewer_"+this.m_Name+"_Button_Play", this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile, this.m_BasicButtonPlayDesc_TC, this.m_ObjectName + ".TogglePlay()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonPlayFile_Disabled);
			this.AddButton("PhotoViewer_"+this.m_Name+"_Button_Stop", this.m_BasicButtonIMGFilePath + this.m_BasicButtonStopFile, this.m_BasicButtonStopDesc_TC, this.m_ObjectName + ".Rewind()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonStopFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonStopFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonStopFile_Disabled);
			this.AddButton("PhotoViewer_"+this.m_Name+"_Button_Back", this.m_BasicButtonIMGFilePath + this.m_BasicButtonBackFile, this.m_BasicButtonBackDesc_TC, this.m_ObjectName + ".Back()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonBackFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonBackFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonBackFile_Disabled);
			this.AddButton("PhotoViewer_"+this.m_Name+"_Button_Forward", this.m_BasicButtonIMGFilePath + this.m_BasicButtonForwardFile, this.m_BasicButtonForwardDesc_TC, this.m_ObjectName + ".Forward()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonForwardFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonForwardFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonForwardFile_Disabled);
			this.AddButton("PhotoViewer_"+this.m_Name+"_Button_Latest", this.m_BasicButtonIMGFilePath + this.m_BasicButtonLatestFile, this.m_BasicButtonLatestDesc_TC, this.m_ObjectName + ".GotoLast()", this.m_BasicButtonIMGFilePath + this.m_BasicButtonLatestFile_Over, this.m_BasicButtonIMGFilePath + this.m_BasicButtonLatestFile_Down, this.m_BasicButtonIMGFilePath + this.m_BasicButtonLatestFile_Disabled);

		}
		else
		{
			//dont know what to do?
		}
	},

	// add a button to the viewer
	// para:
	// 		name: 			the name of the button, to be used for changing image 
	// 		IMG_file_path: 	the image file path of the button
	// 		button_desc: 	the description (tool tips) of the button 
	// 		function_name: 	the name of the function to be called when the button is clicked.  beware that the function must be a function in the generated web page
	// 		IMG_over_file_path: 	the image file path for mouse over, if any
	// 		IMG_down_file_path: 	the image file path for mouse down, if any
	// 		IMG_disabled_file_path: 	the image file path for disabled state, if any
	AddButton:function(name, IMG_file_path, button_desc, function_name, IMG_over_file_path, IMG_down_file_path, IMG_disabled_file_path)
	{
		var new_button_index=this.m_ButtonList.length;
		this.m_ButtonList[new_button_index]= new Button(name, IMG_file_path, button_desc, function_name, IMG_over_file_path, IMG_down_file_path, IMG_disabled_file_path)

		//preload mouse over button if there is
		if ((IMG_over_file_path) && (IMG_over_file_path != ""))
		{
			this.PreloadImage(IMG_over_file_path);
			this.PreloadImage(IMG_file_path);
		}

		//preload mouse down button if there is
		if ((IMG_down_file_path) && (IMG_down_file_path != ""))
			this.PreloadImage(IMG_down_file_path);

		//preload mouse disabled button if there is
		if ((IMG_over_file_path) && (IMG_disabled_file_path != ""))
			this.PreloadImage(IMG_disabled_file_path);

	},

	// add a toolbar button to the viewer
	// para:
	// 		IMG_file_path: 	the image file path of the button
	// 		button_text: 	the text to be shown next to the button
	// 		button_desc: 	the description (tool tips) of the button 
	// 		function_name: 	the name of the function to be called when the button is clicked.  beware that the function must be a function in the generated web page
	AddToolbarButton:function(IMG_file_path, button_text, button_desc, function_name)
	{
		var new_button_index=this.m_ToolbarList.length;
		this.m_ToolbarList[new_button_index]= new ToolbarButton(IMG_file_path, button_text, button_desc, function_name);
	},

	//pass a array of pictures file name for display
	//para:
	// 			array_files: the animation sequence picture file name
	// 			basemap_file: the basemap picture file name
	SetPictures:function(array_files, basemap_file) {
		this.m_Files = array_files;	

		if (basemap_file)
			this.m_BasemapFile = basemap_file;
		else
			this.m_BasempaFile = "";

		if (this.m_BasemapFile != "")
		{
			//load the basemap picture
			this.m_BasemapPic = new Image();
			this.m_BasemapPic.src=basemap_file;
		}
			
		this.m_CurrentFrame = this.m_Files.length-1;
	},

	// add a tab to the viewer
	// 		desc: 			Description of the tab
	// 		link: 			the link to redirect when it is clicked
	// 		image_path: 	the path of the image if this tab is selected
	// 		image_down_path: 	the path of the image is this tab is not selected
	// 		enable_click: 	true if this tab could be clicked (normally a selected tab is not clickable)		
	AddTab:function(desc, link, image_path, image_down_path, selected, enable_click)
	{
		var new_button_index=this.m_TabList.length;
		this.m_TabList[new_button_index]= new TabPage(desc, link, image_path, image_down_path, selected, enable_click);
	},
				
	//startup job
	Init:function()
	{
		//preload some neccessary images
		this.PreloadImage(this.m_BasicButtonIMGFilePath + this.m_BasicButtonBasemapFile);
		this.PreloadImage(this.m_BasicButtonIMGFilePath + this.m_BasicButtonBasemapDownFile);

		this.PreloadImage(this.m_Files[this.m_Files.length-1]);
		
	},

	//for preloading images, count the number of image that is loaded
	APicLoaded:function()
	{
		g_Object.m_PicLoaded = g_Object.m_PicLoaded +1;
		
		//check all pictures loaded
		if (g_Object.m_PicLoaded >= g_Object.m_Files.length)
		{
			g_Object.PicturesLoaded();
		}
	},

	//called when all pictures is loaded or timeout
	PicturesLoaded:function()
	{
		//if it is notified already, do nothing (timeout after loading)
		if (this.m_PicLoadingDone)
			return;
		
		this.m_PicLoadingDone = true;
		
		//the last picture is selected at first
		this.m_CurrentFrame = this.m_Files.length-1;

		//show playback panel panel for dynamic loading
		if (this.m_IsNotNS4)
		{
			//hide the waiting message
			GetObjectRef("PhotoViewer_"+this.m_Name+"_LoadingMessagePanel").visibility="hidden";
			GetObjectRef("PhotoViewer_"+this.m_Name+"_LoadingMessagePanel").display="none";

			//show the animation button
			GetObjectRef("PhotoViewer_"+this.m_Name+"_AnimationButtonPanel").visibility="visible";
			GetObjectRef("PhotoViewer_"+this.m_Name+"_AnimationButtonPanel").display="block";
		}

		//start the animation
		this.TogglePlay();
	},

	// load pictures for animation: load the images into memory for faster display
	LoadAnimationPictures:function() {
		g_Object = this;

		//for each picture that it is going to display, load it into a image object for cache.
		this.m_FileImageCacheList = new Array(this.m_Files.length);
		
		for (i=0; i<this.m_Files.length; i++) {
			this.m_FileImageCacheList[i] = new Image();
			this.m_FileImageCacheList[i].src = this.m_Files[i];

			//check if the picture is here
			if ((this.m_FileImageCacheList[i].complete) || (this.m_FileImageCacheList[i].height != 0))
			{
				this.m_PicLoaded = this.m_PicLoaded + 1;

				//check all pictures loaded
				if (this.m_PicLoaded >= this.m_Files.length -1)
				{
					this.PicturesLoaded();
				}
			}
			else
			{
				//the picture is not loaded, load it using preloader
			//TODO: modify to make it not global function call.
				this.m_FileImageCacheList[i].onload = this.APicLoaded;
			}
		}

		//set callback for picture loading timeout
		setTimeout(this.m_ObjectName + ".PicturesLoaded()", 30000);
	
	},

	//the actual code that put the control to a web page
	// para: *ONLY FOE FLASH VERSION
	// 		file_name: 		swf file name for flash version
	// 		movie_width: 	width of the movie
	// 		movie_height: 	height of the movie					
	// 		list_file: 		the file that stores the list of images path
	Show:function(file_name, movie_width, movie_height, list_file) {
		//the control is going to be shown.  do some init job
		this.Init();

		document.writeln("<div id=\"PhotoViewer_"+this.m_Name+"_AnimationPanel\" style=\"\" >");
		
		document.writeln("<table cellspacing=0 cellpadding=0 width=\"100%\" border=0><tr><td>");

		document.writeln("<table name=\"PhotoViewer_"+this.m_Name+"_Container\" id=\"PhotoViewer_"+this.m_Name+"_Container\" cellpadding=0 cellspacing=0 align=center border=0>");

		//tabs (if any)
		if (this.m_TabList.length >0)
		{
			document.writeln("<tr height=28>");

			if (this.m_IsNotNS4)
				document.writeln("<td height=28 width=\"*\" background=\""+this.m_BasicButtonIMGFilePath+this.m_TabsBGFile+"\" style=\"background-repeat: repeat-x;\">");
			else
				document.writeln("<td height=28 width=\"*\" background=\""+this.m_BasicButtonIMGFilePath+this.m_TabsBGFile+"\">");

				document.writeln("<table border=0 cellspacing=0 cellpadding=0 align=right height=28>");
				document.writeln("<tr height=28>");
							
				for (i=0; i<this.m_TabList.length; i++)
				{
					document.writeln("<td height=28>");
				
					//check what picture to show depending on the selected state
					var pic="";
					if (this.m_TabList[i].m_IsSelected)
						pic = this.m_TabList[i].m_FilePath;
					else
						pic = this.m_TabList[i].m_FilePath_Down;
						
					//no link if it is not clickable
					if (this.m_TabList[i].m_IsClickable)
						document.write("<a href=\""+this.m_TabList[i].m_Link+"\" alt=\""+this.m_TabList[i].m_Desc+"\">");
					
					document.write("<img src=\""+pic+"\" border=0 alt=\""+this.m_TabList[i].m_Desc+"\" title=\""+this.m_TabList[i].m_Desc+"\"/>");
					
					if (this.m_TabList[i].m_IsClickable)
						document.write("</a>");
					
					document.writeln("</td>");
				}

				document.writeln("</tr>");
				document.writeln("</table>");

			document.writeln("</td>");
			
			document.writeln("</tr>");
		}

		//title, if any
		if (this.m_Title != "")
		{
			document.writeln("<tr><td align=center bgcolor="+this.m_TitleBarBGColor+">");

			if (this.m_IsNotNS4)
				document.writeln("<p style=\"margin: 5px 2px 2px 2px; color:#000000;\"><b>" + this.m_Title + "</b></p>");
			else
				document.writeln("<p color=#000000><b>" + this.m_Title + "</b></p>");
			
			document.writeln("</td></tr>");
		}
		
		//toolbar (if any)
		if (this.m_ToolbarList.length >0)
		{
			document.writeln("<tr>");
			
	//		document.writeln("<td background=\""+this.m_BasicButtonIMGFilePath+this.m_ToolbarLeftBorderFile+"\" width=8>&nbsp;</td>");

			if (this.m_IsNotNS4)
				document.writeln("<td align=left width=\"*\" bgcolor="+this.m_ToolbarBGColor+" background=\""+this.m_BasicButtonIMGFilePath+this.m_ToolbarBGFile+"\" style=\"background-repeat: repeat-x;\">");
			else
				document.writeln("<td align=left width=\"*\" bgcolor="+this.m_ToolbarBGColor+" background=\""+this.m_BasicButtonIMGFilePath+this.m_ToolbarBGFile+"\">");
			
				document.writeln("<table border=0 cellspacing=0 cellpadding=4 align=left>");
				document.writeln("<tr align=left>");
							
				for (i=0; i<this.m_ToolbarList.length; i++)
				{
					document.writeln("<td>");
					
					document.write("<a href=\"JavaScript:"+this.m_ToolbarList[i].m_FunctionName+"\" alt=\""+this.m_ToolbarList[i].m_Desc+"\"><img src=\""+this.m_ToolbarList[i].m_FilePath+"\" border=0 alt=\""+this.m_ToolbarList[i].m_Desc+"\" title=\""+this.m_ToolbarList[i].m_Desc+"\"/></a>");

					document.writeln("</td><td><a href=\"JavaScript:"+this.m_ToolbarList[i].m_FunctionName+"\" alt=\""+this.m_ToolbarList[i].m_Desc+"\" title=\""+this.m_ToolbarList[i].m_Desc+"\"><nobr>"+this.m_ToolbarList[i].m_Text+"</nobr></a>");
					
					//document.write("<a href=\"JavaScript:"+this.m_ToolbarList[i].m_FunctionName+"\" alt=\""+this.m_ToolbarList[i].m_Desc+"\"><img src=\""+this.m_ToolbarList[i].m_FilePath+"\" border=0 alt=\""+this.m_ToolbarList[i].m_Desc+"\" title=\""+this.m_ToolbarList[i].m_Desc+"\"/><br><nobr>"+this.m_ToolbarList[i].m_Text+"</nobr></a>");
					
					document.writeln("</td>");
				}

				document.writeln("</tr>");
				document.writeln("</table>");

			document.writeln("</td>");
			

	//		document.writeln("<td width=8 background=\""+this.m_BasicButtonIMGFilePath+this.m_ToolbarRightBorderFile+"\">&nbsp;</td>");
			
			document.writeln("</tr>");
		}

		document.writeln("<tr><td>");
		document.writeln("<table width=100% bgcolor=#CCCCCC cellpadding=0 cellspacing=1 align=center border=0>");

		//table cell for picture
		document.writeln("<tr><td align=center bgcolor=#000000>");

		//check for flash or javascript version
		if (this.m_UseFlash != 1) {
					
			document.writeln("<table  width=100% cellpadding=0 cellspacing=0 border=0>");
			
			document.writeln("<tr><td align=center>");
			
			//picture
				document.writeln("<table bgcolor="+this.m_ViewerImageBorderColour+" cellpadding="+this.m_ViewerImageBorderSize+"><tr><td>");

				//if it is NS4 and animation, show loading message
				if ((!this.m_IsNotNS4) && (this.m_Mode=="playback") )
				{
					//set the size for the picture since the loading image may not equal to the actual picturs size which Netscape will not auto resize it
					if (this.m_ImageMaxWidth >0 && this.m_ImageMaxHeight >0)
						document.writeln("<img name=\""+this.m_IMGControlID+"\" id=\""+this.m_IMGControlID+"\" width=\""+this.m_ImageMaxWidth+"\" height=\""+this.m_ImageMaxHeight+"\" border=0 src=\"loading.jpg\" alt=\""+this.m_ImageAlt+"\" title=\""+this.m_ImageAlt+"\" /><br/>"); 
						
					else
						document.writeln("<img name=\""+this.m_IMGControlID+"\" id=\""+this.m_IMGControlID+"\" border=0 src=\"loading.jpg\" alt=\""+this.m_ImageAlt+"\" title=\""+this.m_ImageAlt+"\" /><br/>"); 
				}
				else
					document.writeln("<img name=\""+this.m_IMGControlID+"\" id=\""+this.m_IMGControlID+"\" border=0 src=\""+this.m_Files[this.m_Files.length-1]+"\" alt=\""+this.m_ImageAlt+"\" title=\""+this.m_ImageAlt+"\" /><br/>"); 
				
				document.writeln("</td></tr></table>");

			document.writeln("</td></tr></table>");
			
			//timeline indicator (only shown if it is not NS4)
				if (this.m_IsNotNS4)
				{
					document.writeln("</td></tr><tr><td>");
					document.writeln("<table bgcolor=#000000 border=0 cellpadding=0 cellspacing=0 width=\"100%\"><tr height=\"5\"><td align=\"left\">");
					document.writeln("<table id=\"PhotoViewer_"+this.m_Name+"_TimeLine\" name=\"PhotoViewer_"+this.m_Name+"_TimeLine\" bgcolor=#000000 border=0 cellpadding=0 cellspacing=0 width=\"100%\"><tr height='3' bgcolor=#6BBCB3><td></td></tr></table>");
					document.writeln("</td></tr></table>");
				}
			
			//buttons
				document.writeln("</td></tr><tr><td>");

				//table for all buttons (include basemap)
				document.writeln("<table width=100%  border=0 cellpadding=0 cellspacing=0><tr><td align=cente>");
					
				//table for playback button
				document.writeln("<table width=100% bgcolor=#CCCCCC border=0 cellpadding=5 cellspacing=0><tr><td align=center>");
				
				//buttons for latest
					//show only if the mode is not playback (preview mode)
					if (this.m_Mode!="playback")
					{
						//pressing the play button will switch to the animation mode
						htmlname = new String(self.location);
						var link_path = "";
						if (htmlname.indexOf("?")<0)
							link_path = htmlname + "?pv_mode=playback";
						else
							link_path = htmlname + ";pv_mode=playback";
								
						if (this.m_IsNotNS4)
						{
							document.writeln("<div id=\"PhotoViewer_"+this.m_Name+"_PreviewButtonPanel\" align=center style=\"position:relative;\" >");

							//show different language tool tips for different language
							if (this.m_Language == "EN")
							{
								document.write("<a href=\""+link_path+"\" ><img src=\""+this.m_BasicButtonIMGFilePath+this.m_BasicButtonAnimateFile_EN+"\" border=0 alt=\""+this.m_BasicButtonAnimateDesc_EN+"\" title=\""+this.m_BasicButtonAnimateDesc_EN+"\"/></a>");
							}
							else if (this.m_Language == "TC")
							{
								document.write("<a href=\""+link_path+"\"><img src=\""+this.m_BasicButtonIMGFilePath+this.m_BasicButtonAnimateFile_TC+"\" border=0 alt=\""+this.m_BasicButtonAnimateDesc_TC+"\" title=\""+this.m_BasicButtonAnimateDesc_TC+"\"/></a>");
							}
							else if (this.m_Language == "SC")
							{
								document.write("<a href=\""+link_path+"\"><img src=\""+this.m_BasicButtonIMGFilePath+this.m_BasicButtonAnimateFile_SC+"\" border=0 alt=\""+this.m_BasicButtonAnimateDesc_TC+"\" title=\""+this.m_BasicButtonAnimateDesc_TC+"\"/></a>");
							}
							else
							{
								//nth to do
							}
						
							document.writeln("</div>");
						}
						else
						{
							//show different language tool tips for different language
							if (this.m_Language == "EN")
							{
								document.write("<a href=\""+link_path+"\" ><img src=\""+this.m_BasicButtonIMGFilePath+this.m_BasicButtonAnimateFile_EN+"\" border=0 alt=\""+this.m_BasicButtonAnimateDesc_EN+"\" title=\""+this.m_BasicButtonAnimateDesc_EN+"\"/></a>");
							}
							else if (this.m_Language == "TC")
							{
								document.write("<a href=\""+link_path+"\"><img src=\""+this.m_BasicButtonIMGFilePath+this.m_BasicButtonAnimateFile_TC+"\" border=0 alt=\""+this.m_BasicButtonAnimateDesc_TC+"\" title=\""+this.m_BasicButtonAnimateDesc_TC+"\"/></a>");
							}
							else if (this.m_Language == "SC")
							{
								document.write("<a href=\""+link_path+"\"><img src=\""+this.m_BasicButtonIMGFilePath+this.m_BasicButtonAnimateFile_SC+"\" border=0 alt=\""+this.m_BasicButtonAnimateDesc_TC+"\" title=\""+this.m_BasicButtonAnimateDesc_TC+"\"/></a>");
							}
							else
							{
								//nth to do
							}
							
						}
					}
			
				//buttons for animation
					//show only when the mode is "playback"
					if (this.m_Mode == "playback")
					{
						if (this.m_IsNotNS4)
						{
							document.writeln("<div id=\"PhotoViewer_"+this.m_Name+"_AnimationButtonPanel\" align=left style=\"position:relative;visibility:hidden;display:none;\">");
							for (i=0; i<this.m_ButtonList.length; i++)
							{
								if ( (this.m_ButtonList[i].m_FilePathOver) && (this.m_ButtonList[i].m_FilePathOver != ""))
								{
									document.write("<a href=\"JavaScript:"+this.m_ButtonList[i].m_FunctionName+"\" onmouseDown=\"Javascript:"+this.m_ObjectName+".m_ButtonList["+i+"].ButtonDown()\" onmouseUp=\"Javascript:"+this.m_ObjectName+".m_ButtonList["+i+"].ButtonUp()\" onmouseOver=\"Javascript:"+this.m_ObjectName+".m_ButtonList["+i+"].ButtonOver()\" onmouseOut=\"Javascript:"+this.m_ObjectName+".m_ButtonList["+i+"].ButtonOut()\" alt=\""+this.m_ButtonList[i].m_Desc+"\"><img name=\""+this.m_ButtonList[i].m_Name+"\" id=\""+this.m_ButtonList[i].m_Name+"\" src=\""+this.m_ButtonList[i].m_FilePath+"\" border=0 alt=\""+this.m_ButtonList[i].m_Desc+"\" title=\""+this.m_ButtonList[i].m_Desc+"\"/></a>");
								}
								else
									document.write("<a href=\"JavaScript:"+this.m_ButtonList[i].m_FunctionName+"\" alt=\""+this.m_ButtonList[i].m_Desc+"\"><img src=\""+this.m_ButtonList[i].m_FilePath+"\" border=0 alt=\""+this.m_ButtonList[i].m_Desc+"\" title=\""+this.m_ButtonList[i].m_Desc+"\"/></a>");
								// document.write("<a href=\"JavaScript:"+this.m_ButtonList[i].m_FunctionName+"\" alt=\""+this.m_ButtonList[i].m_Desc+"\"><img src=\""+this.m_ButtonList[i].m_FilePath+"\" border=0 alt=\""+this.m_ButtonList[i].m_Desc+"\" title=\""+this.m_ButtonList[i].m_Desc+"\"/></a>");
							}

							document.writeln("</div>");
						}
						else
						{
							var i;
							for (i=0; i<this.m_ButtonList.length; i++)
							{
								document.write("<a href=\"JavaScript:"+this.m_ButtonList[i].m_FunctionName+"\" alt=\""+this.m_ButtonList[i].m_Desc+"\"><img src=\""+this.m_ButtonList[i].m_FilePath+"\" name=\""+this.m_ButtonList[i].m_Name+"\" id=\""+this.m_ButtonList[i].m_Name+"\" border=0 alt=\""+this.m_ButtonList[i].m_Desc+"\" title=\""+this.m_ButtonList[i].m_Desc+"\"/></a>");
							}
						}
					}
					
				//loading message
					if (this.m_IsNotNS4)
					{
						document.writeln("<div id=\"PhotoViewer_"+this.m_Name+"_LoadingMessagePanel\" align=center style=\"position:relative;visibility:hidden;display:none;\">");

						if ((this.m_Language =="TC") || (this.m_Language =="SC"))
							document.write("載入圖片中...");
						else
							document.write("Please wait while loading...");
						
						document.writeln("</div>");
					}
					else
					{
						//code for NS4
						//nth to show, this is for dynamic loading of image
					}
						
				//close for button panel	
				document.writeln("</td></tr></table>");

				document.writeln("</td><td align=right>");

				//button for basemap

					document.writeln("</td><td valign=top align=right>");

					//show basemap button only if there is basemap
					if (this.m_BasemapFile != "")
					{
						//show different language tool tips for different language
						if (this.m_Language == "EN")
						{
							document.write("<a href=\"javascript:"+this.m_ObjectName+".ToggleBasemap();\"><img id=\"PhotoViewer_"+this.m_Name+"_BasemapButton\" name=\"PhotoViewer_"+this.m_Name+"_BasemapButton\" src=\""+this.m_BasicButtonIMGFilePath+this.m_BasicButtonBasemapFile+"\" border=0 alt=\""+this.m_BasicButtonBasemapDesc_EN+"\" title=\""+this.m_BasicButtonBasemapDesc_EN+"\"/></a>");
						}
						else if ((this.m_Language == "TC") || (this.m_Language == "SC"))
						{
							document.write("<a href=\"javascript:"+this.m_ObjectName+".ToggleBasemap();\"><img id=\"PhotoViewer_"+this.m_Name+"_BasemapButton\" name=\"PhotoViewer_"+this.m_Name+"_BasemapButton\" src=\""+this.m_BasicButtonIMGFilePath+this.m_BasicButtonBasemapFile+"\" border=0 alt=\""+this.m_BasicButtonBasemapDesc_TC+"\" title=\""+this.m_BasicButtonBasemapDesc_TC+"\"/></a>");
						}
						else
						{
							//nth to do
						}
					}
					else
					{
						document.write("&nbsp;");
					}
				

				//close for all button panel
				document.writeln("</td></tr></table>");

				//if it is playback mode, start the animation
				if (this.m_Mode == "playback")
				{
					this.PrepareForAnimation();
				}
		}
		else
		{
			//flash version
			this.ShowFlashViewer(file_name, movie_width, movie_height, list_file);
		}	
		
		document.writeln("</td></tr></table>");
		document.writeln("</td></tr></table>");
		
		document.writeln("</td></tr></table>");

		document.writeln("</div>");

	},

	// show the flash version of the viewer
	ShowFlashViewer:function(file_name, movie_width, movie_height, list_file) 
	{
		var para_list = "";
		para_list="?ImageWidth=" + this.m_ImageMaxWidth +"&"+"ImageHeight=" + this.m_ImageMaxHeight;

		//playback mode
		if (this.m_Mode == "playback")
		{
			para_list=para_list+"&PlaybackMode=animation";
		}

		//show basemap button only if there is basemap
		if (this.m_BasemapFile != "")
		{
			para_list=para_list+"&BasemapFile="+this.m_BasemapPic.src;
		}

		//animation link
		htmlname = new String(self.location);
		var link_path = "";
		if (htmlname.indexOf("?")<0)
			link_path = htmlname + "?pv_mode=playback";
		else
			link_path = htmlname + ";pv_mode=playback";
		
		para_list=para_list+"&AnimationLink="+link_path;

		//language
		para_list=para_list+"&Language="+this.m_Language;

		//whethe to show a white bg behind image
		if (this.m_ShowBGInFlash != 0)
			para_list=para_list+"&ShowBG=1";

	/*	//push image list
		var i;
		for (i=0; i<this.m_Files.length; i++) {
			para_list = para_list + "&Pic"+i+"="+this.m_Files[i];
		}
	*/	
		//list file
		para_list = para_list + "&ListFile="+list_file+"%3Frandom%3D"+Math.floor(Math.random()*10000);
		
		var MM_contentVersion = 5;
		var plugin = (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]) ? navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin : 0;
		if ( plugin ) {
				var words = navigator.plugins["Shockwave Flash"].description.split(" ");
				for (var i = 0; i < words.length; ++i)
				{
				if (isNaN(parseInt(words[i])))
				continue;
				var MM_PluginVersion = words[i]; 
				}
			var MM_FlashCanPlay = MM_PluginVersion >= MM_contentVersion;
		}
		else if (navigator.userAgent && navigator.userAgent.indexOf("MSIE")>=0 
		   && (navigator.appVersion.indexOf("Win") != -1)) {
			//assume can be played by IE
			MM_FlashCanPlay = true;
		}
		if ( MM_FlashCanPlay ) {
			document.write('<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"');
			document.write('  codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="'+movie_width+'" height="'+movie_height+'" id="FlashPhotoViewer" align="middle">');
			document.write(' <param name="allowScriptAccess" value="sameDomain" />'); 
			document.write(' <param name="movie" value="'+file_name+para_list+'" /><param name="quality" value="low" /><param name="scale" value="noscale" /><param name="salign" value="lt" /><param name="menu" value="false" /><param name="bgcolor" value="#000000" /><embed src="'+file_name+para_list+'" quality="low" menu="false" scale="noscale" salign="lt" bgcolor="#000000" width="'+movie_width+'" height="'+movie_height+'" name="FlashPhotoViewer" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />');
			
			document.write('</object>');
		} else{
			document.write('<table width="100%" height="80" border="0" cellspacing="10" cellpadding="10"<tr><td align=center valign=middle>');
			document.write('<a href="http://www.macromedia.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash&promoid=BIOX" target="_blank">This page needs flash player 5 or above, please click here to get flash player plugin.</a></td></tr></table>');

		}	
	},	 

	// explicitely set the size of the pictures, needed for Netscaope 4 browser
	SetSize:function(width, height)
	{
		this.m_ImageMaxWidth = width;
		this.m_ImageMaxHeight = height;
	},

	// preload an image.  when an image should be preloaded at some time, call this function 
	// para: 
	// 		IMG_file_path: 	the path of the image
	PreloadImage:function(IMG_file_path)
	{
		//get the next available slot
		var temp_ind = this.m_GeneralImageCache.length;
		
		this.m_GeneralImageCache[temp_ind] = new Image();
		this.m_GeneralImageCache[temp_ind].src = IMG_file_path;
		
	},

	// set the background image and color for toolbar
	// para:
	// 		image_path: 		the image file path for background
	// 		bg_color: 			the bg color that outside the image
	SetToolbarBG:function(image_path, bg_color)
	{
		this.m_ToolbarBGFile = image_path;
		this.m_ToolbarBGColor=bg_color;
	},

	// set the title text and bg color
	// para:
	// 		title: 				the text to be shown on the viewer
	// 		title_bg_color: 	the color of the title bg (e.g. #FFFFFF)
	SetTitle:function(title, title_bg_color)
	 {
		 this.m_Title = title;
		 if (title_bg_color)
			 this.m_TitleBarBGColor = title_bg_color;
	 },

	// set the image alt text
	// para:
	// 		text: 				image's alt text
	SetImageAlt:function(text)
	{
		this.m_ImageAlt = text;
	}
}
	
// create a new button object that stores the image file path and the description (tool tips) of the button
// para:
// 		name: 			the name of the button, to be used for changing image 
// 		IMG_file_path: 	the image file path of the button
// 		button_desc: 	the description (tool tips) of the button 
// 		function_name: 	the name of the function to be called when the button is clicked.  beware that the function must be a function in the generated web page
// 		IMG_over_file_path: 	the image file path for mouse over, if any
// 		IMG_down_file_path: 	the image file path for mouse down, if any
// 		IMG_disabled_file_path: 	the image file path for disabled state, if any
function Button(name, IMG_file_path, button_desc, function_name, IMG_over_file_path, IMG_down_file_path, IMG_disabled_file_path)
{
	this.m_Name = name;
	this.m_FilePath=IMG_file_path;
	this.m_Desc = button_desc;
	this.m_FunctionName= function_name;
	this.m_FilePathOver=IMG_over_file_path;
	this.m_FilePathDown=IMG_down_file_path;
	this.m_FilePathDisabled=IMG_disabled_file_path;

	//state info
	this.m_IsOver = false;
	this.m_IsDown=false;
	this.m_IsEnabled=true;

}

Button.prototype = {
	// update the button image based on the state
	UpdatePicture:function()
	{
		if (this.m_IsEnabled)
		{
			if (this.m_IsDown)
			{
				if (this.m_FilePathDown && (this.m_FilePathDown != ""))
					GetObject(this.m_Name).src=this.m_FilePathDown;
			}
			else
			{
				if (this.m_IsOver)
				{
					if (this.m_FilePathOver && (this.m_FilePathOver != ""))
						GetObject(this.m_Name).src=this.m_FilePathOver;
				}
				else
				{
					GetObject(this.m_Name).src=this.m_FilePath;
				}
			}
		}
		else
		{
			if (this.m_FilePathDisabled && (this.m_FilePathDisabled != ""))
				GetObject(this.m_Name).src=this.m_FilePathDisabled;
		}
	},

	// to be called when the button is pressed to update its image
	ButtonDown:function()
	{
		if (this.m_IsDown)
			return;
		
		this.m_IsDown=true;

		this.UpdatePicture();
	},

	// to be called when the button is released to update its image
	ButtonUp:function()
	{
		if (!this.m_IsDown)
			return;
		
		this.m_IsDown=false;

		this.UpdatePicture();
	},

	// to be called when the button is mouse overed to update its image
	ButtonOver:function()
	{
		if (this.m_IsOver)
			return;
		
		this.m_IsOver=true;

		this.UpdatePicture();
	},

	// to be called when the button is mouse out to update its image
	ButtonOut:function()
	{
		//check all for mouse down state becuase mouse up outside is not rasied
		this.ButtonUp()
		
		if ((!this.m_IsOver))
			return;
		
		this.m_IsOver=false;

		this.UpdatePicture();
	},

	// to be called when the button is enabled to update its image
	ButtonEnable:function()
	{
		if (this.m_IsEnabled)
			return;
		
		this.m_IsEnabled=true;

		this.UpdatePicture();
	},

	// to be called when the button is disabled to update its image
	ButtonDisable:function()
	{
		if (!this.m_IsEnabled)
			return;
		
		this.m_IsEnabled=false;

		this.UpdatePicture();
	}
}

// create a new toolbar button object that stores the image file path, the text and the description (tool tips) of the button
// para:
// 		IMG_file_path: 	the image file path of the button
// 		button_text: 	the text to be shown next to the button
// 		button_desc: 	the description (tool tips) of the button 
// 		function_name: 	the name of the function to be called when the button is clicked.  beware that the function must be a function in the generated web page
function ToolbarButton(IMG_file_path, button_text, button_desc, function_name)
{
	this.m_FilePath=IMG_file_path;
	this.m_Text = button_text;
	this.m_Desc = button_desc;
	this.m_FunctionName= function_name;
}

// class: TabPage
// represent a tab above the PhotoViewer
// para:
// 		desc: 			Description of the tab
// 		link: 			the link to redirect when it is clicked
// 		image_path: 	the path of the image if this tab is selected
// 		image_down_path: 	the path of the image is this tab is not selected
// 		enable_click: 	true if this tab could be clicked (normally a selected tab is not clickable)
function TabPage(desc, link, image_path, image_down_path, selected, enable_click)
{
	this.m_Desc = desc;
	this.m_Link = link;
	this.m_FilePath = image_path;
	this.m_FilePath_Down = image_down_path;
	this.m_IsSelected = selected;
	this.m_IsClickable = enable_click;
}

