/**

 * Template.js

 *

 * The template class manages all of the brochure's button data and provides

 * methods for formatting the HTML necessary to render these buttons.

 * In practice, only the formatRemoteToolbarImage() method will need to be

 * overridden in the descendant class. Most of this classes customization

 * is performed through the toolbarButtonData and templateButtonData objects.

 */



/**

 * This is the default data structure for a Template.

 * It is merged with the overrides when the real Template object calls registerData

 */

Template.BASE_DATA = {

	layers:

	{		//This defines the structure of the page in div tags.

		//each of these are evaluate to a corresponding function to get html for that frame

		//eg Client_Branding gets html from the function 'Template.prototype.getClient_BrandingContent = function(flag,params)'

		'Client_Branding': {},

		'Portal_Branding': {},

		'Action_Buttons': {},

		'templateButtonsLayer': {},

		'Main_Heading_Text': {},

		'Sub_Heading_Text': {},

		'General_Text': {},

		'Thumbnails_Frame': {},

		'Detailed_Image_Text': {},

		'Help_Frame': {},

		'Email_Frame': {},

		'viewerLayer': {},

		'View_Controls_Frame': {},

		'Floorplan': {},

		'Viewer_Frame':{},

		'External_Links':{},

		'Drop_Down_Menu':{},

		'Functions_Buttons': {},

		'User_Defined_Frame_1':{},

		'User_Defined_Frame_2':{},

		'User_Defined_Frame_3':{},

		'User_Defined_Frame_4':{},

		'User_Defined_Frame_5':{},

		'User_Defined_Frame_6':{},

		'User_Defined_Frame_7':{},

		'User_Defined_Frame_8':{}

		//'debugLayer':{}

	},

		//If non-null, after resource finding, this should be a string that is a URL to the style sheet

	style:null,

		//If non-null, after resource finding, this should be a string that is a URL to the CSS that defines the positioning of the layers

	layout:null,

		//This is a holder for everything to do with the remote toolbar stuff.

		//The format function is called to format the toolbar remote image.

		//The data parameter is this object itself

	remoteToolbar:{

		format:function(data){return "";}

	},

		//Each item in this array represents a button that exists once in the brochure

	buttonData:{

	},

		//This is one item that defines how to make floorplan buttons.

		//The constructor is called each timetha

	floorplanButtonData:{

		ctor:function(buttonType,data){}

	},

		//This is the default way to make icons on the floorplan surface.

		//After resource location, each item should be either null or an url

	iconData:{

		floorplan:{},

		pano:{},

		video:{},

		obj3d:{},

		still:{}

	},

		//This is how we define a thumbnail of a given type

	thumbnailData:{

		pano:{ctor:function(data,id,viewable){}},

		video:{ctor:function(data,id,viewable){}},

		still:{ctor:function(data,id,viewable){}},

		obj3d:{ctor:function(data,id,viewable){}}

	},



		//This is the default behaviour for a template - can be overridden in sub classes.

	viewerData:{

		'Java':{						//This whole sub object is ONLY for the Java viewer, not the flash viewer or other technologies

			'viewerObject':{			//Extra things for the applet

				attributes:{			//Attributes to be added to the APPLET tag

					codebase:{

						nodeType:"Resource",

						url:".."		//Important to not end with /

					},

					archive:"PanoViewer.zip"

				},

				callbackURL:{		//For Safari and maybe other browsers, we have to call out to another page

					nodeType:"Resource",	//and have that sent back to the browser.  This is that relative url.

					url:"../echo.html"

				},

				enablefiltering:true,	//Bilinear filtering is on by default

				incRate:50,				//50ms increment rate for redrawing non dragged animation

				revealHotSpots:true,	//Show all the hotspots

				logo:{					//The logo is found in the default place

					image:"$(brochure.portal.viewer_Logo_URL)"

				},

				onLoad:{				//When first loaded, callback to say that callouts work.  If the brochure doesn't get this message then either the viewer isn't working or it can't call out

					nodeType:"Callback",

					code:"function(){theBrochure.viewer.setCallbacksWorking(true);}"

				},

				onYawChange:{

					nodeType:"Callback",

					code:"function(yaw){theBrochure.template.notifyYawChanged(yaw);}"

				},

				onPitchChange:{

					nodeType:"Callback",

					code:"function(pitch){window.status=pitch;}"

				},

				onZoomChange:{

					nodeType:"Callback",

					code:"function(zoom){window.status=zoom;}"

				}

			},

			globalActions:{				//If no specific overrides are found, an action is looked up here

				'hide':null,

				'show':{

					nodeType:"LoadRoomAction",

					room:"$(v.v.indexInList)",		//v is the applet wrapper's object.  v.v is the Applet object.

					onFinish:{

						nodeType:"Callback",

						code:"function(){theBrochure.notifyViewableChanged('$(v.id)');}"

					}

				},

				'directedShow':"show",	//This is used by hotspot actions to show a viewable from a hotspot.

										//It allows the direction information in the hotspot to be used as part of the showing.

										//Default ignores it though

				'left':null,			//By default the standard actions do nothing

				'right':null,

				'zoomIn':null,

				'zoomOut':null,

				'thumbnail':{			//Called to move from one viewable to another when a thumbnail is clicked.

										//This is when there is nothing specific such as a hotspot.

										//PARAMS:

										//v - The from viewable

										//vType - The type of the from viewable

										//toV - The viewable to move to

										//toType - The type of the viewable to move to

										//cacheKey - The key used to cache with

					nodeType:"Script",

					loop:false,

					interruptable:true,

					actions:{			//We have 4 steps - do something at first, then hide, then show the other viewable, then do something in it

						vA_preHideThumbnail:{

							actionName:"preHideThumbnail",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						},

						vA_hide:{

							actionName:"hide",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						},

						vB_show:{

							actionName:"show",

							params:{

								v:"$(toV)",

								type:"$(toType)"

							}

						},

						vB_showOffThumbnail:{

							actionName:"showOffThumbnail",

							params:{

								v:"$(toV)",

								type:"$(toType)"

							}

						}

					}

				},

				'hotspotToURL':{							//Called when jumping to a URL outside

					nodeType:"Script",

					loop:false,

					interruptable:true,

					actions:{			//We have 2 steps - do something at first, then hide, then show the other viewable, then do something in it

						preHideHotspot:{

							actionName:"preHideHotspot",

							params:{

								v:"$(v)",

								type:"$(type)",

								hs:"$(hs)",

								cacheKey:"$(cacheKey)"

							}

						},

						showURL:{

							actionName:"showURL",

							params:{

								url:"$(url)"

							}

						}

					}

				},

				'showURL':{

					nodeType:"LoadURLAction",

					url:"$(url)",

					frame:"_new"

				},

				'thumbnailWithHotspot':"hotspotNormal",

													//Called for a thumbnail when there is a hotspot.

													//PARAMS

													// v - The destination viewable, NOT the pano

													// vType - The destination viewable type

													// fromV - The pano viewable

													// cacheKey - The key to cache on

													//

													//Call the hotspotNormal by default.  IE we go to the other viewable and stay there.

				'stillHotspot':"hotspotReturn",

													//Call the hotspotNormal by default.  IE we go to the other viewable and stay there.

				'panoHotspot':"hotspotReturn",

													//Called for a hotspot from a pano to another viewable.

													//PARAMS

													// v - The destination viewable, NOT the pano

													// vType - The destination viewable type

													// fromV - The pano viewable

													// cacheKey - The key to cache on

													//

													//By default we return after showing a viewable.

													//Note that this action is attached to the TO viewable.

													//By default, the pano type overrides this so that when we move

													//from one pano to another via a hotspot we stay there.

				'hotspotNormal':{

					nodeType:"Script",				//Move via hotspot from a pano to the viewable and stay there

					loop:false,						//Not part of the spec, but it is included for convenience.

					interruptable:true,				//We run a script with four actions as laid out below

					actions:{

						panoV_preHideHotspot:{

							actionName:"preHideHotspot",

							params:{

								v:"$(fromV)",

								type:"$(fromType)",

								hs:"$(hs)",

								cacheKey:"$(cacheKey)"

							}

						},

						panoV_hide:{

							actionName:"hide",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vB_show:{

							actionName:"directedShow",

							params:{

								v:"$(v)",

								type:"$(type)",

								hs:"$(hs)"

							}

						},

						vB_showOff:{

							actionName:"postShowHotspot",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						}

					}

				},

				'hotspotReturn':{					//Move from a pano to another viewable by hotspot and then come back

					nodeType:"Script",

					loop:false,

					interruptable:true,

					actions:{

						panoV_preHideHotspot:{

							actionName:"preHideHotspotReturn",

							params:{

								v:"$(fromV)",

								type:"$(fromType)",

								hs:"$(hs)",

								cacheKey:"$(cacheKey)"

							}

						},

						panoV_hide:{

							actionName:"hide",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vB_show:{

							actionName:"directedShow",

							params:{

								v:"$(v)",

								type:"$(type)",

								hs:"$(hs)"

							}

						},

						vB_showOff:{

							actionName:"postShowHotspotReturn",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						},

						vB_hide:{

							actionName:"hide",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						},

						panoA_show:{

							actionName:"reShow",

							params:{

								v:"$(fromV)",

								type:"$(fromType)",

								hs:"$(hs)"

							}

						},

						panoA_postShowHotspotFinish:{

							actionName:"postShowHotspotFinish",

							params:{

								v:"$(fromV)",

								type:"$(fromType)",

								hs:"$(hs)"

							}

						}

					}

				},

				reShow:"show",							//Only pano cares about reShow

				tourTransition:{						//Guided tour to move from us to the next one

														//parameters:

														//v			Destination

														//type		Destination type

														//fromV

														//fromType

														//cacheKey

					nodeType:"Script",

					loop:false,

					interruptable:true,

					actions:{

						vA_preHideTour:{

							actionName:"preHideTour",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vA_hide:{

							actionName:"hide",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vB_show:{

							actionName:"show",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						},

						vB_showOffTour:{

							actionName:"showOffTour",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						}

					}

				},

				tourTransitionWithHotspot:{						//When moving in the guided tour from one viewable to

					nodeType:"Script",							//another and there is a hotspot

					loop:false,

					interruptable:true,

					actions:{

						vA_preHideTour:{

							actionName:"preHideTourWithHotspot",

							params:{

								v:"$(fromV)",

								type:"$(fromType)",

								hs:"$(hs)",

								cacheKey:"$(cacheKey)"

							}

						},

						vA_hide:{

							actionName:"hide",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vB_show:{

							actionName:"show",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						},

						vB_showOffTour:{

							actionName:"showOffTour",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						}

					}

				},

				tourInit:null,				//If the guided tour starts from us

				tourStart:{

					nodeType:"Script",							//another and there is a hotspot

					loop:false,

					interruptable:true,

					actions:{

						vA_preHideTour:{

							actionName:"preHideTour",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vA_hide:{

							actionName:"hide",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vB_show:{

							actionName:"show",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						}

					}

				},

				tourStartWithHotspot:{

					nodeType:"Script",							//another and there is a hotspot

					loop:false,

					interruptable:true,

					actions:{

						vA_preHideTour:{

							actionName:"preHideTourWithHotspot",

							params:{

								v:"$(fromV)",

								type:"$(fromType)",

								hs:"$(hs)",

								cacheKey:"$(cacheKey)"

							}

						},

						vA_hide:{

							actionName:"hide",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vB_show:{

							actionName:"show",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						}

					},

					preHideThumbnail:null,

					showOffThumbnail:null,

					preHideHotspot:null,

					postShowHotspot:null,

					preHideTour:null,

					showOffTour:null,

					preHideTourWithHotspot:null,

					postShowHotspotReturn:null,

					postShowHotspotFinish:null,

					thumbnailWithHotspot:null

				}

			},

			viewableTypes:{			//This defines for each type of viewable the default attributes

				'pano':{			//The panorama type

					defaultRoomType:"SpheriCylinderRoom",

					hotspotType:"Centred3DHotspot",

					extra:{			//Extra things to add to every pano object

						hotspotBG:"#003366",

						hotspotFG:"white",

						topAngle:"15",

						bottomAngle:"-75"

					},

					excludeProps:{				//When adding extra stuff, don't copy these across from brochure data

						"type":true,			//This is always "pano" and identifies the viewable as such

						"description":true,		//The description

						"short_desc":true,		//The short description

						"thumbnailURL":true,	//The URL for the thumbnail

						"order":true,			//The order of the thumbnail

						"roomType":true,		//The type of room object to use - picked up in the specific code

						"hotspots":true			//We use this in specific code to make the PanoHotspots into Centred3DHotspots

					},

					allHotspots:{				//Definition of every hotspot in this pano

						extras:{				//Adds to every hotspot as default values overridable in the real template and brochure

							points:"(20,20)(20,-20)(-20,-20)(-20,20)",

							text:"$(page.viewables[dataHS.targetViewableName].short_desc)"

						},

						excludeProps:{			//When copying a hotspot across, what do we exclude?

							targetViewableName:true,//This is the viewable name (key in the viewables array) to go to

							url:true			//This is for when we link to a URL instead

						}

					},

					actions:{					//The actions

						'left':"$(typeof(v.v.partial) == 'undefined' ? 'normalLeft' : 'partialLeft')",

						'partialLeft':{

							nodeType:"PingPongAction",

							time:60000,

							yaw:-360

						},

						'normalLeft':{

							nodeType:"PositionAction",

							time:60000,

							isRel:true,

							pos:{

								yaw:-360

							}

						},

						'right':"$(typeof(v.v.partial) == 'undefined' ? 'normalRight' : 'partialRight')",

						'partialRight':{

							nodeType:"PingPongAction",

							time:60000,

							yaw:360

						},

						'normalRight':{

							nodeType:"PositionAction",

							time:60000,

							isRel:true,

							pos:{

								yaw:360

							}

						},

						'zoomIn':{

							nodeType:"PositionAction",

							time:2000,

							isRel:true,

							pos:{

								zoom:.5

							}

						},

						'zoomOut':{

							nodeType:"PositionAction",

							time:2000,

							isRel:true,

							pos:{

								zoom:-.5

							}

						},

						'show':{

							nodeType:"LoadRoomAction",

							room:"$(v.v.indexInList)",		//v is the applet wrapper's object.  v.v is the Applet object.

							onFinish:{

								nodeType:"Callback",

								code:"function(){theBrochure.notifyViewableChanged('$(v.id)');}"

							},

							initPos:"$(typeof(v.v.initPos) == 'undefined' ? {yaw:0,pitch:0,zoom:1} : v.v.initPos)"		//TODO test this

						},

						'reShow':'show',

						tourInit:{				//When the tour begins in us

							nodeType:"PositionAction",

							isRel:false,

							pos:"$(v.v.initPos.yaw == undefined && v.v.initPos.pitch == undefined && v.v.initPos.zoom == undefined ? {yaw:0,pitch:0,zoom:1} : v.v.initPos)",		//TODO test this

							time:500		//Very quick

						},

						stillHotspot:'hotspotNormal',

						panoHotspot:'hotspotNormal',		//Pano to Pano means go to it and stay

						postShowHotspot:"postShowHotspotDefault",			//When there is a normal hotspot to us

						postShowHotspotReturn:"postShowHotspotDefault",		//When there is a hotspot to us that returns

						showOff:"left",					//Thumbnail from us to us

						showOffThumbnail:"left",		//Thumbnail from someone else to us after moving to us

						showOffTour:{

							nodeType:"PositionAction",

							time:7000,

							isRel:true,

							pos:{

								yaw:180

							}

						},

						directedShow:{

							nodeType:"LoadRoomAction",

							room:"$(v.v.indexInList)",		//v is the applet wrapper's object.  v.v is the Applet object.

							onFinish:{

								nodeType:"Callback",

								code:"function(){theBrochure.notifyViewableChanged('$(v.id)');}"

							},

							initPos:{

							  //yaw:"$(hs.pos.yaw)",			//This is in comments because the default is to just show the room.

							  //pitch:"$(hs.pos.pitch)",		//But if all the rooms are aligned then we can walk through from one to another

							  //zoom:"$(hs.pos.zoom)"			//This can be nicely changed to zoom into it too

							}

						},

						preHideThumbnail:"preHideDefault",			//Just a delegation

						preHideTour:"preHideDefault",				//Just a delegation

									//Specific to the pano

						preHideHotspot:"preHotspotDefault",

						preHideHotspotReturn:"preHotspotDefault",

						postShowHotspotFinish:"postShowDefault",

						preHideTourWithHotspot:"preHotspotDefault",

									//These are not part of the spec but just for delegation without customisation problems

						postShowHotspotDefault:{

							nodeType:"Script",

							loop:false,

							interruptable:true,

							actions:{

								postShow:"postShowDefault",

								showOff:"showOff"

							}

						},

						preHotspotDefaultHotSpotPositionAction:{

							nodeType:"HotSpotPositionAction",

							time:3000,

							hotspot:"$(hs.indexInList)"

						},

						preHotspotDefault:{

							nodeType:"Script",

							loop:false,

							interruptable:true,

							actions:{

								postShow:"preHotspotDefaultHotSpotPositionAction",

								showOff:"zoomIn"

							}

						},

						postShowDefault:null,

						preHideDefault:null

					}

				},

				'still':{

					defaultRoomType:"ImageLayer",

					hotspotType:"FlatHotSpot",

					allHotspots:{				//Definition of every hotspot in this pano

						extras:{				//Adds to every hotspot as default values overridable in the real template and brochure

							shape:"$(dataHS.shape)",

							text:"$(page.viewables[dataHS.targetViewableName].short_desc)"

						},

						excludeProps:{			//When copying a hotspot across, what do we exclude?

							targetViewableName:true,//This is the viewable name (key in the viewables array) to go to

							url:true			//This is for when we link to a URL instead

						}

					},

					excludeProps:{

						"type":true,			//This is always "pano" and identifies the viewable as such

						"description":true,

						"short_desc":true,

						"thumbnailURL":true,

						"order":true

					},

					actions:{

						postShowHotspot:"postShowDefault",

						postShowHotspotReturn:"postShowDefault",

						showOff:null,

						showOffTour:{

							nodeType:"PauseAction",

							time:3000

						},

						showOffThumbnail:"postShowDefault",

						preHideThumbnail:null,

						preHideTour:null

					}

				},

				'video':{

					defaultRoomType:"ImageSequenceLayer",

					hotspotType:"FlatHotspot",

					allHotspots:{				//Definition of every hotspot in this pano

						extras:{				//Adds to every hotspot as default values overridable in the real template and brochure

							shape:"$(dataHS.shape)",

							text:"$(page.viewables[dataHS.targetViewableName].short_desc)"

						},

						excludeProps:{			//When copying a hotspot across, what do we exclude?

							targetViewableName:true,//This is the viewable name (key in the viewables array) to go to

							url:true			//This is for when we link to a URL instead

						}

					},

					extra:{

						waitForFullImage:true,

						allowDragging:false,

						defaultTime:6000

					},

					excludeProps:{

						"type":true,

						"description":true,

						"short_desc":true,

						"thumbnailURL":true,

						"order":true

					},

					actions:{

						left:"play",

						right:"play",

						postShowHotspot:"play",

						postShowHotspotReturn:"play",

						showOff:"play",

						showOffTour:"play",

						showOffThumbnail:"play",

						preHideThumbnail:null,

						preHideTour:null,

								//Not part of spec

						play:{

							nodeType:"PlayImageSequenceAction",

							forward:true,

							respectTiming:true,

							loop:false,

							interruptable:true,

							rewindAtEnd:true,

							isLayer:false

						}

					}

				},

				'obj3d':{

					defaultRoomType:"ImageSequenceLayer",

					hotspotType:"FlatHotspot",

					allHotspots:{				//Definition of every hotspot in this pano

						extras:{				//Adds to every hotspot as default values overridable in the real template and brochure

							shape:"$(dataHS.shape)",

							text:"$(page.viewables[dataHS.targetViewableName].short_desc)"

						},

						excludeProps:{			//When copying a hotspot across, what do we exclude?

							targetViewableName:true,//This is the viewable name (key in the viewables array) to go to

							url:true			//This is for when we link to a URL instead

						}

					},

					extras:{

						waitForFullImage:true,

						allowDragging:true,

						flush:false,

						defaultTime:300

					},

					excludeProps:{

						"type":true,

						"description":true,

						"short_desc":true,

						"thumbnailURL":true,

						"order":true

					},

					actions:{

						left:"play",

						right:"playBackwards",

						postShowHotspot:"play",

						postShowHotspotReturn:"play",

						showOff:"play",

						showOffTour:"play",

						showOffThumbnail:"play",

						preHideThumbnail:"preHideDefault",

						preHideTour:"preHideDefault",

								//Not part of spec

						'play':{

							nodeType:"PlayImageSequenceAction",

							forward:true,

							respectTiming:false,

							loop:true,

							interruptable:true,

							isLayer:false,

							rewindAtEnd:false			//TODO was in comments



						},

						'playBackwards':{

							nodeType:"PlayImageSequenceAction",

							forward:false,

							respectTiming:false,

							loop:true,

							interruptable:true,

							isLayer:false,

							rewindAtEnd:false			//TODO was in comments

						},

						preHideDefault:null

					}

				}

			}

		},

		'Flash':{						//This whole sub object is ONLY for the Java viewer, not the flash viewer or other technologies

			'viewerObject':{			//Extra things for the applet

				attributes:{			//Attributes to be added to the APPLET tag

					codebase:{

						nodeType:"Resource",

						url:"../"		//Important to not end with /

					},

					bgcolor:"#FFFFFF"

				},

				callbackURL:{		//For Safari and maybe other browsers, we have to call out to another page

					nodeType:"Resource",	//and have that sent back to the browser.  This is that relative url.

					url:"../echo.html"

				},

				enablefiltering:true,	//Bilinear filtering is on by default

				incRate:50,				//50ms increment rate for redrawing non dragged animation

				bgcolor:"#FFFFF",

				reveal_hotspots:true,	//Show all the hotspots

				logo:{					//The logo is found in the default place

					image:"<logo><image>"+"$(brochure.portal.logoURL)"+"</image><bgcolor></bgcolor></logo>"

				},

				onLoad:{				//When first loaded, callback to say that callouts work.  If the brochure doesn't get this message then either the viewer isn't working or it can't call out

					nodeType:"Callback",

					code:"function(){theBrochure.viewer.setCallbacksWorking(true);}"

				},

				onYawChange:{

					nodeType:"Callback",

					code:"function(yaw){theBrochure.template.notifyYawChanged(yaw);}"

				},

				onPitchChange:{

					nodeType:"Callback",

					code:"function(pitch){window.status=pitch;}"

				},

				onZoomChange:{

					nodeType:"Callback",

					code:"function(zoom){window.status=zoom;}"

				}

			},

			globalActions:{				//If no specific overrides are found, an action is looked up here

				'hide':null,

				'show':{

					nodeType:"load_room",

					room:"$(v.v.indexInList)",		//v is the applet wrapper's object.  v.v is the Applet object.

					onFinish:{

						nodeType:"Callback",

						code:"function(){theBrochure.notifyViewableChanged('$(v.id)');}"

					}

				},

				'directedShow':"show",	//This is used by hotspot actions to show a viewable from a hotspot.

										//It allows the direction information in the hotspot to be used as part of the showing.

										//Default ignores it though

				'left':null,			//By default the standard actions do nothing

				'right':null,

				'zoomIn':null,

				'zoomOut':null,

				'thumbnail':{			//Called to move from one viewable to another when a thumbnail is clicked.

										//This is when there is nothing specific such as a hotspot.

										//PARAMS:

										//v - The from viewable

										//vType - The type of the from viewable

										//toV - The viewable to move to

										//toType - The type of the viewable to move to

										//cacheKey - The key used to cache with

					nodeType:"Script",

					loop:false,

					interruptable:true,

					actions:{			//We have 4 steps - do something at first, then hide, then show the other viewable, then do something in it

						vA_preHideThumbnail:{

							actionName:"preHideThumbnail",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						},

						vA_hide:{

							actionName:"hide",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						},

						vB_show:{

							actionName:"show",

							params:{

								v:"$(toV)",

								type:"$(toType)"

							}

						},

						vB_showOffThumbnail:{

							actionName:"showOffThumbnail",

							params:{

								v:"$(toV)",

								type:"$(toType)"

							}

						}

					}

				},

				'hotspotToURL':{							//Called when jumping to a URL outside

					nodeType:"Script",

					loop:false,

					interruptable:true,

					actions:{			//We have 2 steps - do something at first, then hide, then show the other viewable, then do something in it

						preHideHotspot:{

							actionName:"preHideHotspot",

							params:{

								v:"$(v)",

								type:"$(type)",

								hs:"$(hs)",

								cacheKey:"$(cacheKey)"

							}

						},

						showURL:{

							actionName:"showURL",

							params:{

								url:"$(url)"

							}

						}

					}

				},

				'showURL':{

					nodeType:"LoadURLAction",

					url:"$(url)",

					frame:"_new"

				},

				'thumbnailWithHotspot':"hotspotNormal",

													//Called for a thumbnail when there is a hotspot.

													//PARAMS

													// v - The destination viewable, NOT the pano

													// vType - The destination viewable type

													// fromV - The pano viewable

													// cacheKey - The key to cache on

													//

													//Call the hotspotNormal by default.  IE we go to the other viewable and stay there.

				'hotspot':"hotspotReturn",

													//Called for a hotspot from a pano to another viewable.

													//PARAMS

													// v - The destination viewable, NOT the pano

													// vType - The destination viewable type

													// fromV - The pano viewable

													// cacheKey - The key to cache on

													//

													//By default we return after showing a viewable.

													//Note that this action is attached to the TO viewable.

													//By default, the pano type overrides this so that when we move

													//from one pano to another via a hotspot we stay there.

				'hotspotNormal':{

					nodeType:"Script",				//Move via hotspot from a pano to the viewable and stay there

					loop:false,						//Not part of the spec, but it is included for convenience.

					interruptable:true,				//We run a script with four actions as laid out below

					actions:{

						panoV_preHideHotspot:{

							actionName:"preHideHotspot",

							params:{

								v:"$(fromV)",

								type:"$(fromType)",

								hs:"$(hs)",

								cacheKey:"$(cacheKey)"

							}

						},

						panoV_hide:{

							actionName:"hide",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vB_show:{

							actionName:"directedShow",

							params:{

								v:"$(v)",

								type:"$(type)",

								hs:"$(hs)"

							}

						},

						vB_showOff:{

							actionName:"postShowHotspot",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						}

					}

				},

				'hotspotReturn':{					//Move from a pano to another viewable by hotspot and then come back

					nodeType:"Script",

					loop:false,

					interruptable:true,

					actions:{

						panoV_preHideHotspot:{

							actionName:"preHideHotspotReturn",

							params:{

								v:"$(fromV)",

								type:"$(fromType)",

								hs:"$(hs)",

								cacheKey:"$(cacheKey)"

							}

						},

						panoV_hide:{

							actionName:"hide",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vB_show:{

							actionName:"directedShow",

							params:{

								v:"$(v)",

								type:"$(type)",

								hs:"$(hs)"

							}

						},

						vB_showOff:{

							actionName:"postShowHotspotReturn",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						},

						vB_hide:{

							actionName:"hide",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						},

						panoA_show:{

							actionName:"reShow",

							params:{

								v:"$(fromV)",

								type:"$(fromType)",

								hs:"$(hs)"

							}

						},

						panoA_postShowHotspotFinish:{

							actionName:"postShowHotspotFinish",

							params:{

								v:"$(fromV)",

								type:"$(fromType)",

								hs:"$(hs)"

							}

						}

					}

				},

				reShow:"show",							//Only pano cares about reShow

				tourTransition:{						//Guided tour to move from us to the next one

														//parameters:

														//v			Destination

														//type		Destination type

														//fromV

														//fromType

														//cacheKey

					nodeType:"Script",

					loop:false,

					interruptable:true,

					actions:{

						vA_preHideTour:{

							actionName:"preHideTour",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vA_hide:{

							actionName:"hide",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vB_show:{

							actionName:"show",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						},

						vB_showOffTour:{

							actionName:"showOffTour",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						}

					}

				},

				tourTransitionWithHotspot:{						//When moving in the guided tour from one viewable to

					nodeType:"Script",							//another and there is a hotspot

					loop:false,

					interruptable:true,

					actions:{

						vA_preHideTour:{

							actionName:"preHideTourWithHotspot",

							params:{

								v:"$(fromV)",

								type:"$(fromType)",

								hs:"$(hs)",

								cacheKey:"$(cacheKey)"

							}

						},

						vA_hide:{

							actionName:"hide",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vB_show:{

							actionName:"show",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						},

						vB_showOffTour:{

							actionName:"showOffTour",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						}

					}

				},

				tourInit:null,				//If the guided tour starts from us

				tourStart:{

					nodeType:"Script",							//another and there is a hotspot

					loop:false,

					interruptable:true,

					actions:{

						vA_preHideTour:{

							actionName:"preHideTour",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vA_hide:{

							actionName:"hide",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vB_show:{

							actionName:"show",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						}

					}

				},

				tourStartWithHotspot:{

					nodeType:"Script",							//another and there is a hotspot

					loop:false,

					interruptable:true,

					actions:{

						vA_preHideTour:{

							actionName:"preHideTourWithHotspot",

							params:{

								v:"$(fromV)",

								type:"$(fromType)",

								hs:"$(hs)",

								cacheKey:"$(cacheKey)"

							}

						},

						vA_hide:{

							actionName:"hide",

							params:{

								v:"$(fromV)",

								type:"$(fromType)"

							}

						},

						vB_show:{

							actionName:"show",

							params:{

								v:"$(v)",

								type:"$(type)"

							}

						}

					}

				}

			},

			viewableTypes:{			//This defines for each type of viewable the default attributes

				'pano':{			//The panorama type

					defaultRoomType:"pano", //defaultRoomType:"3dpano",

					hotspotType:"Centred3DHotspot",

					extra:{			//Extra things to add to every pano object

						limit:"$(typeof(v.v.partial) == 'undefined' ? '' : '<yaw>'+v.v.partial+'</yaw>')",

						hotspotBG:"#003366",

						hotspotFG:"white",

						name:"$(v.v.short_desc)"

					},

					excludeProps:{				//When adding extra stuff, don't copy these across from brochure data

						"type":true,			//This is always "pano" and identifies the viewable as such

						"description":false,		//The description

						"short_desc":false,		//The short description

						"thumbnailURL":true,	//The URL for the thumbnail

						"order":true,			//The order of the thumbnail

						"roomType":true,		//The type of room object to use - picked up in the specific code

						"hotspots":false			//We use this in specific code to make the PanoHotspots into Centred3DHotspots

					},

					allHotspots:{				//Definition of every hotspot in this pano

						extras:{				//Adds to every hotspot as default values overridable in the real template and brochure

							points:"(20,20)(20,-20)(-20,-20)(-20,20)",

							text:"$(page.viewables[dataHS.targetViewableName].short_desc)"

						},

						excludeProps:{			//When copying a hotspot across, what do we exclude?

							targetViewableName:true,//This is the viewable name (key in the viewables array) to go to

							url:true			//This is for when we link to a URL instead

						}

					},

					actions:{					//The actions

						'left':"$(typeof(v.v.partial) == 'undefined' ? 'normalLeft' : 'partialLeft')",

						'partialLeft':{

							nodeType:"PingPongAction",

							time:60000,

							yaw:-720

						},

						'normalLeft':{

							nodeType:"position",

							time:60000,

							relative:true,

								yaw:-720,

								pitch:0

						},

						'right':"$(typeof(v.v.partial) == 'undefined' ? 'normalRight' : 'partialRight')",

						'partialRight':{

							nodeType:"PingPongAction",

							time:60000,

							yaw:720

						},

						'normalRight':{

							nodeType:"position",

							time:60000,

							relative:true,

								yaw:720

						},

						'zoomIn':{

							nodeType:"position",

							time:4000,

							relative:true,

								zoom:.5

						},

						'zoomOut':{

							nodeType:"position",

							time:4000,

							relative:true,

								zoom:-.5

						},

						'show':{

							nodeType:"load_room",

							room:"$(v.v.indexInList)",		//v is the applet wrapper's object.  v.v is the Applet object.

							onFinish:{

								nodeType:"Callback",

								code:"function(){theBrochure.notifyViewableChanged('$(v.id)');}"

							},

							initPos:"$(typeof(v.v.initPos) == 'undefined' ? {yaw:0,pitch:0,zoom:1} : v.v.initPos)"		//TODO test this

						},

						'reShow':'show',

						tourInit:{				//When the tour begins in us

							nodeType:"position",

							relative:false,

							pos:"$(typeof(v.v.initPos) == 'undefined' ? {yaw:0,pitch:0,zoom:1} : v.v.initPos)",		//TODO test this

							time:1000		//Very quick

						},

						hotspot:'hotspotNormal',		//Pano to Pano means go to it and stay

						postShowHotspot:"postShowHotspotDefault",			//When there is a normal hotspot to us

						postShowHotspotReturn:"postShowHotspotDefault",		//When there is a hotspot to us that returns

						showOff:"left",					//Thumbnail from us to us

						showOffThumbnail:"left",		//Thumbnail from someone else to us after moving to us

						showOffTour:{

							nodeType:"position",

							time:7000,

							relative:true,

								yaw:180

						},

						directedShow:{

							nodeType:"load_room",

							room:"$(v.v.indexInList)",		//v is the applet wrapper's object.  v.v is the Applet object.

							onFinish:{

								nodeType:"Callback",

								code:"function(){theBrochure.notifyViewableChanged('$(v.id)');}"

							},

						  initPos:{

							  //yaw:"$(hs.pos.yaw)",			//This is in comments because the default is to just show the room.

							  //pitch:"$(hs.pos.pitch)",		//But if all the rooms are aligned then we can walk through from one to another

							  //zoom:"$(hs.pos.zoom)"			//This can be nicely changed to zoom into it too

						  }

						},

						preHideThumbnail:"preHideDefault",			//Just a delegation

						preHideTour:"preHideDefault",				//Just a delegation

									//Specific to the pano

						preHideHotspot:"preHotspotDefault",

						preHideHotspotReturn:"preHotspotDefault",

						postShowHotspotFinish:"postShowDefault",

						preHideTourWithHotspot:"preHotspotDefault",

									//These are not part of the spec but just for delegation without customisation problems

						postShowHotspotDefault:{

							nodeType:"Script",

							loop:false,

							interruptable:true,

							actions:{

								postShow:"postShowDefault",

								showOff:"showOff"

							}

						},

						preHotspotDefault:{

							nodeType:"HotSpotPosition",

							time:3000,

							hotspot:"$(hs.indexInList)"

						},

						postShowDefault:null,

						preHideDefault:null

					}

				},

				'still':{

					defaultRoomType:"still",

					hotspotType:"FlatHotSpot",

					extra:{

						name:"$(v.v.short_desc)"

					},

					allHotspots:{				//Definition of every hotspot in this pano

						extras:{				//Adds to every hotspot as default values overridable in the real template and brochure

							points:"$(dataHS.shape)",

							text:"$(page.viewables[dataHS.targetViewableName].short_desc)"

						},

						excludeProps:{			//When copying a hotspot across, what do we exclude?

							targetViewableName:true,//This is the viewable name (key in the viewables array) to go to

							url:true			//This is for when we link to a URL instead

						}

					},

					excludeProps:{

						"type":true,			//This is always "pano" and identifies the viewable as such

						"description":false,

						"short_desc":false,

						"thumbnailURL":true,

						"order":true

					},

					actions:{

						postShowHotspot:"postShowDefault",

						postShowHotspotReturn:"postShowDefault",

						showOff:null,

						showOffTour:{

							nodeType:"position",

							time:3000

						},

						showOffThumbnail:"postShowDefault",

						preHideThumbnail:null,

						preHideTour:null

					}

				},

				'video':{

					defaultRoomType:"slideshow",

					hotspotType:"FlatHotspot",

					allHotspots:{				//Definition of every hotspot in this pano

						extras:{				//Adds to every hotspot as default values overridable in the real template and brochure

							points:"$(dataHS.shape)",

							text:"$(page.viewables[dataHS.targetViewableName].short_desc)"

						},

						excludeProps:{			//When copying a hotspot across, what do we exclude?

							targetViewableName:true,//This is the viewable name (key in the viewables array) to go to

							url:true			//This is for when we link to a URL instead

						}

					},

					extra:{

						initial_action:'3',

						waitForFullImage:true,

						allowDragging:false,

						defaultTime:6000,

						name:"$(v.v.short_desc)"

					},

					excludeProps:{

						type:true,

						"description":false,

						"short_desc":false,

						"thumbnailURL":true,

						"order":true

					},

					actions:{

						left:"play",

						right:"play",

						postShowHotspot:"play",

						postShowHotspotReturn:"play",

						showOff:"play",

						showOffTour:"play",

						showOffThumbnail:"play",

						preHideThumbnail:null,

						preHideTour:null,

								//Not part of spec

						play:{

							nodeType:"PlayImageSequenceAction",

							forward:true,

							respectTiming:true,

							loop:false,

							interruptable:true,

							rewindAtEnd:true,

							isLayer:false

						},

						'zoomOut':{

							nodeType:"position",

							time:2000,

							relative:true,

								zoom:-.5

						},

						'zoomIn':{

							nodeType:"position",

							time:2000,

							relative:true,

								zoom:.5

						}

					}

				},

				'obj3d':{

					defaultRoomType:"3dobject",

					hotspotType:"FlatHotspot",

					allHotspots:{				//Definition of every hotspot in this pano

						extras:{				//Adds to every hotspot as default values overridable in the real template and brochure

							points:"$(dataHS.shape)",

							text:"$(page.viewables[dataHS.targetViewableName].short_desc)"

						},

						excludeProps:{			//When copying a hotspot across, what do we exclude?

							targetViewableName:true,//This is the viewable name (key in the viewables array) to go to

							url:true			//This is for when we link to a URL instead

						}

					},

					extras:{

						waitForFullImage:true,

						allowDragging:true,

						flush:false,

						defaultTime:300,

						name:"$(v.v.short_desc)"

					},

					excludeProps:{

						type:true,

						"description":false,

						"short_desc":false,

						"thumbnailURL":true,

						"order":true

					},

					actions:{

						left:"play",

						right:"playBackwards",

						postShowHotspot:"play",

						postShowHotspotReturn:"play",

						showOff:"play",

						showOffTour:"play",

						showOffThumbnail:"play",

						preHideThumbnail:"preHideDefault",

						preHideTour:"preHideDefault",

								//Not part of spec

						'play':{

							nodeType:"PlayImageSequenceAction",

							forward:true,

							respectTiming:false,

							loop:true,

							interruptable:true,

							isLayer:false,

							rewindAtEnd:false			//TODO was in comments



						},

						'playBackwards':{

							nodeType:"PlayImageSequenceAction",

							forward:false,

							respectTiming:false,

							loop:true,

							interruptable:true,

							isLayer:false,

							rewindAtEnd:false			//TODO was in comments

						},

						preHideDefault:null

					}

				}

			}

		}

	}

};



/**

 * This is optionally used by subclasses as default places to find images relative to the sub class, not this class.

 */

Template.DEFAULT_DATA = {

	style:{nodeType:"Resource",url:'look.css'},

	layout:{nodeType:"Resource",url:'layout.css'},

	remoteToolbar:{

		img:{nodeType:"Resource",url:'Images/toolbar_remote_default.gif'},

		// Function deprecated 20060515 (jamie)

		/*

		format:function(data){

			return '<img name="toolbarRemote" '

				+ 'height="39" '

				+ 'width="123" '

				+ 'src="' + data.img + '">';

		}

		*/

		// New function

		format:function(data){

			return '<img name="toolbarRemote" '

				+ 'src="' + data.img + '">';

		}

	},

	iconData:{

		floorplan:{nodeType:"Resource",url:"Images/icon_floorplan_floorplan.gif"},

		pano:{nodeType:"Resource",url:"Images/pano-ani.gif"},

		video:{nodeType:"Resource",url:"Images/film-ani.gif"},

		obj3d:{nodeType:"Resource",url:"Images/object-ani.gif"},

		still:{nodeType:"Resource",url:"Images/still-ani.gif"}

	},

	buttonData:{

		mute:

		{

			ctor:		MuteButton,

			image:		{nodeType:"Resource",url:'Images/toolbar_nosound.gif'},

			rolloverImage:	{nodeType:"Resource",url:'Images/toolbar_nosound_over.gif'},

			muteImage:		{nodeType:"Resource",url:'Images/toolbar_mute.gif'},

			rolloverMuteImage:{nodeType:"Resource",url:'Images/toolbar_mute_over.gif'},

			activeImage:		{nodeType:"Resource",url:'Images/toolbar_activeSound.gif'},

			rolloverActiveImage:{nodeType:"Resource",url:'Images/toolbar_activeSound_over.gif'},

			width:		33,

			height:		39,

			remoteId:	'toolbarRemote',

			remoteWidth:	123,

			remoteHeight:	39,

			remoteImage:       	{nodeType:"Resource",url:'Images/toolbar_remote_default.gif'},

			remoteRolloverImage:   	{nodeType:"Resource",url:'Images/toolbar_remote_mute.gif'},

			actions:{

				mute:"viewer"

			}

		},

			// Toolbar button data.

		zoomOut:

		{

			ctor:		RemoteButton,

			image:		{nodeType:"Resource",url:'Images/toolbar_zoom_out.gif'},

			rolloverImage:	{nodeType:"Resource",url:'Images/toolbar_zoom_out_over.gif'},

			width:		33,

			height:		39,

			remoteId:	'toolbarRemote',

			remoteWidth:	123,

			remoteHeight:	39,

			remoteImage:       	{nodeType:"Resource",url:'Images/toolbar_remote_default.gif'},

			remoteRolloverImage:   	{nodeType:"Resource",url:'Images/toolbar_remote_zoom_out.gif'},

			actions:{

				zoomOut:"viewer"

			}

		},

		zoomIn:

		{

			ctor:		RemoteButton,

			image:		{nodeType:"Resource",url:'Images/toolbar_zoom_in.gif'},

			rolloverImage:	{nodeType:"Resource",url:'Images/toolbar_zoom_in_over.gif'},

			width:		33,

			height:		39,

			remoteId:	'toolbarRemote',

			remoteWidth:	123,

			remoteHeight:	39,

			remoteImage:        	{nodeType:"Resource",url:'Images/toolbar_remote_default.gif'},

			remoteRolloverImage:   	{nodeType:"Resource",url:'Images/toolbar_remote_zoom_in.gif'},

			actions:{

				zoomIn:"viewer"

			}

		},

		help:

		{

			ctor:		RemoteButton,

			image:		{nodeType:"Resource",url:'Images/toolbar_help.gif'},

			rolloverImage:	{nodeType:"Resource",url:'Images/toolbar_help_over.gif'},

			width:		33,

			height:		39,

			remoteId:	'toolbarRemote',

			remoteWidth:	123,

			remoteHeight:	39,

			remoteImage:        	{nodeType:"Resource",url:'Images/toolbar_remote_default.gif'},

			remoteRolloverImage:   	{nodeType:"Resource",url:'Images/toolbar_remote_help.gif'},

			actions:{

					showHelp_Frame:"template"

			}

		},

		left:

		{

			ctor:			RemoteButton,

			image:			{nodeType:"Resource",url:'Images/toolbar_move_left.gif'},

			rolloverImage:		{nodeType:"Resource",url:'Images/toolbar_move_left_over.gif'},

			width:			33,

			height:			39,

			remoteId:		'toolbarRemote',

			remoteWidth:		123,

			remoteHeight:		39,

			remoteImage:        	{nodeType:"Resource",url:'Images/toolbar_remote_default.gif'},

			remoteRolloverImage:   	{nodeType:"Resource",url:'Images/toolbar_remote_move_left.gif'},

			actions:{

				left:"viewer"

			}

		},

		stop:

		{

			ctor:					RemoteButton,

			image:					{nodeType:"Resource",url:'Images/toolbar_stop.gif'},

			rolloverImage:			{nodeType:"Resource",url:'Images/toolbar_stop_over.gif'},

			width:							33,

			height:							39,

			remoteId:						'toolbarRemote',

			remoteWidth:					123,

			remoteHeight:					39,

			remoteImage:        	{nodeType:"Resource",url:'Images/toolbar_remote_default.gif'},

			remoteRolloverImage:   	{nodeType:"Resource",url:'Images/toolbar_remote_stop.gif'},

			actions:{				stop:"viewer"

			}

		},

		right:

		{

			ctor:					RemoteButton,

			image:					{nodeType:"Resource",url:'Images/toolbar_move_right.gif'},

			rolloverImage:			{nodeType:"Resource",url:'Images/toolbar_move_right_over.gif'},

			width:							33,

			height:							39,

			remoteId:						'toolbarRemote',

			remoteWidth:					123,

			remoteHeight:					39,

			remoteImage:        	{nodeType:"Resource",url:'Images/toolbar_remote_default.gif'},

			remoteRolloverImage:   	{nodeType:"Resource",url:'Images/toolbar_remote_move_right.gif'},

			actions:{

				right:"viewer"

			}

		},

		enlarge:

		{

			ctor:					RemoteButton,

			image:					{nodeType:"Resource",url:'Images/toolbar_enlarge.gif'},

			rolloverImage:			{nodeType:"Resource",url:'Images/toolbar_enlarge_over.gif'},

			width:							33,

			height:							39,

			remoteId:						'toolbarRemote',

			remoteWidth:					123,

			remoteHeight:					39,

			remoteImage:        	{nodeType:"Resource",url:'Images/toolbar_remote_default.gif'},

			remoteRolloverImage:   	{nodeType:"Resource",url:'Images/toolbar_remote_enlarge.gif'},

			actions:{

				enlargeViewer:"template"

			}

		},

		toolbarGuidedTour:

		{

			ctor:					RemoteButton,

			image:					{nodeType:"Resource",url:'Images/toolbar_guided_tour.gif'},

			rolloverImage:			{nodeType:"Resource",url:'Images/toolbar_guided_tour_over.gif'},

			width:							33,

			height:							39,

			remoteId:						'toolbarRemote',

			remoteWidth:					123,

			remoteHeight:					39,

			remoteImage:        	{nodeType:"Resource",url:'Images/toolbar_remote_default.gif'},

			remoteRolloverImage:   	{nodeType:"Resource",url:'Images/toolbar_remote_guided_tour.gif'},

			actions:{

				guidedTour:"viewer"

			}

		},

			// Template button data.

		overview:

		{

			ctor:					Button,

			image:					{nodeType:"Resource",url:'Images/template_overview.gif'},

			rolloverImage:			{nodeType:"Resource",url:'Images/template_overview_over.gif'},

			width:							66,

			height:							18,

			actions:{

				showGeneral_Text:"template"

			}

		},

		templateGuidedTour:

		{

			ctor:					Button,

			image:					{nodeType:"Resource",url:'Images/template_movie.gif'},

			rolloverImage:			{nodeType:"Resource",url:'Images/template_movie_over.gif'},

			width:							66,

			height:							18,

			actions:{

				guidedTour:"viewer"

			}

		},

		print:

		{

			ctor:					Button,

			image:					{nodeType:"Resource",url:'Images/template_print.gif'},

			rolloverImage:			{nodeType:"Resource",url:'Images/template_print_over.gif'},

			width:							66,

			height:							18,

			actions:{

				showPrintDialog:"template"

			}

		},

		email:

		{

			ctor:					Button,

			image:					{nodeType:"Resource",url:'Images/template_email.gif'},

			rolloverImage:			{nodeType:"Resource",url:'Images/template_email_over.gif'},

			width:							66,

			height:							18,

			actions:{

				showEmail_Frame:"template"

			}

		}

	},



	// The floorplan button entry should be thought of as a pattern for

	// creating as many floorplan buttons as are required at runtime.

	// In other words, don't declare multiple floorplan buttons.

	floorplanButtonData:{

		ctor:					Button,

		//image:					{nodeType:"Resource",url:'Images/icon_plan.gif'},

		//rolloverImage:			{nodeType:"Resource",url:'Images/icon_plan_on.gif'},

		image:					{nodeType:"Resource",url:'Images/e_floorplan.gif'},

		rolloverImage:			{nodeType:"Resource",url:'Images/e_floorplan_on.gif'},

		width:							66,

		height:							18

	},

	thumbnailData:{

		// Like the floorplan buttons, the thumbnail entries should also be

		// thought of as patterns for creating objects. In other words, it is

		// not necessary to define multiple panoramaThumbnail entries because a

		// particular tour contains two or more panoramas. Instead, just one

		// panoramaThumbnail entry should be defined and the software will create

		// as many panoramaThumbnail instances as are required.

		pano:

		{

			ctor:	PanoramaThumbnail,

			icon:			{nodeType:"Resource",url:'Images/icon_pano.gif'},

			iconAni:		{nodeType:"Resource",url:'Images/icon_pano_on.gif'},

			outerWidth:		60,

			outerHeight:	40,

			titleWidth:		60,

			titleHeight:	15

		},

		video:

		{

			ctor:	Thumbnail,

			icon:			{nodeType:"Resource",url:'Images/icon_video.gif'},

			iconAni:		{nodeType:"Resource",url:'Images/icon_video_on.gif'},

			outerWidth:		60,

			outerHeight:	40,

			titleWidth:		60,

			titleHeight:	15

		},

		obj3d:

		{

			ctor:	Thumbnail,

			icon:			{nodeType:"Resource",url:'Images/icon_object3D.gif'},

			iconAni:		{nodeType:"Resource",url:'Images/icon_object3D_on.gif'},

			outerWidth:		60,

			outerHeight:	40,

			titleWidth:		60,

			titleHeight:	15

		},

		still:

		{

			ctor:	Thumbnail,

			icon:			{nodeType:"Resource",url:'Images/icon_2d.gif'},

			iconAni:		{nodeType:"Resource",url:'Images/icon_2d_on.gif'},

			outerWidth:		60,

			outerHeight:	40,

			titleWidth:		60,

			titleHeight:	15

		}

	},

	viewerData:{

		'Java':{

			viewableTypes:{

				'pano':{

					hotspotExtras:{		//Add to a hotspot that points to us

						image:{

							nodeType:"Resource",

							url:"Images/icon_floorplan_panorama.gif"

						}

					}

				},

				'still':{

					hotspotExtras:{		//Add to a hotspot that points to us

						image:{

							nodeType:"Resource",

							url:"Images/icon_floorplan_still.gif"

						}

					}

				},

				'video':{

					hotspotExtras:{		//Add to a hotspot that points to us

						image:{

							nodeType:"Resource",

							url:"Images/icon_floorplan_animated_seq.gif"

						}

					}

				},

				'obj3d':{

					hotspotExtras:{		//Add to a hotspot that points to us

						image:{

							nodeType:"Resource",

							url:"Images/icon_floorplan_3dobject.gif"

						}

					}

				}

			}

		},

		'Flash':{

			viewableTypes:{

				'pano':{

					hotspotExtras:{		//Add to a hotspot that points to us

						image:{

							nodeType:"Resource",

							url:"Images/icon_floorplan_panorama.gif"

						}

					}

				},

				'still':{

					hotspotExtras:{		//Add to a hotspot that points to us

						image:{

							nodeType:"Resource",

							url:"Images/icon_floorplan_still.gif"

						}

					}

				},

				'video':{

					hotspotExtras:{		//Add to a hotspot that points to us

						image:{

							nodeType:"Resource",

							url:"Images/icon_floorplan_animated_seq.gif"

						}

					}

				},

				'obj3d':{

					hotspotExtras:{		//Add to a hotspot that points to us

						image:{

							nodeType:"Resource",

							url:"Images/icon_floorplan_3dobject.gif"

						}

					}

				}

			}

		}

	}

};



/**

 * Constructor.

 */

function Template()

{

}



/**

 * Called by the brochure object to load.

 * This should call registerData somehow if it is overridden.

 */

Template.prototype.init = function(path,brochure)

{

	Utility.locateResources( Template.BASE_DATA, brochure.jsPath, brochure.path );

	Utility.locateResources( Template.DEFAULT_DATA, path, brochure.path );

	this.registerDatas( path, brochure, [Template.DEFAULT_DATA,Template.BASE_DATA] );

}



/**

 * If we use all the main default values for images etc BUT RELATIVE TO THE CUSTOMIZED BROCHURE.

 */

Template.prototype.registerUsingDefaultData = function( path, brochure, data )

{

	Utility.locateResources( Template.BASE_DATA, brochure.jsPath, brochure.path );

	Utility.locateResources( Template.DEFAULT_DATA, path, brochure.path );

	Utility.locateResources( data, path, brochure.path );

	this.registerDatas( path, brochure, [data,Template.DEFAULT_DATA,Template.BASE_DATA] );

}



/**

 * Called by the sub class when it is ready to setup the information on which buttons exist and how to format them.

 * The buttonData object is a map of button id to buttonDatum.

 * buttonDatum contains the information to send to the button constructor.

 * The only thing it needs is for sure is the attribute "constructor" which is a function

 * that will be called to construct the new button object passing the buttonDatum.

 * The buttonDatum has the id set in it for the button's usage.

 * All the constructed buttons are put into the array buttons owned by the template.

 *

 * The floorplan is the template for writing floorplan buttons.

 *

 * The thumbnails are different in that we have templates and not the final thumbnails.

 * For each type of viewable we have a thumbnail type.

 */

Template.prototype.registerData = function( path, brochure, data )

{

	Utility.locateResources( Template.BASE_DATA, brochure.jsPath, brochure.path );

	Utility.locateResources( data, path, brochure.path );

	this.registerDatas( path, brochure, [data,Template.BASE_DATA] );

}



/**

 * Called internally by one of the above 3 methods.

 * Builds one common data object from the given data objects.

 * Sets up the internal data structures.

 */

Template.prototype.registerDatas = function( path, brochure, datas )

{

	this.brochure = brochure;

	this.datas = datas;

	this.path = path;

}



/**

 * This is called from the Brochure.writeInitialContent() method.

 * The point is that all the various scripts needed have now loaded and the configuration object can be built.

 */

Template.prototype.finishInit = function()

{

		//Now we merge the datas objects into one big configuration object that we store under data

	this.data = {};

	Utility.addIntoNodeN( this.data, this.datas, null, null, false, null );

	delete this.datas;



		//Now clear out properties ready to build stuff

	this.callbacks = null;

	this.buttons = new Object();

	this.floorplans = new Object();

	this.thumbnails = new Object();

	this.thumbnailsByOrder = new Object();



		// Create the toolbar and other standard buttons and store them in buttons array

	this.viewerActions = [];

	for (var id in this.data.buttonData)

	{

		var buttonDatum = this.data.buttonData[id];

		if( typeof( buttonDatum.actions ) == "undefined" || buttonDatum.actions == null )

		{

			buttonDatum.actions = {};

		}

		else

		{

			for( var actionID in buttonDatum.actions )

			{

				if( buttonDatum.actions[actionID] == "viewer" )

				{

					this.viewerActions.push(actionID);

				}

			}

		}

		buttonDatum.id = id;

		this.buttons[id] = new buttonDatum.ctor("button",buttonDatum);

	}

}



/**

 * Called when onReady on the brochure has happened because the CSS files are downloaded

 */

Template.prototype.onReady = function()

{

	for (var layerName in this.data.layers)

	{

		var layer	= this.data.layers[layerName];

		if( layer != null )

		{

			var layerTag = document.getElementById(layerName);

			if( layerTag == null )

			{

				this.data.layers[layerName]=null;

			}

			else

			{

				layer.top = parseInt(Utility.getStyle(layerName, 'top', 'top'));

				layer.left = parseInt(Utility.getStyle(layerName, 'left', 'left'));

				layer.right = layer.left + parseInt(Utility.getStyle(layerName, 'width', 'width'));

				layer.bottom = layer.top + parseInt(Utility.getStyle(layerName, 'height', 'height'));

			}

		}

	}

	for( var name in this.data.layers )

	{

		if( this.data.layers[name] != null )

		{

			var layer = Brochure.getLayer( name );

			if( layer != null )

			{

				var propName = name.charAt(0).toUpperCase()+name.substring(1);

				var funcName = "format"+propName;

				if( typeof( this[funcName] ) == "function" &&

				    typeof( this["get"+propName+"Content"] ) != "function" )

				{		//It has a format method and neither of the other two

					this[funcName]( layer, false, null );

				}

			}

		}

	}

	this.endFormat();

}



/**

 * Called to unload the page-specific information

 */

Template.prototype.unloadPage = function()

{

	this.thumbnails = null;

	this.thumbnailsByOrder = null;

	this.floorplans = null;

	this.pageName = null;

	for( var name in this.data.layers )

	{

		var funcName = "unload"+name.charAt(0).toUpperCase()+name.substring(1);

		if( typeof( this[funcName] ) == "function" )

		{

			this[funcName]();

		}

		else

		{

			Brochure.unloadDiv(Brochure.getLayer(name));

		}

	}

}



Template.prototype.nonVisualLoadPage = function( pageName, page )

{

	this.thumbnails = new Object();

	this.thumbnailsByOrder = new Object();

	this.pageName = pageName;



	for (var id in page.viewables)

	{

		var viewable = page.viewables[id];

		var thumbnailDef = this.data.thumbnailData[viewable.type];

		this.thumbnailsByOrder[viewable.order] = this.thumbnails[id] = new thumbnailDef.ctor(thumbnailDef, id, viewable);

	}



	this.floorplans = new Object();

	var floorplans = page.floorplans;

	for( var id in floorplans )

	{

		var floorplan = floorplans[id];

		this.data.floorplanButtonData.id = id;

		this.data.floorplanButtonData.alt = floorplan.alt;

		this.floorplans[id] = new this.data.floorplanButtonData.ctor("floorplan",this.data.floorplanButtonData);

		delete this.data.floorplanButtonData.id;

		delete this.data.floorplanButtonData.alt;

	}

	this.resetButtonStates();

}



Template.prototype.getInitialContent = function(pageName,page)

{

	this.brochure.debug("Starting getInitialContent");

	this.nonVisualLoadPage( pageName, page );

	this.startFormat();

	var str = "";

		//Write out the layers

	str += "<div id=\"brochureLayer\" style=\"display:block\">";

	str += "<div id=\"waitLayer\"></DIV>";

		// Create each of the inner layers and append them to the enclosing layer.

	for (var layerName in this.getLayers())

	{		// Get the existing layer

		str+="<div id=\""+layerName+"\"";

		var propName = layerName.charAt(0).toUpperCase()+layerName.substring(1);

		var funcName = "getInitial"+propName+"Content";

		var ans;

		if( typeof( this[funcName] ) == "function" && (ans = this[funcName]()) != null )

		{

			str+=ans;

		}

		else

		{

			str+=">";

			funcName = "get"+propName+"Content";

			if( typeof( this[funcName] ) == "function" && (ans = this[funcName](false,null)) != null )

			{

				str+=ans;

			}

		}

		str+="</div>";

	}

	str+="</div>";

	return str;

}



/**

 * Called when the page changes to load in the new button etc details into the template

 */

Template.prototype.loadPage = function(pageName,page)

{

	this.nonVisualLoadPage( pageName, page );

	this.startFormat();

	for( var name in this.data.layers )

	{

		if( this.data.layers[name] != null )

		{

			var layer = Brochure.getLayer( name );

			if( layer != null )

			{

				var propName = name.charAt(0).toUpperCase()+name.substring(1);

				var funcName = "get"+propName+"Content";

				if( typeof( this[funcName] ) == "function" )

				{

					var str = this[funcName](false,null);

					if( str != null )

					{

						layer.innerHTML = "";

						layer.innerHTML = str;

					}

				}

				else

				{

					funcName = "format"+propName;

					if( typeof( this[funcName] ) == "function" )

					{

						this[funcName]( layer, false, null );

					}

				}

			}

		}

	}



	this.endFormat();

}



Template.prototype.reRenderLayer = function( name, layer, params )

{

	var propName = name.charAt(0).toUpperCase()+name.substring(1);

	var funcName = "get"+propName+"Content";

	if( typeof( this[funcName] ) == "function" )

	{

		layer.innerHTML = "";

		layer.innerHTML = this[funcName](true,params);

	}

	else

	{

		funcName = "format"+name.charAt(0).toUpperCase()+name.substring(1);

		if( typeof( this[funcName] ) == "function" )

		{

			this.startFormat();

			this[funcName]( layer, true, params );

			this.endFormat();

		}

	}

}



/**

 * This returns the data structure used to customize the viewer.

 */

Template.prototype.getViewerData = function( type )

{

	return this.data.viewerData[type];

}



/**

 * This returns the list of action IDs that are expected to exist on the viewer

 */

Template.prototype.getViewerActions = function()

{

	return this.viewerActions;

}



Template.prototype.getFormattedButton = function(id)

{

	if (this.buttons[id])

	{

		return this.buttons[id].format();

	}

	else

	{

		return null;

	}

}



Template.prototype.getFormattedImage = function(id)

{

	if (this.buttons[id])

	{

		return this.buttons[id].format();

	}

	else

	{

		return null;

	}

}



Template.prototype.getUnformattedImage = function(id)

{

	if (this.buttons[id])

	{

		return this.buttons[id].raw();

	}

	else

	{

		return null;

	}

}



Template.prototype.startFormat = function()

{

	this.brochure.debug("Starting format");

	this.callbacks = new Array();

}



Template.prototype.addAfterFormatCallback = function( obj )

{

	this.callbacks.push( obj );

}



Template.prototype.endFormat = function()

{

	this.brochure.debug("Ending format");

	var callbacks = this.callbacks;

	this.callbacks = null;

	if(callbacks) {

		for( var i = 0; i < callbacks.length; i++ )

		{

			callbacks[i].onFormatFinished();

		}

	}

}



/**

 * Formats and shows the floorplan layer.

 *

 * The sourceButtonId parameter contains the name of the button

 * that generated the click event. The button name will be

 * something like 'floorplan1', 'floorplan2' or 'floorplan3'.

 * The showFloorplan method uses the button name to lookup

 * the floorplan layer to be displayed. Consequently, care should

 * be taken to ensure that the floorplans specified in brochureData.js

 * are identified by the names 'floorplan1', 'floorplan2', etc.

 */

Template.prototype.showFloorplan = function(id)

{		//TODO When we have a shortcut type bar to choose the floorplan from, do it there too.

	this.brochure.setFloorplan(id);

	if( this.getLayers()['Floorplan'] != null )

	{

		this.brochure.reRenderLayer( 'Floorplan', this.brochure.getCurrentPage().currentViewableName );

		this.brochure.showLayer('Floorplan');

		if(this.floorplanDirection != null) {this.floorplanDirection.clear();this.floorplanDirection=null;}

		this.floorplanDirection = new jsGraphics("FloorplanDirection");

	}

}



Template.prototype.resetButtonStates = function()

{

	var viewer = this.brochure.viewer;

	for( var i in this.buttons )

	{

		var bid;

		switch( i )

		{

		case 'toolbarGuidedTour':		//TODO hacky

		case 'templateGuidedTour':

			bid = 'guidedTour';

			break;

		default:

			bid = i;

		}

		var state = viewer.getButtonState( bid );

		if( state != null )

		{

			this.buttons[i].setEnabled( state );

		}

	}

}



/**

 * The get...IconURL() methods return useful default values.

 * The main difference between the old brochure architecture

 * and the new brochure architecture in this context, is that

 * the new architecture enables the defaults to be overridden

 * in descendant classes.

 */

Template.prototype.getFloorplanIconURL = function(type)

{

	if( this.data.iconData[type] )

	{

		return this.data.iconData[type];

	}

	return null;

}



Template.prototype.getButton = function(type,id)

{

	switch( type )

	{

	case 'button':

		return this.buttons[id];

	case 'floorplan':

		return this.floorplans[id];

	case 'thumbnail':

		return this.thumbnails[id];

	}

	alert("unknown button type "+type);

}



Template.prototype.notifyYawChanged = function( yaw )

{

	if(this.floorplanDirection != null) {

		if(this.floorplanDirection != 'undefined') {

			var page = this.brochure.getCurrentPage()

			//var currentViewable = page.currentViewableName;

			var currentViewable = page.viewables[page.currentViewableName];

			var newYaw=yaw;

			if(currentViewable.north) {

				if(currentViewable.north.yaw) {

					newYaw = newYaw + eval(currentViewable.north.yaw);

				}

			}

			if (newYaw>360) newYaw = newYaw - 360;

			myDrawFunction(0,0,newYaw,40,this.floorplanDirection);

		}

	}

}



Template.prototype.notifyViewableChanged = function( id )

{

	this.brochure.getCurrentPage().currentViewableName = id;

	this.updateLayersDueToViewableChanged( id );

	this.resetButtonStates();

}



Template.prototype.updateLayersDueToViewableChanged = function(id)

{

	if( this.getLayers().Detailed_Image_Text )

	{

		this.brochure.reRenderLayer('Detailed_Image_Text',id);

	}

	if( this.getLayers().Thumbnails_Frame )

	{

		var params = new Array();

		params[0] = Brochure.getLayer( "Thumbnails_Frame" ).clientWidth;

		params[1] = id;

		this.brochure.reRenderLayer("Thumbnails_Frame",params);

	}

	if( this.getLayers().Floorplan )

	{

		this.brochure.reRenderLayer('Floorplan', id);

		if(this.floorplanDirection != null) {this.floorplanDirection.clear();this.floorplanDirection=null;}

		this.floorplanDirection = new jsGraphics("FloorplanDirection");

	}

	if( this.getLayers().Drop_Down_Menu )

	{

		this.brochure.reRenderLayer('Drop_Down_Menu', id);

	}

}



/**

 * Listens for buttons in the brochure and re-routes them to actions

 */

Template.prototype.buttonClicked = function( id )

{		//The definition of listeners comes from the data structure

	this.brochure.debug("Template.buttonClicked( "+id+" ) enter" );

	var acts = this.data.buttonData[id].actions;

	for( var i in acts )

	{

		this.brochure.debug("Template.buttonClicked( "+id+" ) action "+i+" "+acts[i] );

		var act = acts[i];

		switch( typeof( act ) )

		{

		case "string":

			switch( acts[i] )

			{

			case "viewer":

				this.brochure.debug("Template.buttonClicked( "+id+" ) calling viewer.doAction" );

				this.brochure.viewer.doAction( i );

				this.brochure.debug("Template.buttonClicked( "+id+" ) called viewer.doAction" );

				break;

			case "template":

				if( typeof( this[i] ) == "function" )

				{

					this.brochure.debug("Template.buttonClicked( "+id+" ) calling function on self "+i+"()" );

					this[i]();

					this.brochure.debug("Template.buttonClicked( "+id+" ) called function on self "+i+"()" );

				}

				break;

			}

			break;

		case "function":

			act(i);

		}

	}

	this.brochure.debug("Template.buttonClicked( "+id+" ) exit" );

}



Template.prototype.getLayers = function()

{

	return this.data.layers;

}





////////////////FORMAT LAYER FUNCTIONS



/**

 * Formats and returns a string containing the HTML necessary to render the

 * client branding layer.

 *

 * @return A string containing HTML.

 */

Template.prototype.getClient_BrandingContent = function(flag,params)

{

	var a = this.brochure.client;

	var leftColumn = '';



	if (a.logoURL)

	{

		if( a.webAddress )

		{

			leftColumn = '<a href="' + a.webAddress + '" target="_new"><img src="' + a.logoURL + '" border="0" alt="' + a.webAddress + '"></a>';

		}

		else

		{

			leftColumn = '<img src="' + a.logoURL + '">';

		}

	}

	else

		leftColumn = '&nbsp;';



	var rightColumn = '';

	if (a.title)

		rightColumn += a.title;

	if (a.webAddress)

		rightColumn += '<br>Web: <a href="' + a.webAddress + '" target="_new">' + a.webAddress + '</a>';

	if (a.address)

		rightColumn += '<br>' + a.address;

	if (a.phone)

		rightColumn += '<br>Phone: ' + a.phone;

	if (a.emailAddress)

		rightColumn += '<br>Email: <a href="#" onclick="theBrochure.buttonClicked(\'button\',\'email\')">' + a.emailAddress + '</a>';

	if (this.brochure.getCurrentPage().clientname)

		rightColumn += '<br>Name: ' + this.brochure.getCurrentPage().clientname;

	if (this.brochure.getCurrentPage().clientphone)

		rightColumn += '<br>Contact: ' + this.brochure.getCurrentPage().clientphone;



	return '<table cellspacing="0" cellpadding="0">'

		+ '<tr>'

		+ '<td class="clientBrandingImage">' + leftColumn + '</td>'

		+ '<td class="Client_Branding">' + rightColumn + '</td>'

		+ '</tr>'

		+ '</table>';

}



/**

 * Formats and returns a string containing the HTML necessary to render the

 * portal branding layer.

 *

 * @return A string containing HTML.

 */

Template.prototype.getPortal_BrandingContent = function(flag,params)

{

	var p = this.brochure.portal;

	var leftColumn = '';



	if (p.logoURL)

	{

		if( p.webAddress )

		{

			leftColumn = '<a href="' + p.webAddress + '" target="_new"><img src="' + p.logoURL + '" border="0" alt="' + p.webAddress + '"></a>';

		}

		else

		{

			leftColumn = '<img src="' + p.logoURL + '">';

		}

	}

	else

	{

		leftColumn = '&nbsp;';

	}



	var rightColumn = '';

	if (p.title)

		rightColumn += p.title;

	if (p.webAddress)

		rightColumn += '<br><a href="' + p.webAddress + '" target="_new">' + p.webAddress + '</a>';

	if (p.phone)

		rightColumn += '<br>' + p.phone;

	if (p.emailAddress)

		rightColumn += '<br>Email: <a href="mailto:' + p.emailAddress + '">' + p.emailAddress + '</a>';



	return '<table cellspacing="0" cellpadding="0">'

		+ '<tr>'

		+ '<td class="portalBrandingImage">' + leftColumn + '</td>'

		+ '<td class="Portal_Branding">' + rightColumn + '</td>'

		+ '</tr>'

		+ '</table>';

}



/**

 * Formats and returns a string containing the HTML necessary to render the

 * page links layer.

 *

 * @return A string containing HTML.

 */

Template.prototype.getAction_ButtonsContent = function(flag,params)

{

	//Page Links

	var pageNames = this.brochure.getPageNames();

	var unorderedListHTML = '&nbsp;';



	if (pageNames.length)

	{

		var listItemsHTML = '';



		for (var i = 0; i < pageNames.length; i++)

		{

			var page = this.brochure.getPage(pageNames[i]);

			var pageTitle = '';



			if (page.title)

				pageTitle = page.title;

			else

				pageTitle = 'Page ' + (i + 1);



			listItemsHTML += '<div style="float:left;" class="Action_Buttons">';

			listItemsHTML += '<table cellpadding="0" cellspacing="0"><tr style="background-image:url(' + this.getUnformattedImage('genericButtonMid') +')">';

			listItemsHTML += '<td nowrap>' + this.getFormattedButton('genericButtonLeft') + '</td>'; //get left side of button

			listItemsHTML += '<td nowrap><a href="#"  class="Action_Buttons" onClick="theBrochure.changePage(\'' + pageNames[i] + '\');return false;">' + pageTitle + '</a></td>'; //get middle of button

			listItemsHTML += '<td nowrap>' + this.getFormattedButton('genericButtonRight') + '</td>'; //get end of button

			listItemsHTML += '</tr></table>';

			listItemsHTML += '</div>';

		}

		unorderedListHTML = listItemsHTML;

	}



	return unorderedListHTML;

}



/**

 * Formats and returns a string containing the HTML necessary to render the

 * Template buttons layer. The template buttons include an overview button,

 * zero or more floorplan buttons and zero or one guided tour buttons.

 *

 * @return A string containing HTML.

 */

Template.prototype.getTemplateButtonsLayerContent = function(flag,params)

{

	// TODO

	// The floorplan buttons need to be in their own layer because

	// some brochure will contain a very large number of floorplans

	// and the navigation between the floorplan will need to be via

	// the floorplans themselves and not via buttons. Putting the

	// floorplan buttons in their own layer will enable all of the

	// floorplan buttons to be made invisible in cases where the

	// number of floorplans is great and button control is not desired.



	// Format the overview button.

	var text = '<table cellpadding="0" cellspacing="0">'

		+ '<tr><td>' + this.getFormattedButton('overview') + '</td></tr>\n';



	// Append the floorplans buttons HTML to the result.

	text += this.formatFloorplanButtons('<tr><td>','</td></tr>');



	// Append the guided tour button to the result.

	var guidedTourText = this.getFormattedButton('templateGuidedTour');



	if (guidedTourText)

		text += '<tr><td>' + guidedTourText + '</td></tr>\n';



	text += '</table>\n';

	//return text;

	return ''; /// ABOVE CODE COMMENTED OUT BY DS 20060403 JP TO COMMENT ON BUG #930



}



/**

 * Formats and returns a string containing the HTML necessary to render the

 * system buttons layer. The system buttons include the print and email

 * buttons.

 *

 * @return A string containing HTML.

 */

//Template.prototype.getFunctions_ButtonsContent = function(flag,params)

Template.prototype.formatFunctions_Buttons = function(divTag,flag,params)

{

	var str = '';

	// Format the overview button.

 	var layerName = "General_Text";

 	var layer = Brochure.getLayer(layerName);

 	if( layer != null )

 	{

	 	var overlappingLayerNames = this.brochure.getOverlappingLayerNames(layerName);

		if (overlappingLayerNames.length > 0) str += this.getFormattedButton('overview');

 	}



 	layerName = "Thumbnails_Frame";

 	layer = Brochure.getLayer(layerName);

 	if( layer != null )

 	{

	 	var overlappingLayerNames = this.brochure.getOverlappingLayerNames(layerName);

		if (overlappingLayerNames.length > 0) str += this.getFormattedButton('thumbnails');

 	}



	// Append the floorplans buttons HTML to the result.

 	layerName = "Floorplan";

 	layer = Brochure.getLayer(layerName);

 	if( layer != null )

 	{

	 	var overlappingLayerNames = this.brochure.getOverlappingLayerNames(layerName);

		if (overlappingLayerNames.length > 0) str += this.formatFloorplanButtons('','');

 	}



	// Append the guided tour button to the result.

	var guidedTourText = this.getFormattedButton('templateGuidedTour');

	var page = this.brochure.getCurrentPage();

	if(page.guidedTour.num > 0)

		if (guidedTourText)

				str += guidedTourText;



	str+=this.getFormattedButton('print');



 	layerName = "Email_Frame";

 	layer = Brochure.getLayer(layerName);

 	if( layer != null )

 	{

	 	var overlappingLayerNames = this.brochure.getOverlappingLayerNames(layerName);

		if (overlappingLayerNames.length > 0) str+=this.getFormattedButton('email');

 	}

	//return str;

	divTag.innerHTML="<p class='Functions_Buttons'>"+ str + "</p>";;



	//Deprecated 20060310

	//return '<table cellpadding="0" cellspacing="0">'

	//	+ '<tr><td>' + this.getFormattedButton('print') + '</td></tr>\n'

	//	+ '<tr><td>' + this.getFormattedButton('email') + '</td></tr>\n'

	//	+ '</table>\n';

}



/**

 * Formats and returns a string containing the HTML necessary to render the

 * heading layer.

 *

 * @return A string containing HTML.

 */

Template.prototype.getMain_Heading_TextContent = function(flag,params)

{

	return '<p class=\"Main_Heading_Text\">' + this.brochure.getCurrentPage().heading1 + '</p>';

}



/**

 * Formats and returns a string containing the HTML necessary to render the

 * subheading layer.

 *

 * @return A string containing HTML.

 */

Template.prototype.getSub_Heading_TextContent = function(flag,params)

{

	var page = this.brochure.getCurrentPage();

	return '<p class=\"Sub_Heading_Text\">' + page.heading2 + '</p>'

		+ '<p class=\"Sub_Heading_Text\">' + page.heading3 + '</p>';

}



/**

 * Formats and returns a string containing the HTML necessary to render the

 * general text layer.

 *

 * @return A string containing HTML.

 */

Template.prototype.getGeneral_TextContent = function(flag,params)

{

    var tempStr = this.brochure.getCurrentPage().description;

    tempStr = tempStr.replace(/\r/gi,'</p><p class="General_Text">');

	return '<p class="General_Text">' + tempStr + '</p>';

}



/**

 * This is called back by the formatting system to re-do the thumbnails if needed

 */

Template.prototype.modifyThumbnails = function( prevWidth )

{

	var innerWidth = Brochure.getLayer( "Thumbnails_Frame" ).clientWidth;

	if( innerWidth )

	{

		innerWidth=""+innerWidth;

		if( innerWidth.substring( innerWidth.length-2 ) == "px" )

		{

			innerWidth = innerWidth.substring( 0, innerWidth.length-2 );

		}

		innerWidth *= 1;

	}

	if( innerWidth < prevWidth )

	{

		this.brochure.debug( "Re rendering the thumbnails because innerWidth="+innerWidth+" prevWidth="+prevWidth);

		var params = new Array();

		params[0]=innerWidth;

		this.brochure.reRenderLayer("Thumbnails_Frame",innerWidth);

	}

}



/**

 * Formats the div tag to render the thumbnails layer.

 * Special care should be taken in this method to ensure

 * that the thumbnail rendering degrades gracefully in old browsers and the

 * Netscape browser. This was an issue in the old brochures, so care should

 * be taken not to repeat past mistakes.

 */

Template.prototype.formatThumbnails_Frame = function(divTag,flag,params)

{

	var currentViewableName = null;

	if(params!=null){ if(params[1]) currentViewableName = params[1];}

	var text = '';

	var innerWidth = -1;

	var width = Utility.getStyleFromTag(divTag, 'width', 'width');

	if( width.substring( width.length-2 ) == "px" )

	{

		width = width.substring( 0, width.length-2 );

	}

	width *= 1;

	if( !flag )

	{		//First time through - set a callback for when we know if we have a scrollbar

			//We use the full width less 16 for now

		innerWidth = width-16;

		this.addAfterFormatCallback( {onFormatFinished:function(){

			setTimeout("theBrochure.getTemplate().modifyThumbnails("+innerWidth+")");

		}} );

	}

	else

	{		//Callback - use the clientWidth property for the width to scale to

		innerWidth = params[0];

	}



		//A table to contain one cell for each line

	text += '<table width="'+innerWidth+'" cellspacing="0" cellpadding="0" border=0 align="left">';

	var span = 0;

		//A table for each line to contain one cell for each thumbnail

	text += '<tr align="left"><td align="left"><table cellspacing="0" cellpadding="5" border=0 align="left"><tr align="left">';

	var first = true;

	// a little fix to cope with orders not being in linear sequence, eg. 3,4,1 (no occurance of 2 at all is legal)

	var idMax = 0;

	for(var it in this.thumbnailsByOrder) {

		if(parseInt(it)>idMax) idMax=parseInt(it);

	}

	for(var id=0; id <= idMax; id++)

	{

		if(th = this.thumbnailsByOrder[id]) {

			span+=10+th.outerWidth;

			if( first )

			{

				first = false;

			}

			else if( span > innerWidth )

			{		//Go to next line before writing the next

				text+='</tr></table></td></tr>';

				text += '<tr align="left"><td align="left"><table cellspacing="0" cellpadding="5" border=0 align="left"><tr align="left">';

				span = 10+th.outerWidth;

			}

			if(currentViewableName == th.id) { // highlight currentViewable

				text += '<td valign=top align=left class=Thumbnails_Frame>'+th.format(true)+'</td>\n';

			}

			else {

				text += '<td valign=top align=left class=Thumbnails_Frame>'+th.format(false)+'</td>\n';

			}

		}

	}

	text+='</tr></table></td></tr></table>';

	if( flag )

	{		//When redoing, clear the div first

		Brochure.unloadDiv(divTag);

	}

	//divTag.style.overflow = "auto";

	text = "<DIV style=\"overflow:hidden;width:"+innerWidth+"px\">"+text+"</DIV>";

	divTag.innerHTML=text;

}



/**

 * Formats and returns a string containing the HTML necessary to render the

 * detailed image description layer.

 *

 * @return A string containing HTML.  Note that params is the id of the viewable

 */

Template.prototype.getDetailed_Image_TextContent = function(divTag,flag,params)

{

	if( params == null )

	{

		params = this.brochure.viewer.getCurrentViewable(false);

	}

	if( params == null )

	{

		return;

	}

	var tempStr = this.brochure.getCurrentPage().viewables[params].description;

    tempStr = tempStr.replace(/\r/gi,'</p><p class="Detailed_Image_Text">');

	return '<p class="Detailed_Image_Text">' + tempStr + '</p>';

}



/**

 * Formats and returns a string containing the HTML necessary to render the

 * floorplan layer.

 *

 * @return A string containing HTML.

 */

//Template.prototype.getFloorplanContent = function(flag,params)

Template.prototype.formatFloorplan = function(divTag,flag,params)

{

	var page = this.brochure.getCurrentPage();

	var floorplan = this.brochure.getCurrentFloorplan();

	if( floorplan != null )

	{

		var foundPanoHotspot=false;

		var directionCenterX=0;

		var directionCenterY=0;

		var text = '<div style="border:1px;position:absolute;'

			+ 'left:0px;'

			+ 'top:0px;'

			+ 'width:' + 100 + '%;'

			+ 'height:' + 100 + '%;">'

			+ '<div style="position: absolute;"><img src="' + floorplan.image + '"></div>';

		//alert('hello');

		for (var hotspot in floorplan.HotspotsArray)

		{

			var pointsArray;

			if(hotspot != "listType") {

				var targetName = floorplan.HotspotsArray[hotspot].targetName;

				var page = this.brochure.getCurrentPage();

				var type = null;

				if( typeof( page.viewables[targetName] ) != "undefined" )

				{

					type = page.viewables[targetName].type;

				}

				else if( typeof( page.floorplans[targetName] ) != "undefined" )

				{

					type = 'floorplan';

				}

				var points = floorplan.HotspotsArray[hotspot].points;

				pointsArray =  points.split(',');



				var iconURL	= this.getFloorplanIconURL(type);

				if (iconURL)

				{

					text+=

						'<div style="position:absolute;'

						+ 'left:' + pointsArray[0] + 'px;'

						+ 'top:' + pointsArray[1] + 'px;';

						//+ 'width:' + pointsArray[2] + 'px;'

						//+ 'height:' + pointsArray[3] + 'px;">'

						text+= 'width:' + 60 + 'px;'

						+ 'height:' + 60 + 'px;">'

						+ '<img src="' + iconURL + '" '

						+ 'alt="' + page.viewables[targetName].short_desc + '" '

						+ 'onMouseOver="javascript:window.status=\''+ page.viewables[targetName].short_desc +'\'" '

						+ 'onClick="theBrochure.floorPlanActionCallback(\'' + hotspot + '\')" '

						+ 'style="cursor:hand;';

						if (targetName==params) {

							text+= 'border:1px solid #FF0000;';

						}

						text+='" '

						+ '>' //+ '<font class="Floorplan">'+ page.viewables[targetName].short_desc + '</font>'

						+ '</div>\n';

				}

				// get points to center floorplanDirection feature

				if(targetName==params) {

					directionCenterX = eval(pointsArray[0]) +9; // add 9 to compensate for hotspot icons sizes

					directionCenterY = eval(pointsArray[1]) +9; // add 9 to compensate for hotspot icons sizes

					foundPanoHotspot=true;

				}

			}

		}

		if(foundPanoHotspot) {

			text += '<div id="FloorplanDirection" style="left:' + directionCenterX + 'px;top:' + directionCenterY + 'px;WIDTH:100%;POSITION:absolute;HEIGHT:100%"></div>';

		}

		text += '</div>';

		divTag.innerHTML = text;

	}

	return "";

}



/**

 * Checks to see if floorplan layer is ontop (NOT USED CURRENTLY)

 */

Template.prototype.showFloorplanCheck = function(id)

{

	var onTop = this.brochure.isLayerOnTop("Floorplan");

	alert('hello');

	if( onTop )

	{

		this.brochure.debug( "Re rendering the floorplan layer");

		this.showFloorplan(this.brochure.getCurrentPage().currentViewableName);

	}

}



/**

 * Returns the HTML necessary to format the floorplans surrounding each floorplan with HTML in prefix and suffix.

 * TODO ensure order is good.

 */

Template.prototype.formatFloorplanButtons = function(prefix,suffix)

{

	var text = "";

	for (var id in this.floorplans)

	{

		text += prefix+this.floorplans[id].format()+suffix;

	}

	return text;

}



/**

 * Formats and returns a string containing the HTML necessary to render the

 * help layer.

 *

 * @return A string containing HTML.

 */

Template.prototype.getHelp_FrameContent = function(flag,params)

{		//TODO

	//return "HELP HERE";





/*

		+ '<td'+toolBarBack+'>' + this.getFormattedImage('leftEnd') + '</td>\n'

		+ '<td'+toolBarBack+'>' + this.formatRemoteToolbarImage() + '</td>\n'

		+ '<td'+toolBarBack+'>' + this.getFormattedButton('mute') + '</td>\n'

		+ '<td'+toolBarBack+'>' + this.getFormattedButton('zoomOut') + '</td>\n'

		+ '<td'+toolBarBack+'>' + this.getFormattedButton('zoomIn') + '</td>\n'

		+ '<td'+toolBarBack+'>' + this.getFormattedButton('help') + '</td>\n'

		+ '<td'+toolBarBack+'>' + this.getFormattedButton('left') + '</td>\n'

		+ '<td'+toolBarBack+'>' + this.getFormattedButton('stop') + '</td>\n'

		+ '<td'+toolBarBack+'>' + this.getFormattedButton('right') + '</td>\n'

		+ '<td'+toolBarBack+'>' + this.getFormattedButton('enlarge') + '</td>\n'

		+ '<td'+toolBarBack+'>' + this.getFormattedButton('toolbarGuidedTour') + '</td>\n'

		+ '<td'+toolBarBack+'>' + this.getFormattedImage('rightEnd') + '</td>\n'



		*/

return	"<table border=\"0\" cellpadding=\"5\" cellspacing=\"0\">"

  + "	  <tr>"

  + "	    <td colspan=\"2\" class=Help_Frame><strong>Viewer Help</strong></td>"

  + "	  </tr>"

  + "	  <tr>"

  + "	    <td valign=\"top\" class=Help_Frame>"+this.getFormattedButton('zoomIn')+"</td>"

  + "	    <td class=Help_Frame>This button zooms in or tightens the viewing angle of a panorama so as to be able to see aspects of a scene from a closer perspective.</td>"

  + "	  </tr>"

  + "	  <tr>"

  + "	    <td valign=\"top\" class=Help_Frame>"+ this.getFormattedButton('help') +"</td>"

  + "	    <td class=Help_Frame>This button calls the help information you are now reading.</td>"

  + "	  </tr>"

  + "	  <tr>"

  + "	    <td valign=\"top\" class=Help_Frame>"+ this.getFormattedButton('left') +"</td>"

  + "	    <td class=Help_Frame>This button pans the panorama to the left.</td>"

  + "	  </tr>"

  + "	  <tr>"

  + "	    <td valign=\"top\" class=Help_Frame>" + this.getFormattedButton('stop') + "</td>"

  + "	    <td class=Help_Frame>This button pauses any movement within the viewer screen.</td>"

  + "	  </tr>"

  + "	  <tr>"

  + "	    <td valign=\"top\" class=Help_Frame>" + this.getFormattedButton('right') + "</td>"

  + "	    <td class=Help_Frame>This button pans the panorama to the right.</td>"

  + "	  </tr>"

  + "	  <tr>"

  + "	    <td valign=\"top\" class=Help_Frame>" + this.getFormattedButton('mute') + "</td>"

  + "	    <td class=Help_Frame>This button turns sound ON or OFF.</td>"

  + "	  </tr>"

  + "	  <tr>"

  + "	    <td valign=\"top\" class=Help_Frame>" + this.getFormattedButton('toolbarGuidedTour') + "</td>"

  + "	    <td class=Help_Frame>This button begins the guided tour sequence which displays all aspects of the tour in turn.</td>"

  + "	  </tr>"

  + "	  <tr>"

  + "	    <td valign=\"top\" class=Help_Frame>NOTE:</td>"

  + "	  </tr>"

  + "	  <tr>"

  + "	    <td colspan=\"2\" class=Help_Frame>Some of these features are unavailable when viewing a still image.</td>"

  + "	  </tr>"

  + "</table>";

}



/**

 * Formats and returns a string containing the HTML necessary to render the

 * email layer.

 *

 * @return A string containing HTML.

 */



Template.prototype.getEmail_FrameContent = function(flag,params)

{

	var page = this.brochure.getCurrentPage();



	return '<form name="dataForm">'

		+ '<table border="0" cellpadding="1" cellspacing="0">'

		+ '<tr><td class=Email_Frame><strong>Tell a friend or ask the client about this tour</strong></tr>'

		+ '<tr><td class=Email_Frame>To (email)</td></tr>'

		+ '<tr><td class=Email_Frame><input type="text" name="toEmailAddress" size="20" value="' + this.brochure.client.emailAddress + '"></td></tr>'

		+ '<tr><td class=Email_Frame>From (email)</td></tr>'

		+ '<tr><td class=Email_Frame><input type="text" name="fromEmailAddress" size="20"></td></tr>'

		+ '<tr><td class=Email_Frame>Your Name</td></tr>'

		+ '<tr><td class=Email_Frame><input type="text" name="sender" size="20"></td></tr>'

		+ '<tr><td class=Email_Frame>Subject</td></tr>'

		+ '<tr><td class=Email_Frame><input type="text" name="subject" size="20" value="' + page.title + '"></td></tr>'

		+ '<tr><td class=Email_Frame>Message</td></tr>'

		+ '<tr><td>'

		+ '<textarea cols="20" rows="6" name="message">'

		+ page.heading1 + '\n'

		+ page.heading2 + '\n'

		+ page.heading3 + '\n'

		+ '</textarea>'

		+ '</td></tr>'

		+ '</form>'

		+ '<tr><td class=Email_Frame>'

		+ '<form name="mailForm" action="mailto:" method="post" enctype="text/plain" onSubmit="Template.sendMail();">'

		+ '<input type="hidden" name="message" value="">'

		+ '<input type="submit" value="Send">'

		+ '</td></tr>'

		+ '</form>'

		+ '</table>';

}





/**

 * This is called to set up the initial viewer layer content by returning the mark-up as a string.

 * This method is deleted by itself after first usage so that the formatViewer is used subsequently.

 */



Template.prototype.getInitialViewerLayerContent = function(flag,params)

{

	return ">"+this.brochure.getViewer().getViewerLayerContent();

}



/**

 * Formats the viewer layer to take into consideration the new situation.

 */

Template.prototype.formatViewerLayer = function(divTag,flag,params)

{

	this.brochure.getViewer().formatViewerLayer( divTag, flag, params );

}



Template.prototype.unloadViewerLayer = function()

{

	this.brochure.getViewer().unloadViewerDiv();

}



/**

 * Formats and returns a string containing the HTML necessary to render the

 * viewer toolbar layer.

 *

 * @return A string containing HTML.

 */

Template.prototype.getView_Controls_FrameContent = function(flag,params)

{

	var toolBarBack = ' style="background-image:url(' + this.getUnformattedImage('toolBarBackground') + ');" ';

	var str = '';

	str+= '<table width="100%" cellpadding="0" cellspacing="0"><tr>\n';

	str+=  '<td'+toolBarBack+'>' + this.getFormattedImage('leftEnd') + '</td>\n';

	str+=  '<td'+toolBarBack+'>' + this.formatRemoteToolbarImage() + '</td>\n';

	str+=  '<td'+toolBarBack+'>' + this.getFormattedButton('mute') + '</td>\n';

	str+=  '<td'+toolBarBack+'>' + this.getFormattedButton('zoomOut') + '</td>\n';

	str+=  '<td'+toolBarBack+'>' + this.getFormattedButton('zoomIn') + '</td>\n';

	str+=  '<td'+toolBarBack+'>' + this.getFormattedButton('help') + '</td>\n';

	str+=  '<td'+toolBarBack+'>' + this.getFormattedButton('left') + '</td>\n';

	str+=  '<td'+toolBarBack+'>' + this.getFormattedButton('stop') + '</td>\n';

	str+=  '<td'+toolBarBack+'>' + this.getFormattedButton('right') + '</td>\n';

	//str+=  '<td'+toolBarBack+'>' + this.getFormattedButton('enlarge') + '</td>\n';

	var page = this.brochure.getCurrentPage();

	if(page.guidedTour.num > 0)

		str+=  '<td'+toolBarBack+'>' + this.getFormattedButton('toolbarGuidedTour') + '</td>\n';

	str+=  '<td'+toolBarBack+' align=right>' + this.getFormattedImage('rightEnd') + '</td>\n';

	str+=  '</tr></table>\n';

	return str;

}



/**

 * The toolbar has an extra image which changes depending on what button you are hovering over.

 * Format that button here

 */

Template.prototype.formatRemoteToolbarImage = function()

{

	return this.data.remoteToolbar.format(this.data.remoteToolbar);

}



/**

 * Private class method used by formatEmail_Frame() to send an email message.

 */

Template.sendMail = function()

{

    document.mailForm.action =

    	'mailto:' + dataForm.toEmailAddress.value + '?subject=' + dataForm.subject.value;



    document.mailForm.message.value =

    	'Page Title: ' + document.title + '\r\n'

    	+ 'Mailed From: ' + document.location + '\r\n'

    	+ 'Sender Name: ' + dataForm.sender.value + '\r\n\r\n'

    	+ document.dataForm.message.value;



    return true;

}





////////////showXYZLayer functions



/**

 * Shows the help layer.

 */

Template.prototype.showHelp_Frame = function()

{

	this.brochure.showLayer('Help_Frame');

}



/**

 * Shows the thumbnails frame.

 */

Template.prototype.showThumbnails_Frame = function()

{

	this.brochure.showLayer('Thumbnails_Frame');

}



/**

 * Shows the email layer.

 */

Template.prototype.showEmail_Frame = function()

{

	this.brochure.showLayer('Email_Frame');

}



/**

 * Shows the generalText layer.

 */

Template.prototype.showGeneral_Text = function()

{

	this.brochure.showLayer('General_Text');

}



/**

 * Shows the print dialog layer.

 */

Template.prototype.showPrintDialog = function()

{

	var da = (document.all) ? 1 : 0;

	var pr = (window.print) ? 1 : 0;

	var mac = (navigator.userAgent.indexOf("Mac") != -1);



	if (pr) { // NS4, IE5

	    window.print();

	} else if (da && !mac) { // IE4 (Windows)

	    vbPrintPage();

	} else { // other browsers

	    alert("Sorry, your browser doesn't support this feature.");

	}



	if (da && !pr && !mac) with (document) {

	  writeln('<OBJECT ID="WB" WIDTH="0" HEIGHT="0" CLASSID="clsid:8856F961-340A-11D0-A96B-00C04FD705A2"></OBJECT>');

	  writeln('<' + 'SCRIPT LANGUAGE="VBScript">');

	  writeln('Sub window_onunload');

	  writeln('  On Error Resume Next');

	  writeln('  Set WB = nothing');

	  writeln('End Sub');

	  writeln('Sub vbPrintPage');

	  writeln('  OLECMDID_PRINT = 6');

	  writeln('  OLECMDEXECOPT_DONTPROMPTUSER = 2');

	  writeln('  OLECMDEXECOPT_PROMPTUSER = 1');

	  writeln('  On Error Resume Next');

	  writeln('  WB.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER');

	  writeln('End Sub');

	  writeln('<' + '/SCRIPT>');

	}

}



Template.prototype.enlargeViewer = function()

{		//TODO

	alert("Enlarge Viewer");

}

Template.prototype.formatDebugLayer = function( debugLayer, flag, params )

{

	if( flag )

	{

		Brochure.unloadDiv(divTag);

	}

	debugLayer.style.top="600px";

	var text = "";

	if( this.brochure.debugText )

	{

		text = this.brochure.debugText;

	}

	debugLayer.innerHTML='<TEXTAREA id="debugTA" cols="80" rows="20">'+text+'</TEXTAREA>';

}



Template.prototype.getViewer_FrameContent = function(flag,params)

{

	return "";

}



Template.prototype.getExternal_LinksContent = function(flag,params)

{

	return "";

}



Template.prototype.getDrop_Down_MenuContent = function(flag,params)

{

	var page = this.brochure.getCurrentPage();

	var currentViewable = null;

	if (params) currentViewable=params;

	var text = '';

	//A table for each line to contain one cell for each thumbnail

	text += '<select name="mydropdown" onChange="theBrochure.buttonClicked(\'thumbnail\',this.value)">';

	var optionText = "";

	// a little fix to cope with orders not being in linear sequence, eg. 3,4,1 (no occurance of 2 at all is legal)

	var idMax = 0;

	for(var it in this.thumbnailsByOrder) {

		if(it>idMax) idMax=it;

	}

	for(var id=0; id <= idMax; id++)

	{

		if(th = this.thumbnailsByOrder[id]) {

			optionText = page.viewables[th.id].short_desc;

			if(optionText == "") optionText=th.id;

			text += '<option ';

			if(currentViewable == th.id) text += 'selected="true" ';

			text += 'value="'+th.id+'">'+optionText+'</option>\n';

		}

	}

	text+='</select>';

	return text;

}



Template.prototype.getUser_Defined_Frame_1Content = function(flag,params)

{

// User defined arbitary html code

//	var htmlCode = '';

//	htmlCode += '<img src="test.jpg">';

//	return htmlCode;

//	

	return "";

}



Template.prototype.getUser_Defined_Frame_2Content = function(flag,params)

{

	return "";

}



Template.prototype.getUser_Defined_Frame_3Content = function(flag,params)

{

	return "";

}



Template.prototype.getUser_Defined_Frame_4Content = function(flag,params)

{

	return "";

}



Template.prototype.getUser_Defined_Frame_5Content = function(flag,params)

{

	return "";

}



Template.prototype.getUser_Defined_Frame_6Content = function(flag,params)

{

	return "";

}



Template.prototype.getUser_Defined_Frame_7Content = function(flag,params)

{

	return "";

}



Template.prototype.getUser_Defined_Frame_8Content = function(flag,params)

{

	return "";

}
