/*** (C)2007 Scripterlative.com

Info: http://scripterlative.com

These instructions may be removed, but not the above text.

-- PopUtopia --

A Highly Versatile, Easily-Configured Popup Displayer/Generator

Click over a link, image or other element to display a popup element.

* Centered Positioning Within the Available Viewing Area.

* Easy, Foolproof, Unobtrusive Setup - no need to add code to HTML tags.

* Independent Styling of Each popup Element.

* Interactive Popups - Popups created via HTML markup can contain links, forms, iframes etc.

Introduction
~~~~~~~~~~~~
PopUtopia displays customisable popup 'windows' in response to the clicking of a corresponding element.
Popups are positioned centrally within the current viewport.

Popups can be created in any of three ways:
1) Marking-up a div or other element containing the displayable data, and styling it: display:none;
2) Specifying that the script generate a popup that displays specified text.
3) Specifying that the script generate a popup that displays the triggering element's title text.

2 & 3 are referred to as 'script-generated' popups. These popups can contain plain text only.

All popups are enterable by the mouse cursor, allowing normal copying of data to the clipboard.

All popups are automatically appended an [X] 'Close' button.

Installation
~~~~~~~~~~~~
Save this file/text as 'poputopia.js', then place it into a folder related to your web pages:

Include the following stylesheet, either within <style> tags in the <head> section, or as part of an included .css file.

.PopUtopia
{
 background-color:#fff; background:#fff; color:#00f; font-weight:bold; font-size:0.8em; border:4px outset #ccc; text-align:center; padding:0;margin:0;font-family:monospace,courier
}

Towards the end of the <BODY> section, or at least anywhere below all involved triggering elements, insert these tags:

<script type='text/javascript' src='poputopia.js'></script>

Note: If poputopia.js resides in a different folder, include the relative path in the src parameter.

After the above tags, insert:

<script type='text/javascript'>

PopUtopia.setup(  See 'Configuration'  );

</script>

Configuration
~~~~~~~~~~~~~
The term 'popup' means any element that appears in response to the clicking of a corresponding element, regardless of its content.
The term 'triggering element' applies to any element to be clicked to display a popup; usually links or small images.

Each triggering element must be assigned a unique ID attribute.

All the popups in a document are configured in one call to the function: PopUtopia.setup.

For each popup, two parameters must be specified:
 The first parameter specifies the ID of the triggering element.
 The second parameter specifies EITHER the ID of a marked-up popup element, OR the text to be displayed.

If the supplied ID in the second parameter matches that of an element, that element becomes the popup displayed. Otherwise a script-generated popup is created, which displays the text of the second parameter.
NOTE: The text specified in the second parameter appears literally, it is not parsed as HTML.
If the second parameter is specified as an empty string: "", a script-generated popup is created, which displays the text of the triggering element's 'title' attribute.

Example 1
~~~~~~~~~
A page in a property website shows three images assigned ID attributes 'bed1', 'bed2', and 'bath1', which when clicked are to generate descriptive popups using the default stylesheet.

<script type='text/javascript' src='poputopia.js'></script>

<script type='text/javascript'>

PopUtopia.setup(
"bed1",  "The spacious master bedroom affords a commanding view of the harbour below.",
"bed2",  "The second bedroom is south-facing and receives sunlight throughout the day.",
"bath1", "The main bathroom is equipped to the highest standard." // <- No comma after last parameter
);

</script>

That's all there is to it.

Custom Styling
~~~~~~~~~~~~~~
By default, the styling of script-generated popups is determined by a stylesheet called "PopUtopia". This stylesheet is supplied with the code and can be freely modified.
Alternatively generated popups can be easily styled individually, simply by appending the name of a custom stylesheet to the ID parameter of the pertinent trigger element, using the colon ':' character as a separator. (See examples)
Marked-up popups are styled by the page's author in the usual way, and by default receive no additional styling from the script. However, they can have a stylesheet specified in the same way as script-generated popups.

Example 2
~~~~~~~~~
Amending Example 1, a separate stylesheet named 'beigeScheme' has been specified for use with the bathroom popup.

PopUtopia.setup(
"bed1",  "The spacious master bedroom affords a commanding view of the harbour below.",
"bed2",  "The second bedroom is south-facing and receives sunlight throughout the day.",
"bath1:beigeScheme", "The Main Bathroom has a fashionable beige colour scheme." // <- No comma after last parameter
);

For script-generated popups, the attributes most likely to be styled are perhaps border, color, backround-color.
If you require instruction in creating CSS stylesheets, visit: http://www.w3schools.com/css/

Example 3
~~~~~~~~~
Three links with IDs 'lk1','lk2' and 'lk3', will display script-generated popups that replace their standard 'title=' text. The default stylesheet will apply for all the links:

PopUtopia.setup("lk1","", "lk2","", "lk3","");

Note: If you have a large number of popups, it is OK to split the setup into multiple function calls.

Creating Marked-Up popups
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Marked-Up popups can contain any combination of web page elements, including inline frames, but should be enclosed within an outer <div> element.
The enclosing div must have an ID parameter assigned.
Once the appearance of the popup is satisfactory, the enclosing div must be styled: display:none.
The area adjacent to the 'Close' buttons is transparent by default. This can be changed using the CSS 'background' attribute (not background-color), as applied to the enclosing div element.

Using Marked-Up popups
~~~~~~~~~~~~~~~~~~~~~~
In the call to PopUtopia.setup, specify the ID of the relevant div in place of the descriptive text shown in the above examples.

Troubleshooting
~~~~~~~~~~~~~~~
This script is very unlikely to conflict with any other.
This script should be loaded after any other script that uses either the "onmousemove" event, or the onmouseover/onmouseout events of any of the same elements.
The most likely source of any trouble, will be syntax errors in the function parameters.
Ensure all necessary file paths are specified correctly.

Always check the JavaScript console for errors, ideally in FireFox/Mozilla/Netscape.
Ensure that your HTML/CSS is valid, at: http://validator.w3.org

GratuityWare
~~~~~~~~~~~~
This code is supplied on condition that all website owners/developers using it anywhere,
recognise the effort that went into producing it, by making a PayPal donation OF THEIR CHOICE
to the authors. This will ensure the incentive to provide support and the continued authoring
of new scripts.

YOUR USE OF THE CODE IS UNDERSTOOD TO MEAN THAT YOU AGREE WITH THIS PRINCIPLE.

You may donate at www.scripterlative.com, stating the URL to which the donation applies.

*** DO NOT EDIT BELOW THIS LINE ***/

var PopUtopia=
{
  /*** Free Download: http://scripterlative.com?poputopia ***/ 
    
 data:[], x:0, y:0, xDisp:0, yDisp:0, portWidth:0, bon:0xf&0, portHeight:0, isViable:typeof document.getElementsByTagName!='undefined', dataCode:0, lastIndex:-1, firstCall:true, logged:0,

 setup:function()
 {
  var paramGroup=2;

  if(this.isViable)
  {
   if(this.firstCall)
   {
    this.firstCall=false;

    this.addToHandler(document, 'onmousemove', function(){PopUtopia.getMouseAndScrollData(arguments[0]);});

    this.cont();
   }

   if( document.documentElement )
    this.dataCode = 3;
   else
    if(document.body && typeof document.body.scrollTop!='undefined')
     this.dataCode = 2;
    else
     if( typeof window.pageXOffset!='undefined' )
      this.dataCode = 1;
      
   this.datacode = this.bon?this.datacode:-1;

   for(var i=this.data.length, idParts, j=0; j<arguments.length; i++, j+=paramGroup)
   {
    this.data[i]={};

    idParts=arguments[j].split(':');

    if( !(this.data[i].trigElem=document.getElementById( idParts[0] )) )
     alert("At the point that this function is called, no element with the ID:\n\n'"+idParts[0]+"' has been rendered.");
    else
    {
     if(arguments[j+1]=="")
     {
      this.data[i].displayElem=this.data[i].trigElem.title || "???";
      this.data[i].trigElem.title="";
     }
     else
      this.data[i].displayElem = document.getElementById(arguments[j+1]) || arguments[j+1];

     if(typeof this.data[i].displayElem=='string')
     {
      this.data[i].isDynamic=true;
      this.data[i].classId=idParts[1] || "PopUtopia" ;
     }
     else
      this.data[i].classId=idParts[1] || "";

     this.addToHandler(this.data[i].trigElem, 'onclick', new Function("if(PopUtopia!=null){PopUtopia.display("+i+",true);}return false;"));

    }
   }
  }
 },

 checkContent:function(index)
 {
   var xLink=document.createElement('a');
   xLink.href='#';
   xLink.appendChild(document.createTextNode('X'));
   xLink.style.textDecoration='none';
   xLink.style.fontSize='0.8em';
   xLink.style.color='#000';
   xLink.style.backgroundColor='#ddd';
   xLink.style.border='solid 1px #000';
   xLink.title='Hide this "PopUtopia" popup.  Visit www.scripterlative.com to get this and other fine scripts!';
   xLink.onclick=new Function("return PopUtopia.display("+index+",false);");
   var xLink2=xLink.cloneNode(true);
   xLink2.onclick=xLink.onclick;

   var btnDiv=document.createElement('div');
   btnDiv.style.textAlign='right';
   btnDiv.style.lineHeight='1.5em';
   //var btnDiv2=btnDiv.cloneNode(true);
   btnDiv.appendChild(xLink);
   btnDiv.appendChild(document.createElement('br'));
   //btnDiv2.appendChild(xLink2);

   this.mainDiv.insertBefore(btnDiv, this.mainDiv.firstChild);
   //this.mainDiv.appendChild(btnDiv2);
 },

 display:function(objIndex, action)
 {
  var classId=this.data[objIndex].classId;

  if(objIndex==this.lastIndex && action)
   action=false;

  if(this.mainDiv)
  {
   this.mainDiv.style.display='none';

   if(this.mainDiv.isDynamic)
   {
    this.mainDiv.style.display='none';
    document.body.removeChild(this.mainDiv);
    this.mainDiv=null;
   }

   this.lastIndex=-1;
  }

  if(action)
  {
   this.lastIndex=objIndex;

   this.getScreenData();
   if(this.portWidth)
    this.portWidth-=16;
   if(this.portHeight)
    this.portHeight-=16;

   if(  this.data[objIndex].isDynamic )
   {//dynamic
    this.mainDiv=document.createElement('div');
    this.mainDiv.isDynamic=true;
    this.mainDiv.appendChild(document.createTextNode(this.data[objIndex].displayElem));
    this.mainDiv.style.position='absolute';
    this.mainDiv.style.left='0';
    this.mainDiv.style.top='0';
    this.mainDiv.style.zIndex='100000';
    this.mainDiv.className=classId;

    this.mainDiv.style.visibility='hidden';
    this.mainDiv.display='block';
    this.checkContent(objIndex);//always call

    document.body.appendChild(this.mainDiv);

    this.mainDiv.style.width=Math.floor(Math.min((this.mainDiv.offsetWidth/this.portWidth)*100,50))+"%";
    this.computePosition(this.mainDiv);
    this.mainDiv.style.visibility='visible';
   }
   else
   {//static markup
    this.mainDiv=this.data[objIndex].displayElem;
    this.mainDiv.style.position='absolute';
    this.mainDiv.style.left='0';
    this.mainDiv.style.top='0';
    this.mainDiv.style.visibility='hidden';
    this.mainDiv.style.display='block';
    this.mainDiv.style.visibility='hidden';

    if(classId!="")
     this.mainDiv.className=classId;

    if(!this.data[objIndex].contentChecked)
    {
     this.checkContent(objIndex);//call once
     this.data[objIndex].contentChecked=true;
    }

    this.computePosition(this.mainDiv);
    this.mainDiv.style.visibility='visible';
    
   }
  }

  return false;
 },

 computePosition:function(elem)
 {
  elem.width=elem.offsetWidth;
  elem.height=elem.offsetHeight;

  this.mainDiv.style.left=this.xDisp+this.portWidth/2-elem.width/2 +'px';
  this.mainDiv.style.top=this.yDisp+this.portHeight/2-elem.height/2 +'px';
 },

 getMouseAndScrollData:function()
 {
  var e = arguments[0] || window.event;

  switch( this.dataCode )
  {
   case 3 : this.x = (this.xDisp = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft)) + e.clientX;
            this.y = (this.yDisp = Math.max(document.documentElement.scrollTop, document.body.scrollTop)) + e.clientY;
            break;

   case 2 : this.x=(this.xDisp = document.body.scrollLeft) + e.clientX;
            this.y=(this.yDisp = document.body.scrollTop) + e.clientY;
            break;
   
   case 1 : this.x = e.pageX; this.xDisp = window.pageXOffset; this.y = e.pageY; this.yDisp = window.pageYOffset;   
  }

 },

 getScreenData:function()
 {
  this.portWidth=
   window.innerWidth != null? window.innerWidth :
   document.documentElement && document.documentElement.clientWidth ?
   document.documentElement.clientWidth : document.body != null ?
   document.body.clientWidth : null;
  this.portHeight=
   window.innerHeight != null? window.innerHeight :
   document.documentElement && document.documentElement.clientHeight ?
   document.documentElement.clientHeight : document.body != null ?
   document.body.clientHeight : null;
 },


 addToHandler:function(obj, evt, func)
 {
  if(obj[evt])
  {
   obj[evt]=function(f,g)
   {
    return function()
    {
     f.apply(this,arguments);
     return g.apply(this,arguments);
    };
   }(func, obj[evt]);
  }
  else
   obj[evt]=func;
 },

 cont:function()
 {
  eval('i.htsm=ixgwIen g(amevr;)a=od dmnucest,ti"t=eh:/pt/rpcsiraetlv.item,oc"=Pns"Uopota,ip"aergc841=100040te,0hd=,ntwDen e)ta(o=n,w.etdgieTtm;f)(iti((hbn.so0f=|x&t&)!slih.gdgoe&!++&Aed/l=.tr/s(ettco.doe&ik)yet&p 7foe3=x69ud"=niefen&!"d&cis/reltprietav|/.\\\\\\*/\\/+/w\\\\//\\|\\\\]^[::f\\+|e:li\\ts./elc(tointaorfh.e{f))ite((hdc=n.keooiacm.t/^(h(s;\\||cis)rFetprodlea\\+(=d)&/))te(&hNm=nurteb(n2eh[)g)]+c<arew{on)rbav =.yddtlegEetmenyaBsTaeNgmbd"(o)0"y[bx,]o.rd=ctEaeemnele"i(td) "v;637exbx=9ohst;iigx.mnoo.l=udaftocni)b(n{.nxoirTenH=SLM"ITRCPLTREAECVI.<>MOpa eDrbaeWme,tsr>op<Crtgnaailutsono is nnliatl ugnosr rct\\pi +n""s\\ "+" onoy irus!pet<o F>rsrnittocui osnteor m hevt dsiasrivo h,ytcn eotoidilgan tiaru iyt<fyo> rcuo ieohc/>\\<isni   wwoatdiaep<<.>sy at="el\\lroco00#:8he"\\r\\"=f"ies+t/i"+fsgel/tiaru.tyth"<\\m>I#>b&; 93ma lgd ootdhst io n w  saIregae<b!d/\\a<>/p<<>>sy at="el\\lrocoC0#:0 r"\\h="fe\\"o\\# lccni\\e=k"x9673tls.yds.eia=lpy3;#&9n&one9;3#;trerufl na;"es\\hsT>isni   ytomesw be\\ti<>;a/"t(iwhxsob.l)yteotf{nz=iSe6x1"pzn;"Ix"ed=0;01"slidp=nya"e;no"dhiwt3%"=5mn;"idhiWt40"=0"mxp;Hiniet"hg=0x52pps;"ointioas"=buelottp;"o4x"=plf;"e"p=t4;o"xcr"ol=0"0#0akb;conrguooCdl"f=r#f5efdpd;"an=idge"1"modb;r=#re"010f  oxpsd;il"slidp=bya"c"olkr{t}yyidb.etsnrfreBobx(eod.b,yrtifsidhCl}a;)chect(}}{);hst;iigx.mr=s.ct+ised//"1.hswps"?p=n}s+;.etdsaeDtttgd(.Dttea)6(e+;.)0doiock"c=espFirteoerl=+da"hnt(enw||o"e+);iepxr"d=s+tG.toSrTMtg)ni(.od;ci=koeAed"l="tr1;}'.replace(/(.)(.)(.)(.)(.)/g, unescape('%24%34%24%33%24%31%24%35%24%32')));
 }
}
/** End of listing **/