<!--
	Viewport = function() {
		this.fn;    // image filename
		this.tx;    // total pixel-width of full image
		this.ty;
		this.imgs;  // image chunk size
		this.px;    // number of pieces wide
		this.py;
		
		this.vpn;   // viewport name (id)
		this.vpx;   // viewport width
		this.vpy;
		this.vpinner;// inner div object, container for the images
		
		var events = new Events(); // events Object

		this.imgpath = 'http://images.theoldcountrystore.com/'; // path to various images (zoom in, etc.)
		this.imgchunkpath = 'http://images.theoldcountrystore.com/quilts/'; // path to the image chunks
		
		this.clickx;// stores where the user clicked (coords) when beginning the drag
		this.clicky; 
		
		this.images; // 2-dimensional array containing boolean values as to whether the image has been loaded at that location in the grid

		this.x = 0; // current x offset (marginleft)
		this.y = 0;
		
		this.zoomlevels = new Array(.125,.25,.5,1);
		this.zoomlevel = 0;
		
		this.rulers = 1;
		this.rulerColor = '#FFFAC8';
		this.rulerPPI = 0; // pixels per inch for the rulers

		this.icons;  // contains the icon information

		// smoothmove variables
		this.movex = 0;
		this.movey = 0;
		this.moveby = 500;
		this.movetimeout;
		this.isMoving=0;
		
		this.ismovesmooth = 1; // 1 for smooth, 0 for choppy
		
		this.cursordrag0 = this.imgpath+'unclench.cur';
		this.cursordrag1 = this.imgpath+'clench.cur';
		
		this.debug = 0;
		
		this.d;      		// self-reference, html object
		var vp = this; 	// self-reference
		
		this.init = function(vpn,fn,tx,ty,imgs,rulers,rulerPPI,startx,starty) {
			vp.vpn=vpn;

			vp.vpx=parseInt(tx*vp.zoomlevels[0]);
			vp.vpy=parseInt(ty*vp.zoomlevels[0]);
			dbg('vpx: '+vp.vpx+' / vpy: '+vp.vpy);
			vp.vpx=570;
			vp.vpy=364;
			dbg('vpx: '+vp.vpx+' / vpy: '+vp.vpy);
			
			/* main container (id=vpn, e.g. "vp") style */
			vp.d=vp.$(vpn);
			vp.d.style.position="relative";
			//vp.d.style.float="left";
			vp.d.style.width=vp.vpx+'px';
			vp.d.style.height=vp.vpy+'px';
			vp.d.style.overflow='hidden';
			vp.d.style.margin="0 auto";
			vp.d.style.top="0px";
			vp.d.style.border="solid #999 1px";
			vp.d.style.backgroundColor="#fff";
			
			vp.fn=fn;
			vp.tx=tx;
			vp.ty=ty;
			vp.imgs=imgs;

			vp.px=parseInt(tx*vp.zoomlevels[vp.zoomlevel]/imgs)+1;
			vp.py=parseInt(ty*vp.zoomlevels[vp.zoomlevel]/imgs)+1;

			if(startx==undefined||starty==undefined) {
				vp.x=0;
				vp.y=0;
				vp.zoomlevel=0;  // reset to 100% zoom
			} else {
				vp.x=startx;
				vp.y=starty;
			}
			
			// if the rulers parameters are defined and within range, then tell the script to draw them (later on)
			if(rulers==undefined||rulers>1||rulers<-1||rulerPPI==undefined||rulerPPI<0){
				vp.rulers=-1;
			} else {
				vp.rulers=rulers;
				vp.rulerPPI=rulerPPI;
			}
			
			if(vp.vpinner!=undefined) {
				vp.d.removeChild( vp.vpinner );
			}

			vp.vpinner=document.createElement("DIV");
			vp.d.appendChild(vp.vpinner);
			vp.vpinner.id="vpinner";
			vp.vpinner.style.position="absolute";
			vp.vpinner.style.overflow="hidden";
			vp.vpinner.style.backgroundColor="#ccc";
			vp.vpinner.style.backgroundColor="#36c";
			vp.vpinner.style.zIndex=50;
			vp.makeCursor(vp.vpinner,(BrowserDetect.browser!='Opera')?"url("+vp.cursordrag0+"),move":'move',"move");
			vp.vpinner.style.width=parseInt(vp.tx*vp.zoomlevels[vp.zoomlevel])+'px';
			vp.vpinner.style.height=parseInt(vp.ty*vp.zoomlevels[vp.zoomlevel])+'px';
			dbg('vpinner.width: '+vp.vpinner.style.width+' / vpinner.height: '+vp.vpinner.style.height);

			vp.redrawIcons(); // draw icons (zoom, movement, etc)
			vp.redrawRulers(); // draw rulers
			
			vp.images = new Array();
			
			var x,y;
			for(y=0;y<vp.py;y++) {
				vp.images[y]=new Array();
				
				for(x=0;x<vp.px;x++) {
					vp.images[y][x]=false;

					nicex=x;
					nicey=y;
					if(x<10)nicex='0'+x;
					if(y<10)nicey='0'+y;
					
					var newid='vpi'+nicey+'x'+nicex;
					
					var i = document.getElementById(newid);
					if( i!=undefined ) { 
						vp.vpinner.removeChild( i );
					}
					i=document.createElement("DIV");
					vp.vpinner.appendChild(i);
					i.id=newid;
					i.style.position="absolute";
					//if(Browser.advancedOptions())i.style.cursor="move";
					//vp.makeCursor(i,"url(unclench.cur),move","move");

					i.onmousedown = this.dragbegin.bindEvent(i.onmousedown);
					i.ondblclick = this.dblclick.bindEvent(i.ondblclick);

					i.style.width=vp.imgs+"px";
					i.style.height=vp.imgs+"px";
					i.style.left=(x*vp.imgs)+"px";
					i.style.top=(y*vp.imgs)+"px";
					if(vp.debug)i.innerHTML="<div style='border:solid black 1px;width:175px;margin:0 auto;background-color:#fff;text-align:center;'>"+i.id+"</div>";
				}
			}

			vp.coordinate();
			vp.redraw();
			
			document.onmouseup=this.dragend.bindEvent(document);
			document.onblur=this.dragend.bindEvent(document);
			
			dbg('vpd: '+vp.vpn.offsetHeight);
		}
		
		this.toggleRulers = function(e) {
			if( (events.getevent(e)).rightclick ) return;
			if(vp.rulers==1)vp.rulers=0;
			else if(vp.rulers==0)vp.rulers=1;
			vp.redrawRulers();
		}
		
		this.mouseOverIcon = function(e) {
			if(!events||events==undefined)return;
			var t = events.gettarget(e);
			//dbg('changing: '+t.id);
			t.src=vp.imgpath+t.id.substr(2)+"mo.gif";
			//dbg('changed to: '+t.src);
		}

		this.mouseOutIcon = function(e) {
			if(!events||events==undefined)return;
			var t = events.gettarget(e);
			t.src=vp.imgpath+t.id.substr(2)+".gif";
			//dbg('changed back to: '+t.src);
		}
		
		this.redrawIcons = function() {
			var i=0;
			var ib = this.$('vpiconblock'); // iconblock

			if(vp.icons==undefined) {
				// Multi-dimensional array, format as follows:
				//  0: name
				//	1: left (x-coord inside of 'ib' - icon block, defined above)
				//	2: top (y-coord inside of 'ib' - icon block, defined above)
				//	3: the actual IMG element, that will be appended to the document
				//	4: mouseover flag  - if 1, then an onMouseOver should be defined, using predefined naming convention (i.e. 'on' as a suffix for mouseovers, and no suffix for not-mouse-over
				//	5: if set (i.e. not ""), specifies the onMouseClick function
				//	6: the title displayed when mouse is hovering above the icon
				vp.iconsOLD = [
					['zoomin',				4,		0,			document.createElement("IMG"), 1,vp.zoomin,"Zoom In"],
					['zoominmo',			4,		0,			document.createElement("IMG"), -1,"","Zoom In"],
		
					['zoombar3',			4,		i+=54,	document.createElement("IMG"), 1,vp.zoom100,"Zoom To 100%"],
					['zoombar3mo',		4,		i,			document.createElement("IMG"), -1,"","Zoom To 100%"],
					['zoombar2',			4,		i+=11,	document.createElement("IMG"), 1,vp.zoom50,"Zoom To 75%"],
					['zoombar2mo',		4,		i,			document.createElement("IMG"), -1,"","Zoom To 75%"],
					['zoombar1',			4,		i+=12,	document.createElement("IMG"), 1,vp.zoom25,"Zoom To 50%"],
					['zoombar1mo',		4,		i,			document.createElement("IMG"), -1,"","Zoom To 50%"],
					['zoombar0',			4,		i+=12,	document.createElement("IMG"), 1,vp.zoom12,"Zoom To 25%"],
					['zoombar0mo',		4,		i,			document.createElement("IMG"), -1,"","Zoom To 25%"],
		
					['zoomout',				4,		i+=10,	document.createElement("IMG"), 1,vp.zoomout,"Zoom Out"],
					['zoomoutmo',		4,		i,			document.createElement("IMG"), -1,"","Zoom Out"],
					['underzoomout',	4,		i+=52,	document.createElement("IMG"), 0,"",""],
		
					['nbtl',					4,		i+=11,	document.createElement("IMG"), 0,"",""],
					['nbt',						21,		i,			document.createElement("IMG"), 1,vp.moveup,"Move Up"],
					['nbtmo',				21,		i,			document.createElement("IMG"), -1,"","Move Up"],
					['nbtr',					40,		i,			document.createElement("IMG"), 0,"",""],
		
					['nbl',						4,		i+=16,	document.createElement("IMG"), 1,vp.moveleft,"Move Left"],
					['nblmo',				4,		i,			document.createElement("IMG"), -1,"","Move Left"],
					['nbc',						21,		i,			document.createElement("IMG"), 0,"",""],
					['nbr',						40,		i,			document.createElement("IMG"), 1,vp.moveright,"Move Right"],
					['nbrmo',				40,		i,			document.createElement("IMG"), -1,"","Move Right"],
		
					['nbbl',					4,		i+=17,	document.createElement("IMG"), 0,"",""],
					['nbb',						21,		i,			document.createElement("IMG"), 1,vp.movedown,"Move Down"],
					['nbbmo',				21,		i,			document.createElement("IMG"), -1,"","Move Down"],
					['nbbr',					40,		i,			document.createElement("IMG"), 0,"",""],
					['undernavbar',		4,		i+=16,	document.createElement("IMG"), 0,"",""],
		
					['noruler',				4,		i+=8,		document.createElement("IMG"), 1,vp.toggleRulers,"Turn Ruler Off"],
					['norulermo',		4,		i,			document.createElement("IMG"), -1,"","Turn Ruler Off"],
					['ruler',					4,		i,			document.createElement("IMG"), 1,vp.toggleRulers,"Turn Ruler On"],
					['rulermo',			4,		i,			document.createElement("IMG"), -1,"","Turn Ruler On"],
		
					['bottom',				4,		i+=44,	document.createElement("IMG"), 0,"",""]
				];
				
				vp.icons = [
					['nbt',						18,		0,		document.createElement("IMG"), 1,vp.moveup,"Move Up"],
					['nbtmo',					18,		0,		document.createElement("IMG"), -1,"","Move Up"],
		
					['nbl',						0,		17,		document.createElement("IMG"), 1,vp.moveleft,"Move Left"],
					['nblmo',					0,		17,		document.createElement("IMG"), -1,"","Move Left"],

					['nbc',						19,		19,		document.createElement("IMG"), 0,"",""],

					['nbr',						36,		17,		document.createElement("IMG"), 1,vp.moveright,"Move Right"],
					['nbrmo',					36,		17,		document.createElement("IMG"), -1,"","Move Right"],
		
					['nbb',						18,		35,		document.createElement("IMG"), 1,vp.movedown,"Move Down"],
					['nbbmo',					18,		35,		document.createElement("IMG"), -1,"","Move Down"],

					['zoomin',				18,		78,		document.createElement("IMG"), 1,vp.zoomin,"Zoom In"],
					['zoominmo',			18,		78,		document.createElement("IMG"), -1,"","Zoom In"], 
		
					['zoombar3',			18,		102,	document.createElement("IMG"), 1,vp.zoom100,"Zoom To 100%"],
					['zoombar3mo',		18,		102,	document.createElement("IMG"), -1,"","Zoom To 100%"],
					['zoombar2',			18,		113,	document.createElement("IMG"), 1,vp.zoom50,"Zoom To 75%"],
					['zoombar2mo',		18,		113,	document.createElement("IMG"), -1,"","Zoom To 75%"],
					['zoombar1',			18,		125,	document.createElement("IMG"), 1,vp.zoom25,"Zoom To 50%"],
					['zoombar1mo',		18,		125,	document.createElement("IMG"), -1,"","Zoom To 50%"],
					['zoombar0',			18,		136,	document.createElement("IMG"), 1,vp.zoom12,"Zoom To 25%"],
					['zoombar0mo',		18,		136,	document.createElement("IMG"), -1,"","Zoom To 25%"],
		
					['zoomout',				18,		156,	document.createElement("IMG"), 1,vp.zoomout,"Zoom Out"],
					['zoomoutmo',			18,		156,	document.createElement("IMG"), -1,"","Zoom Out"],
		
					['noruler',				3,		198,	document.createElement("IMG"), 1,vp.toggleRulers,"Turn Ruler Off"],
					['norulermo',			3,		198,	document.createElement("IMG"), -1,"","Turn Ruler Off"],
					['ruler',					3,		198,	document.createElement("IMG"), 1,vp.toggleRulers,"Turn Ruler On"],
					['rulermo',				3,		198,	document.createElement("IMG"), -1,"","Turn Ruler On"]
				];
			}
			
			if(ib==undefined||ib=="") { // init
				ib = document.createElement("DIV");
				vp.d.appendChild( ib );
				ib.id = "vpiconblock";
				ib.style.position = "absolute";
				ib.style.top = "15px";
				ib.style.left = "15px";
				ib.style.zIndex = 500;
				
				var cursor0 = document.createElement( "DIV" );
				vp.makeCursor( cursor0, "url("+vp.cursordrag0+")" );
				var cursor1 = document.createElement( "DIV" );
				vp.makeCursor( cursor1, "url("+vp.cursordrag1+")" );
				
				for(i=0;i<vp.icons.length;i++) {
					vp.icons[i][3].style.position="absolute";
					vp.icons[i][3].style.left='-100px'; // load off-screen (firefox liked to display them briefly)
					vp.icons[i][3].style.top='-100px';
					ib.appendChild( vp.icons[i][3] );
					vp.icons[i][3].id = 'vp'+vp.icons[i][0];
					vp.icons[i][3].src = vp.imgpath+vp.icons[i][0]+'.gif';
					vp.icons[i][3].style.left=vp.icons[i][1]+'px';
					vp.icons[i][3].style.top=vp.icons[i][2]+'px';
					vp.icons[i][3].style.zIndex=501;
					vp.icons[i][3].setAttribute("alt",vp.icons[i][6]);
					vp.icons[i][3].setAttribute("title",vp.icons[i][6]);
				}
			}
				
			for(i=0;i<vp.icons.length;i++) {
				if(vp.icons[i][4]==1) { // if mouseover flag set
					vp.icons[i][3].onmouseover = vp.mouseOverIcon;
					vp.icons[i][3].onmouseout = vp.mouseOutIcon;
					vp.makeCursor(vp.icons[i][3],"pointer","hand");
				} else if(vp.icons[i][4]<0) { // -1 means that it is the mouseover, so hide it
					this.hide('vp'+vp.icons[i][0]);
				}
				
				if(vp.icons[i][5]!="") {
					vp.icons[i][3].onmouseup = vp.icons[i][5];
				}
			}
			
			// zoombar
			for(i=0;i<vp.zoomlevels.length;i++) {
				if(i==vp.zoomlevel) {
					this.show('vpzoombar'+i+'mo');
				} else {
					this.hide('vpzoombar'+i+'mo');
				}
			}
			
			// zoom in/out icons
			if(vp.zoomlevel==vp.zoomlevels.length-1) {
				vp.disableIcon('zoomin');
			} else if(vp.zoomlevel==0) {
				vp.disableIcon('zoomout');
			} 

			// ruler icon -- invisible if vp.rulers<0			
			if(vp.rulers<0) {
				vp.icons[ vp.icons.length-1 ][3].style.top=vp.icons[ vp.icons.length-1 ][2]-44+'px';
				this.hide('vpruler');
				this.hide('vpnoruler');
			} else {
				vp.icons[ vp.icons.length-1 ][3].style.top=vp.icons[ vp.icons.length-1 ][2]+'px';
			}
		}
		
		this.disableIcon = function(d) {
			for(var i=0;i<vp.icons.length;i++) {
				if(vp.icons[i][0]==d)
					break;
			}
			if(i<vp.icons.length){
				vp.icons[i][3].onmouseover=null;
				vp.icons[i][3].onmouseout=null;
				vp.icons[i][3].onmouseup=null;
				this.show('vp'+d);
				this.hide('vp'+d+'mo');
				var ev = Object();
				ev.target = this.$('vp'+d);
				vp.mouseOutIcon(ev);
				dbg('hiding '+'vp'+d+'mo '+ this.$('vp'+d+'mo').src);
				vp.makeCursor(vp.icons[i][3],"");
			}
		}
		
		this.mouseOutIcon = function(e) {
			if(!events||events==undefined)return;
			var t = events.gettarget(e);
			t.src=vp.imgpath+t.id.substr(2)+".gif";
		}
				
		this.redrawRulers = function() {
			if(vp.rulers==1) {
				// define horizontal ruler			
				var rulerx = this.$('vprulerx');
				if( rulerx==undefined||rulerx=="" ) { 
					rulerx = document.createElement('DIV');
					vp.d.appendChild(rulerx);
					rulerx.id='vprulerx';
					rulerx.style.backgroundColor="#fff";
					rulerx.style.backgroundColor=vp.rulerColor;
					rulerx.style.border="solid black 1px";
					rulerx.style.position="absolute";
					rulerx.style.left=0+'px';
					rulerx.style.height='20px';
					rulerx.style.zIndex=9998;
					rulerx.style.overflow='hidden';
					//rulerx.style.=;
					rulerx.onmousedown=null;
				}
				rulerx.style.top=(vp.vpy-20)+'px';
				rulerx.style.width=(vp.vpx)+'px';
				
				// define vertical ruler
				var rulery = this.$('vprulery');
				if( rulery==undefined||rulery=="" ) { 
					var rulery = document.createElement('DIV');
					vp.d.appendChild(rulery);
					rulery.id='vprulery';
					rulery.style.backgroundColor="#fff";
					rulery.style.backgroundColor=vp.rulerColor;
					rulery.style.border="solid black 1px";
					rulery.style.position="absolute";
					rulery.style.top='0px';
					rulery.style.width='26px';
					rulery.style.zIndex=9997;
					rulery.style.overflow='hidden';
					//rulery.style.=;
					rulery.onmousedown=null;
				}
				rulery.style.left=(vp.vpx-22)+'px';
				rulery.style.height=(vp.vpy)+'px';
				
				var createLabel = function(par,num,type) { // parent, text to display, type (-1 fraction, 0 normal, 1 foot)
					label = document.createElement("SPAN");
					var left = -4, top = 4;
					dbg('got label title: '+num);
					label.style.backgroundColor=vp.rulerColor;
					if(type==-1) {
						if(num==.5) { 
							num='&#189;';
							top-=2;
							label.style.fontSize="10pt";
						}	else if(num==.25) {
							num='&#188;';
							top-=1;
							left+=2;
							label.style.fontSize="8pt";
						} else if(num==.75) {
							num='&#190;';
							top-=1;
							left+=2;
							label.style.fontSize="8pt";
						}
					} else if(type==0) {
						label.style.fontSize="7pt";
					} else {
						label.style.fontSize="8pt";
						label.style.padding="0";
						label.style.position="absolute";
						label.style.zIndex=10005;
						label.style.backgroundColor="#E2CE2D";
						label.style.border="solid #999 1px";
						label.style.borderBottom="0";
						num+='ft';
						left-=5;
						if(BrowserDetect.browser=='Firefox')top+=1;
					}
					//label.appendChild( document.createTextNode("&gt;&lt;") );
					label.innerHTML=num;
					par.appendChild( label );
					label.style.position="relative";
					label.style.top=top+'px';
					label.style.fontWeight="bold";
					if(num.toString().length<2) {
						label.style.left=left+'px';
					} else {
						label.style.left=(left-3)+'px';
					}
				}

				// draw ruler itself - numbers, lines, etc.
				var label,count=0;
				rulerx.innerHTML="";
				while( count*vp.rulerPPI*vp.zoomlevels[vp.zoomlevel]/8<vp.vpx ) {
					
					if( 
							vp.zoomlevel==0&&vp.rulerPPI==120&&count%8!=0 ||
							vp.zoomlevel==1&&vp.rulerPPI==120&&count%4!=0 ||
							vp.zoomlevel==0&&vp.rulerPPI==22&&count%96!=0 ||
							vp.zoomlevel==1&&vp.rulerPPI==22&&count%24!=0 ||
							vp.zoomlevel==2&&vp.rulerPPI==22&&count%8!=0  ||
							vp.zoomlevel==3&&vp.rulerPPI==22&&count%4!=0
					) {
						count++;
						continue;
					}
					
					var num=document.createElement("DIV");
					num.style.position='absolute';
					num.style.left='-100px'; // load off-screen
					num.style.top='-100px';
					if(count%8==0) {                    			 // every inch
						num.style.height='20px';
						num.style.borderLeft='solid #666 2px';
						if(
								count%96==0&&count!=0 &&
									( vp.rulerPPI==22 ||
									  vp.zoomlevel<2&&vp.rulerPPI==120 ||
									  vp.zoomlevel<1&&vp.rulerPPI==284 )
						) { // every foot
							createLabel(num,parseInt(count/96),1);

						} else {
							if(vp.zoomlevel==0&&vp.rulerPPI==120) {
								if(count%16==0) {
									createLabel(num,count/8%12,0);
								} else {
									num.style.height='10px';
									num.style.borderLeft='solid #666 1px';
								}
							} else {
							  if( vp.zoomlevel==0&&vp.rulerPPI==284 ) {
									createLabel(num,count/8%12,0);
							  } else if( vp.zoomlevel==3&&vp.rulerPPI==22 ) {
									createLabel(num,count/8%12,0);
							  } else if( vp.zoomlevel==2&&vp.rulerPPI==22 ) {
									if(count%16==0) {
										createLabel(num,count/8%12,0);
									} else {
										num.style.height='10px';
										num.style.borderLeft='solid #666 1px';
									}
							  } else if( vp.zoomlevel==1&&vp.rulerPPI==22 ) {
									if(count/8%12==6) {
										createLabel(num,6,0);
									} else {
										num.style.height='10px';
										num.style.borderLeft='solid #666 1px';
									}
							  } else {
									createLabel(num,count/8%12,0);
						  }
							}
						}
					} else if(count%4==0) {                    // every 1/2 inch
						num.style.height='14px';
						num.style.fontSize="1pt";
						if(vp.zoomlevel>1) {
							num.style.borderLeft='solid #666 2px';
						} else {
							num.style.borderLeft='solid #666 1px';
						}

						if( 
								vp.zoomlevel>1&&vp.rulerPPI==284 ||
								vp.zoomlevel==3&&vp.rulerPPI==120 
						) {
							createLabel(num,.5,-1);
						} else if( vp.zoomlevel==3 && vp.rulerPPI==22) {
							num.style.borderLeft='solid #999 1px';
						}

					} else if(count%6==0||count%2==0) {        // every 1/4 inch
						if(vp.zoomlevel>2&&vp.rulerPPI==284) {
							createLabel(num,(count%8==6)?.75:.25,-1);
						}
						num.style.height='10px';
						num.style.fontSize="1pt";
						num.style.borderLeft='solid #666 1px';
					} else {
						num.style.height='6px';
						num.style.fontSize="1pt";
						if(vp.zoomlevel>0) {
							num.style.borderLeft='solid #666 1px';
						}
					}
					rulerx.appendChild(num);
					num.style.position='absolute';
					num.style.top=0+'px';
					num.style.left=(count*vp.rulerPPI*vp.zoomlevels[vp.zoomlevel]/8-3)+'px';
					num.style.color="black";
					num.style.zIndex=9999;
					count++;
				}
				
				// do vertical ruler
				createLabel = function(par,num,type) { // parent, text to display, type (-1 fraction, 0 normal, 1 foot)
					label = document.createElement("SPAN");
					var left = 8, top = -6;
					dbg('got label title: '+num);
					label.style.backgroundColor=vp.rulerColor;
					if(type==-1) {
						if(num==.5) { 
							num='&#189;';
							top-=2;
							label.style.fontSize="10pt";
						}	else if(num==.25) {
							num='&#188;';
							top-=1;
							left+=2;
							label.style.fontSize="8pt";
						} else if(num==.75) {
							num='&#190;';
							top-=1;
							left+=2;
							label.style.fontSize="8pt";
						}
					} else if(type==0) {
						label.style.fontSize="7pt";
					} else {
						label.style.fontSize="8pt";
						label.style.padding="0";
						label.style.position="absolute";
						label.style.zIndex=10005;
						label.style.backgroundColor="#E2CE2D";
						label.style.border="solid #999 1px";
						label.style.borderRight="";
						if(num>9) {
							left-=5;
						} else {
							left-=1;
						}
						num+='ft';
						top-=2;
						if(BrowserDetect.browser=='Firefox') {
							top+=1;
							left+=1;
						}
					}
					//label.appendChild( document.createTextNode("&gt;&lt;") );
					label.innerHTML=num;
					par.appendChild( label );
					label.style.position="relative";
					label.style.top=top+'px';
					label.style.fontWeight="bold";
					if(num.toString().length<2) {
						label.style.left=left+'px';
					} else {
						label.style.left=(left-3)+'px';
					}
				}
				count=0;
				rulery.innerHTML="";
				while( count*vp.rulerPPI*vp.zoomlevels[vp.zoomlevel]/8<vp.vpy ) {
					
					if( 
							vp.zoomlevel==0&&vp.rulerPPI==120&&count%8!=0 ||
							vp.zoomlevel==1&&vp.rulerPPI==120&&count%4!=0 ||
							vp.zoomlevel==0&&vp.rulerPPI==22&&count%96!=0 ||
							vp.zoomlevel==1&&vp.rulerPPI==22&&count%24!=0 ||
							vp.zoomlevel==2&&vp.rulerPPI==22&&count%8!=0  ||
							vp.zoomlevel==3&&vp.rulerPPI==22&&count%4!=0
					) {
						count++;
						continue;
					}
					
					var num=document.createElement("DIV");
					num.style.position='absolute';
					num.style.left='-100px';
					num.style.top='-100px';
					if(count%8==0) {                    			 // every inch
						num.style.width='20px';
						num.style.borderTop='solid #666 2px';
						if(
								count%96==0&&count!=0 &&
									( vp.rulerPPI==22 ||
									  vp.zoomlevel<2&&vp.rulerPPI==120 ||
									  vp.zoomlevel<1&&vp.rulerPPI==284 )
						) { // every foot
							createLabel(num,parseInt(count/96),1);

						} else {
							if(vp.zoomlevel==0&&vp.rulerPPI==120) {
								if(count%16==0) {
									createLabel(num,count/8%12,0);
								} else {
									//createLabel(num,'',0);
									num.style.width='12px';
									num.style.borderTop='solid #999 1px';
								}
							} else {
							  if( vp.zoomlevel==0&&vp.rulerPPI==284 ) {
									createLabel(num,count/8%12,0);
							  } else if( vp.zoomlevel==3&&vp.rulerPPI==22 ) {
									createLabel(num,count/8%12,0);
							  } else if( vp.zoomlevel==2&&vp.rulerPPI==22 ) {
									if(count%16==0) {
										createLabel(num,count/8%12,0);
									} else {
										num.style.width='10px';
										num.style.borderTop='solid #666 1px';
									}
							  } else if( vp.zoomlevel==1&&vp.rulerPPI==22 ) {
									if(count/8%12==6) {
										createLabel(num,6,0);
									} else {
										num.style.width='10px';
										num.style.borderTop='solid #666 1px';
									}
							  } else {
									createLabel(num,count/8%12,0);
						  }
							}
						}
					} else if(count%4==0) {                    // every 1/2 inch
						num.style.width='12px';
						num.style.fontSize="1pt";
						if(vp.zoomlevel>1) {
							num.style.borderTop='solid #666 2px';
						} else {
							num.style.borderTop='solid #666 1px';
						}

						if( 
								vp.zoomlevel>1&&vp.rulerPPI==284 ||
								vp.zoomlevel==3&&vp.rulerPPI==120 
						) {
							createLabel(num,.5,-1);
						} else if( vp.zoomlevel==3 && vp.rulerPPI==22) {
							num.style.borderTop='solid #999 1px';
						}

					} else if(count%6==0||count%2==0) {        // every 1/4 inch
						if(vp.zoomlevel>2&&vp.rulerPPI==284) {
							createLabel(num,(count%8==6)?.75:.25,-1);
						}
						num.style.width='10px';
						num.style.fontSize="1pt";
						num.style.borderTop='solid #666 1px';
					} else {
						num.style.width='6px';
						num.style.fontSize="1pt";
						if(vp.zoomlevel>0) {
							num.style.borderTop='solid #666 1px';
						}
					}
					rulery.appendChild(num);
					num.style.left=0+'px';
					num.style.top=(count*vp.rulerPPI*vp.zoomlevels[vp.zoomlevel]/8-2)+'px';
					num.style.color="black";
					num.style.zIndex=9999;
					count++;
				}
				this.show("vprulerx");
				this.show("vprulery");
				
				this.hide("vpruler");
				this.show("vpnoruler");
			} else if(vp.rulers==0) {
				this.hide("vprulerx");
				this.hide("vprulery");
				
				this.show("vpruler");
				this.hide("vpnoruler");
			} else if(vp.rulers==-1) {
				this.hide("vprulerx");
				this.hide("vprulery");
				
				this.hide("vpruler");
				this.hide("vpnoruler");
			} 
		}
		
		this.redraw = function() {
			var startx = Math.abs( parseInt( vp.x / vp.imgs ) )-1;
			var starty = Math.abs( parseInt( vp.y / vp.imgs ) )-1;
			if(startx<0)startx=0;
			if(starty<0)starty=0;
			
			var endx = parseInt( vp.vpx / vp.imgs ) + startx+3;
			var endy = parseInt( vp.vpy / vp.imgs ) + starty+3;
			if(endx>vp.px)endx=vp.px;
			if(endy>vp.py)endy=vp.py;
			
			dbg('startx: '+startx+' -&gt; endx:'+endx +' / starty: '+starty+' -&gt; endy:'+endy+' / vp,x: '+vp.x+' / vp.y: '+vp.y+' / movex: '+vp.movex+' / movey: '+vp.movey);

			var im,x,y;
			for(y=starty;y<endy;y++) {
				for(x=startx;x<endx;x++) {
					if(vp.images[y][x])continue;

					nicex=(x<10)?'0'+x:x;
					nicey=(y<10)?'0'+y:y;
					im=this.$('vpi'+nicey+'x'+nicex);
					im.style.backgroundImage="url("+vp.imgchunkpath+vp.fn+'/'+parseInt(vp.zoomlevels[vp.zoomlevel]*100)+'.'+nicey+'x'+nicex+'.jpg)';
					dbg('just loaded: '+im.style.backgroundImage);
					vp.images[y][x]=true;
				}
			}
		}
		
		this.coordinate = function() {
			if(vp.vpx > vp.tx*vp.zoomlevels[vp.zoomlevel]) { // if the image is smaller than the viewport
				vp.x = vp.vpx/2 - vp.tx*vp.zoomlevels[vp.zoomlevel]/2; // center it
			} else if(vp.x>0) {  // if out of bounds (top-left)
				vp.x=0;
				if(vp.ismovesmooth&&vp.isMoving)vp.movex=vp.x;
			} else if(vp.x<vp.vpx-(vp.tx*vp.zoomlevels[vp.zoomlevel])) { // if out of bounds (the bottom-right)
				vp.x=vp.vpx-(vp.tx*vp.zoomlevels[vp.zoomlevel]);
				if(vp.ismovesmooth&&vp.isMoving)vp.movex=vp.x;
			}
			if(vp.vpy > vp.ty*vp.zoomlevels[vp.zoomlevel]) {
				vp.y = vp.vpy/2 - vp.ty*vp.zoomlevels[vp.zoomlevel]/2; // center it
			} else if(vp.y>0) {
				vp.y=0;
				if(vp.ismovesmooth&&vp.isMoving)vp.movey=vp.y;
			} else if(vp.y<vp.vpy-(vp.ty*vp.zoomlevels[vp.zoomlevel])) {
				vp.y=vp.vpy-(vp.ty*vp.zoomlevels[vp.zoomlevel]);
				if(vp.ismovesmooth&&vp.isMoving)vp.movey=vp.y;
			}
			
			if(vp.ismovesmooth&&!vp.isMoving) {
				vp.movex=vp.x;
				vp.movey=vp.y;
			}
			
			vp.vpinner.style.left=vp.x+'px';
			vp.vpinner.style.top=vp.y+'px';
		}
		
		this.moveup = function(e) { (vp.ismovesmooth)?vp.movesmooth(e,'u'):vp.movechoppy(e,'u'); }
		this.moveleft = function(e) { (vp.ismovesmooth)?vp.movesmooth(e,'l'):vp.movechoppy(e,'l'); }
		this.moveright = function(e) { (vp.ismovesmooth)?vp.movesmooth(e,'r'):vp.movechoppy(e,'r'); }
		this.movedown = function(e) { (vp.ismovesmooth)?vp.movesmooth(e,'d'):vp.movechoppy(e,'d'); }

		this.movechoppy = function(e,d) { 
			if( !(events.getevent(e)).leftclick ) return;
			var b = 150;
			switch(d) {
				case 'u':vp.y+=vp.zoomlevels[vp.zoomlevel]*b;break;
				case 'l':vp.x+=vp.zoomlevels[vp.zoomlevel]*b;break;
				case 'r':vp.x-=vp.zoomlevels[vp.zoomlevel]*b;break;
				case 'd':vp.y-=vp.zoomlevels[vp.zoomlevel]*b;break;
			}
			vp.coordinate();
			vp.redraw();
		}
		
		this.movesmooth = function(e,d) { 
			if( !(events.getevent(e)).leftclick ) return;
			switch(d) {
				case 'u':vp.movey+=parseInt(vp.zoomlevels[vp.zoomlevel]*vp.moveby);break;
				case 'l':vp.movex+=parseInt(vp.zoomlevels[vp.zoomlevel]*vp.moveby);break;
				case 'r':vp.movex-=parseInt(vp.zoomlevels[vp.zoomlevel]*vp.moveby);break;
				case 'd':vp.movey-=parseInt(vp.zoomlevels[vp.zoomlevel]*vp.moveby);break;
			}
			if(vp.movetimeout==undefined)
				vp.moveActually();
		}
		
		this.moveActually = function() {
			if(vp.movetimeout!=undefined){
				clearTimeout(vp.movetimeout);
				vp.movetimeout=undefined;
			}
			vp.isMoving=1;
			var m = parseInt(vp.zoomlevels[vp.zoomlevel]*vp.moveby/4); // partial move
			dbg('partial move by: '+m);

			if(vp.x>0)vp.movex=vp.x;                         // if image is smaller than viewport, then don't move
			//else if(vp.movex>0)vp.movex=0;                   // if trying to move out of bounds
			else if(Math.abs(vp.x-vp.movex)<m)vp.movex=vp.x; // if the difference is less than the "partial move", then set them equal
			else if(vp.x<vp.movex)vp.x+=m;
			else vp.x-=m;
				
			if(vp.y>0)vp.movey=vp.y;
			else if(Math.abs(vp.y-vp.movey)<m)vp.movey=vp.y;
			else if(vp.y<vp.movey)vp.y+=m;
			else vp.y-=m;
				
			vp.coordinate();
			vp.redraw();
			
			if(vp.movex!=vp.x||vp.movey!=vp.y){
				dbg('Setting timeout');
				vp.movetimeout=setTimeout("vpInstance.moveActually()",1);
			}  else {
				dbg('Timeout FINSIHED');
				vp.movetimeout=undefined;
			}
			vp.isMoving=0;
		}

		this.zoom100 = function(e) {vp.zoomToLevel(e,3);}
		this.zoom50 = function(e) {vp.zoomToLevel(e,2);}
		this.zoom25 = function(e) {vp.zoomToLevel(e,1);}
		this.zoom12 = function(e) {vp.zoomToLevel(e,0);}
		
		this.zoomin = function(e) {	vp.zoomToLevel(e,vp.zoomlevel+1); }
		this.zoomout = function(e) {	vp.zoomToLevel(e,vp.zoomlevel-1); }
		
		this.zoomToLevel = function(e,level) {
			if( !(events.getevent(e)).leftclick ) return;

			// out of bounds check			
			if(level>=vp.zoomlevels.length)level=vp.zoomlevels.length-1;
			else if(level<0) level=0;

			var origzoom = vp.zoomlevel;
			vp.zoomlevel=level;
			
			/*
			logic might come in handy: -->

			var newx = -vp.x; // 100
			newx = newx + vp.vpx/2; // 200
			var percentAcross = newx / (vp.tx * vp.zoomlevels[origzoom]); // .66666
			newx = percentAcross * vp.tx * vp.zoomlevels[vp.zoomlevel]; // 400
			newx = newx - vp.vpx/2; // 300

			var newy = -vp.y; // 100
			dbg('a) newy: '+newy);
			newy = newy + vp.vpy/2; // 200
			dbg('b) newy: '+newy);
			var percentAcross = newy / (vp.ty * vp.zoomlevels[origzoom]); // .66666
			dbg('c) percentAcross: '+percentAcross);
			newy = percentAcross * vp.ty * vp.zoomlevels[vp.zoomlevel]; // 400
			dbg('d) newy: '+newy);
			newy = newy - vp.vpy/2; // 300
			dbg('e) newy: '+newy);

			dbg('reporting newx: '+newx+' / newy: '+newy);

			var newx2 = -parseInt(((vp.vpx/2-vp.x)/(vp.tx*vp.zoomlevels[origzoom]))*vp.tx*vp.zoomlevels[vp.zoomlevel]-vp.vpx/2)
			var newy2 = -parseInt(((vp.vpy/2-vp.y)/(vp.ty*vp.zoomlevels[origzoom]))*vp.ty*vp.zoomlevels[vp.zoomlevel]-vp.vpy/2)

			dbg('reporting newx2: '+newx2+' / newy2: '+newy2);
			*/
			
			vp.init(vp.vpn,vp.fn,vp.tx,vp.ty,vp.imgs,vp.rulers,vp.rulerPPI,-parseInt(((vp.vpx/2-vp.x)/(vp.tx*vp.zoomlevels[origzoom]))*vp.tx*vp.zoomlevels[vp.zoomlevel]-vp.vpx/2),-parseInt(((vp.vpy/2-vp.y)/(vp.ty*vp.zoomlevels[origzoom]))*vp.ty*vp.zoomlevels[vp.zoomlevel]-vp.vpy/2));
		}
		
		this.dblclick = function(e) {
			if(vp.zoomlevel+1<vp.zoomlevels.length){
				var mpos = events.getmpos(e);
				dbg('dblclick: mposX: '+mpos[0]+' / mposY:'+mpos[1]);	
				var c = findPos( vp.d );
				vp.zoomlevel++;
				// the logic is the same, except "center of image" is replaced by where double click occured
				vp.init(vp.vpn,vp.fn,vp.tx,vp.ty,vp.imgs,vp.rulers,vp.rulerPPI,-((mpos[0]-vp.x-c[0])*2-vp.vpx/2),-((mpos[1]-vp.y-c[1])*2-vp.vpy/2));
			}
		}
		
		this.mousewheel = function(e) {
			var d = events.getmousewheel(e);
			if(d==1) {
				vp.dblclick(e);
			} else if(d==-1) {
				vp.zoomout(e);
			}
		}
		
		this.dragend = function(e) {
			ev = events.getevent(e);
			vp.makeCursor(vp.vpinner,"url("+vp.cursordrag0+"),move","move");

			document.onmousemove = null;
			document.onselectstart = null;
		}
		
		this.dragbegin = function(e) {
			ev = events.getevent(e);
			if(!ev.leftclick)return;
			
			if(vp.ismovesmooth&&vp.movetimeout!=undefined){
				clearTimeout(vp.movetimeout);
				vp.movetimeout=undefined;
			}

			vp.clickx=ev.mposx-vp.x;
			vp.clicky=ev.mposy-vp.y;
			
			vp.makeCursor(vp.vpinner,"url("+vp.cursordrag1+"),move","move");

			document.onmousemove = vp.drag.bindEvent(document);
			document.onselectstart = function() { return false; }
			
			vp.drag(e);
			
			return false;
		}
		
		this.drag = function(e) {
			var mpos = events.getmpos(e);
			vp.x=mpos[0]-vp.clickx;
			vp.y=mpos[1]-vp.clicky;
			
			vp.coordinate();
			vp.redraw();
			
			if(!e) var e = window.event;
			e.returnValue=false; // allows for draggable images in IE
			return false;
		}
		
		this.makeCursor = function(d,c,a) {
			if(d==undefined||d.style==undefined)return;
			try {d.style.cursor=c;}
			catch(e){
				try{
					d.style.cursor=a;
				} catch(e) {
					d.style.cursor='default';
				}
			}
		}
	
		this.show = function(id,display) {
			if(display==undefined) display="block";
			var d=this.$(id);
			if(d==""||d==undefined)return;
			d.style.visibility="visible";
			d.style.display=display;
		}
		
		this.hide = function(id) {
			var d=this.$(id);
			if(d==""||d==undefined)return;
			d.style.visibility="hidden";
			d.style.display='none';
		}
	
		function dbg(m) {
			if(BrowserDetect.browser!='Firefox') return;
			if(!vp.debug) return ;
			var d = document.getElementById("vpdebug");
			if(d==undefined) {
				d = document.createElement("DIV");
				document.getElementsByTagName('body')[0].appendChild(d);
				d.id='vpdebug';
				d.style.overflow="auto";
				d.style.marginTop="30";
				d.style.backgroundColor="#def";
				d.style.height="270px";
			}
			d.innerHTML="<span style='font-size:7pt;color:#999'>"+Date()+'</span> '+m+"<br>\n"+d.innerHTML;
		}
		
		this.$ = function(id) {
			var d=document.getElementById(id);
			return (d==undefined)?"":d;
		}
	}

// -->