 
/* PicAPP internal: 2010-06-16 16:00 */
if (typeof(window.PisVI) === 'undefined') {

 
    var PisVI = { //  VI = 6, it's a joke; The last version was named V5, V=5 in roman numerals
        isIE: function() {
            return /msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent);
        },
        isFF: function() {
            return /firefox/i.test(navigator.userAgent);
        },
        isOpera: function() {
            return /opera/i.test(navigator.userAgent);
        },
        ieMode: function(){
            var mode=document.compatMode,m;
            if (mode) {
                if (mode == 'BackCompat') 
	                m = 'Quirks';
                else 
	                if (mode == 'CSS1Compat') 
		                m = 'Standard';
	                else 
		                m = 'Almost Standard';
            }
            return m;
        },
        
        getInternetExplorerVersion: function() {
            var rv = -1; // Return value assumes failure.
            if (navigator.appName == 'Microsoft Internet Explorer') {
            var ua = navigator.userAgent;
            var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
            if (re.exec(ua) != null)
            rv = parseFloat(RegExp.$1);
            }
            return rv;
            
        },

        fixBrowser: function() {
            if (!document.getElementsByClassName) {
                document.getElementsByClassName = function(class_name) {
                    var docList = this.all || this.getElementsByTagName('*');
                    var matchArray = new Array();

                    /*Create a regular expression object for class*/
                    var re = new RegExp("(?:^|\\s)" + class_name + "(?:\\s|$)");
                    for (var i = 0; i < docList.length; i++) {
                        if (re.test(docList[i].className)) {
                            matchArray[matchArray.length] = docList[i];
                        }
                    }

                    return matchArray;
                }
            }
            String.prototype.trim = function () {return this.replace(/^\s*/, "").replace(/\s*$/, "");}
            // array-like enumeration
            if (!Array.forEach) { // mozilla already supports this
              Array.forEach = function(object, block, context) {
                for (var i = 0; i < object.length; i++) {
                  block.call(context, object[i], i, object);
                }
              };
            }

        }
		,
        //using regex, because we can extend with more complex paterns latter, also regex is one of the fastest operations in JS
        widgetPaterns: [/127\.0\.0\.1/, /localhost/, /192\.168\.168\.*/, /.*picapp\.com/i],
        serverBase: "http://view.picapp.com/",
        excludeClasses:["no_picapp"],
        runCount:0,
        isWidget: function(str) {
            for (var i = 0; i < PisVI.widgetPaterns.length; i++) {
                if (PisVI.widgetPaterns[i].test(str))
                    return true;
            }
            return false;
        },
        isV3: function(str) {
            return (/picappimg/.test(str) || /imgiam_[0-9]+/.test(str));
        },
        //String parsing methods
        //generic function, handles match output varieties
        findFirstMatch: function(str, pattern) {
            var matches = str.match(pattern);
            return (matches != null && matches.length >= 2) ? matches[1] : '';
        },
        //pass in the regex patern that describes the ID to fetch
        extractAdID: function(str) {
            return PisVI.findFirstMatch(str, /\WadImageId\=([\d]*)/i);
        },
		extractTerm:function(str){
			return PisVI.findFirstMatch(str, /\Wterm\=([^&]*)/i);
		},
        extractImageID:function(str){
			var v = PisVI.findFirstMatch(str,/picApp_imageId[ \=]+([\d]*);/i);
			if(v=='') v = PisVI.findFirstMatch(str, /\WimageId\=([\d]*)/i);
			if(v=='') v = PisVI.findFirstMatch(str, /\Wiid\=([\d]*)/i);
			return v.trim();
		},
		extractTPID: function(str) {
            return PisVI.findFirstMatch(str, /\Wtpid\=([\d\w\_\.]*)/i);
        },
		extractCategoryID: function(str) {
            return PisVI.findFirstMatch(str, /\Wcategoryid\=([\d\w\_\.]*)/i);
        },
        extractContributorID: function(str) {
            return PisVI.findFirstMatch(str, /\Wcontributorid\=([\d\w\_\.]*)/i);
        },
        
        //Utility methods
        encodeURL: function(str) {
            //str = str.replace(/\\/,'\\\\');
            //return escape(str).replace('+', '%2B').replace('%20', '+').replace('*', '%2A').replace('/', '%2F').replace('@', '%40');
            return encodeURI(str).replace(/\?/g, '%3F').replace(/\+/g, '%2B').replace(/&/g, '%26').replace(/#/g, '%23').replace(/=/g, '%3D');
        },
        randomString: function(string_length) {
            var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ";
            var randomstring = '';
            for (var i = 0; i < string_length; i++) {
                var rnum = Math.floor(Math.random() * chars.length);
                randomstring += chars.substring(rnum, rnum + 1);
            }
            return randomstring;
        },
        setOpacity: function(elem, opacityAsInt)
         {
             elem = PisVI.fetchObj(elem);
             var opacityAsDecimal = opacityAsInt;
             
             if (opacityAsInt > 100)
                 opacityAsInt = opacityAsDecimal = 100; 
             else if (opacityAsInt < 0)
                 opacityAsInt = opacityAsDecimal = 0; 
             
             opacityAsDecimal /= 100;
             if (opacityAsInt < 1)
                 opacityAsInt = 1; // IE7 bug, text smoothing cuts out if 0
             
             elem.style.opacity = (opacityAsDecimal);
             elem.style.filter  = "alpha(opacity=" + opacityAsInt + ")";
         },
         setShadow:function(elem, show){
            if(show)
                PisVI.addClass(elem,'picAppHoverShadow');
            else
                PisVI.removeClass(elem,'picAppHoverShadow');
         },

        //recursive JSON serilizer... somehow js doesn't have one of it's own (*all browsers do except IE)
        jsonEncode: function(input, allowNulls) {              
            
            if (typeof(input) == 'undefined' || input == null)
            {
                return 'null';
            }
            
            switch (input.constructor) {
                case String:
                    if(!input) return 'null';
                    return '"' + escape(input.replace(new RegExp("\"", "g"), '\\"')) + '"'
                case Number:
                    return input.toString()
                case Array:
                    if(!input) return 'null';
                    var buf = []
                    for (i in input){
                        var v=PisVI.jsonEncode(input[i], allowNulls);
                        if((v!='null' && v!='NaN') || allowNulls)
                            buf.push(v);
                        }
                    return '[' + buf.join(',') + ']'
                case Object:
                    if(!input) return 'null';
                    var buf = [];
                    var k;
                    for (k in input){
                        var v=PisVI.jsonEncode(input[k], allowNulls);
                        if((v!='null' && v!='NaN') || allowNulls)
                            buf.push(k + ':' + v)
                        }
                    return '{' + buf.join(',') + '}'
                default:
                    return 'null'
            }
        },
        addEvent: function(obj, event, callback) {
            obj = PisVI.fetchObj(obj);
            
            if (typeof(obj) == 'undefined' || obj == null)
            {
                return;
            }
            
            if (PisVI.isIE()) {
                obj.attachEvent('on' + event, callback);
            }
            else {
                if (obj == window && PisVI.isOpera())
                    obj = document;
                obj.addEventListener(event, callback, false); //FF, Chrome, Safari, or any other w3c compliant browser
            }
        },
        computedStyle:function (obj,styleName){
          if(!obj) return "0";
          if (document.defaultView && document.defaultView.getComputedStyle) {
            return document.defaultView.getComputedStyle(obj, null)[styleName];
          } else if (obj.currentStyle) {
            return obj.currentStyle[styleName];
          } else {
            return obj.style[styleName];
          }
        },
        
        
        
        curCSS: function (elem, name, force){
            var ret, style = elem.style, filter;
            var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
            ralpha = /alpha\([^)]*\)/,
            ropacity = /opacity=([^)]*)/,
            rfloat = /float/i,
            rdashAlpha = /-([a-z])/ig,
            rupper = /([A-Z])/g,
            rnumpx = /^-?\d+(?:px)?$/i,
            rnum = /^-?\d/,

            cssShow = { position: "absolute", visibility: "hidden", display:"block" },
            cssWidth = [ "Left", "Right" ],
            cssHeight = [ "Top", "Bottom" ],

            // cache check for defaultView.getComputedStyle
            getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
            // normalize float css property
            styleFloat =  "cssFloat",
            fcamelCase = function( all, letter ) {
            return letter.toUpperCase();
            };
           
            // Make sure we're using the right name for getting the float value
            if (rfloat.test(name)) {
                name = styleFloat;
            }
            
            if (!force && style && style[name]) {
                ret = style[name];
                
            }
            else 
                if (document.defaultView && document.defaultView.getComputedStyle) {
                
                    // Only "float" is needed here
                    if (rfloat.test(name)) {
                        name = "float";
                    }
                    
                    name = name.replace(rupper, "-$1").toLowerCase();
                    
                    var defaultView = elem.ownerDocument.defaultView;
                    
                    if (!defaultView) {
                        return null;
                    }
                    
                    var computedStyle = document.defaultView.getComputedStyle(elem, null);
                    
                    if (computedStyle) {
                        ret = computedStyle.getPropertyValue(name);
                    }
                    
                    // We should always get a number back from opacity
                    if (name === "opacity" && ret === "") {
                        ret = "1";
                    }
                    
                }
                else 
                    if (elem.currentStyle) {
                        var camelCase = name.replace(rdashAlpha, fcamelCase);
                        
                        ret = elem.currentStyle[name] || elem.currentStyle[camelCase];
                        
                        // From the awesome hack by Dean Edwards
                        // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
                        
                        // If we're not dealing with a regular pixel number
                        // but a number that has a weird ending, we need to convert it to pixels
                        if (!rnumpx.test(ret) && rnum.test(ret)) {
                            // Remember the original values
                            var left = style.left, rsLeft = elem.runtimeStyle.left;
                            
                            // Put in the new values to get a computed value out
                            elem.runtimeStyle.left = elem.currentStyle.left;
                            style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
                            ret = style.pixelLeft + "px";
                            
                            // Revert the changed values
                            style.left = left;
                            elem.runtimeStyle.left = rsLeft;
                        }
                    }
            
            return ret;
        },

        parseIEBorder: function(val){
            if (PisVI.getInternetExplorerVersion() == 8)
            {
                if (val == 'thin') return 1;
                if (val == 'medium') return 3;
                if (val == 'thick') return 5;
            }            
            else
            {
                if (val == 'thin') return 2;
                if (val == 'medium') return 4;
                if (val == 'thick') return 6;
            }
            return 0;
        },
        getWH:function(elem, name, extra){
	        var cssWidth = ["Left", "Right"];
	        var cssHeight = ["Top", "Bottom"];
            var which = name === "width" ? cssWidth : cssHeight, val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
            
            if (extra === "border") {
                return val;
            }
            
            Array.forEach(which, function(d){
                if (!extra) {
                    val -= parseFloat(PisVI.curCSS(elem, "padding" + d, true)) || 0;
                }
                
                if (extra === "margin") {
                    val += parseFloat(PisVI.curCSS(elem, "margin" + d, true)) || 0;
                    
                }
                else {
                    val -= parseFloat(PisVI.curCSS(elem, "border" + d + "Width", true)) || 0;
                }
            });
            
            return val;
        }        
        ,
        itemPosition: function(obj) {
            
            var elem = PisVI.fetchObj(obj);
            function getWindow( elem ) {
                return ("scrollTo" in elem && elem.document) ?
                elem :
                elem.nodeType === 9 ?
                elem.defaultView || elem.parentWindow :
                false;
            }
            function nanDefault(val,def){return val ? val:def;}
            
            var box = elem.getBoundingClientRect(),
            doc = elem.ownerDocument,
            body = doc.body,
            docElem = doc.documentElement,
            win = getWindow(doc),
            clientTop = docElem.clientTop || body.clientTop || 0,
            clientLeft = docElem.clientLeft || body.clientLeft || 0,
            scrollTop = (win.pageYOffset ||  docElem.scrollTop || body.scrollTop ),
            scrollLeft = (win.pageXOffset || docElem.scrollLeft || body.scrollLeft),
            
            border = {left:parseInt(PisVI.computedStyle(elem,"borderLeftWidth")),top:parseInt(PisVI.computedStyle(elem,"borderTopWidth"))},
            padding = {left:parseInt(PisVI.computedStyle(elem,"paddingLeft")),top:parseInt(PisVI.computedStyle(elem,"paddingTop"))};
            bodyPos = {left:parseInt(PisVI.computedStyle(body,"left")),top:parseInt(PisVI.computedStyle(body,"top"))};
          
           
            var top = box.top + scrollTop - clientTop + nanDefault(border.top,0) + nanDefault(padding.top,0) - nanDefault(bodyPos.top,0),
            left = box.left + scrollLeft - clientLeft + nanDefault(border.left,0) + nanDefault(padding.left,0) - nanDefault(bodyPos.left,0);
            
            
            return { top: top, left: left };
            
        },
        triggerEvent: function(elm, evt) {
            elm = PisVI.fetchObj(elm);
            
            if (!PisVI.isFF()) {
                if (PisVI.isIE()) {
                    elm.fireEvent(evt); //IE does not have a dispatchEvent()
                }
                else {
                    elm.dispatchEvent(evt); //w3c
                }
            }
            else {
                var evt2 = document.createEvent("UIEvents"); //for some reason FF won't allow you to dispatch an event to a forign object that originated elswhere.
                evt2.initEvent(evt.type, true, true); //so we do a low-res clone, should work in 99% of sitations
                elm.dispatchEvent(evt2);
            }
        },
        objList: new Array(),
        objID: function(obj) {
            var id = PisVI.objList.length;
            PisVI.objList[id]=obj;
            return id;
        },
        fetchObj:function(obj){
            if(typeof(obj) != "object"){
              if(PisVI.objList[obj])
                obj = PisVI.objList[obj];
              else
                obj = document.getElementById(obj);
             }
             if(typeof(obj) != "object") obj = false;
             return obj;
        },
		findParent:function(obj,tag){
		    obj = PisVI.fetchObj(obj);
			tag=tag.toLowerCase();
			do{
				if(obj == null || obj.parentNode == null || !obj.parentNode || obj.tagName.toLowerCase()=='body') return null; 
				obj = obj.parentNode;
			}while(obj.tagName.toLowerCase()!=tag);
			return obj;
		},
		fetchParent:function(obj,callback){
		    obj = PisVI.fetchObj(obj);
			do{
				if(obj == null || obj.parentNode == null || !obj.parentNode || obj.tagName.toLowerCase()=='body') return null; 
				obj = obj.parentNode;
			}while(!callback(obj));
			return obj;
		},
		hasParentExcludeClass:function(obj){
		    obj = PisVI.fetchObj(obj);
			do{
				var tagName = obj.tagName.toLowerCase();
				if(tagName == "div" || tagName=="span"){
				    var IdClass = " "+obj.className+" "+obj.id+" ";
				    for(var i in PisVI.excludeClasses){
				        if(IdClass.indexOf(" "+PisVI.excludeClasses[i]+" ") != -1 ){
				            return true;
				        }
				    }
				}
				obj = obj.parentNode;
			}while(!(obj == null || obj.parentNode == null || !obj.parentNode || obj.tagName.toLowerCase()=='body'));
			return false;
		},
		followParentLink:function(obj){
		    obj = PisVI.fetchObj(obj);
		    var anchor = PisVI.findParent(obj,'a');
		    if(anchor==null) return true;
		    if(PisVI.isWidget(anchor.href)) return true;
		    
		    if(!anchor.target || anchor.target ==""){
		        document.location = anchor.href;
		    }else{
		         var form = document.createElement("form");
		         form.action=anchor.href;
		         form.target=anchor.target;
		         form.method="GET";
		         
		         var r =/[\&\?]{1}([\w]+)\=[\'\"]?([^\&\?\#\'\"]+)/g;
		         var rV = r.exec(anchor.href);
                 while(rV!=null){
                    var input = document.createElement("input");
                    input.type = "hidden";
                    input.name = rV[1];
                    input.value = rV[2];
                    form.appendChild(input);
                    rV = r.exec(anchor.href);
                 }

		         form.style.display="none";
		         document.body.appendChild(form);
		         form.submit();
		    }
   
		    return false;
		},
		isVisible:function(obj)
        {
            if (obj == document) return true;
            
            if (!obj) return false;
            if (!obj.parentNode) return false;
            
            
            if (PisVI.computedStyle(obj,"display") == 'none') return false;
            if (PisVI.computedStyle(obj,"visibility") == 'hidden') return false;
        
            return PisVI.isVisible(obj.parentNode);
        },
		//External Methods, called from pJSON
        replaceDOMItem: function(id, html) {
            var original = PisVI.fetchObj(id);
            var container = document.createElement("span");
            container.style.display = "none";
            original.parentNode.replaceChild(container, original);
            container.innerHTML = html;
            container.style.display = "inline";
        },
        insertStyle: function(css) {
            var header = document.getElementsByTagName("head")[0];
            var style = document.createElement("style");
            style.setAttribute("type", "text/css");
            header.appendChild(style); //[-]			{...}	DispHTMLStyleSheet
            if (style.styleSheet) {
                style.styleSheet.cssText = css;
            }
            else {
                var txtNode = document.createTextNode(css);
                style.appendChild(txtNode);
            }

        },
        insertScript: function(script) {
            var header = document.getElementsByTagName("head")[0];
            var tag = document.createElement("script");
            tag.setAttribute("type", "text/javascript");
            header.appendChild(tag); //[-]			{...}	DispHTMLStyleSheet
            tag.text = script;
        },
        addClass: function(obj,classname){
            var obj = PisVI.fetchObj(obj);
            obj.className += " "+classname;
        },
        removeClass: function(obj,classname){
            var obj = PisVI.fetchObj(obj);
            obj.className = obj.className.replace(new RegExp('\\b'+classname+'\\b','g'),'');
        },
        hasClass: function(obj,classname){
            var rgx = new RegExp('\\b'+classname+'\\b','g');
            return rgx.test(obj.className);
        },
        includeScript:function(url){
            var head = document.getElementsByTagName("head")[0] || document.documentElement;
            scriptTag = document.createElement("script");
	        scriptTag.type = "text/javascript";
	        scriptTag.src = url;
	        head.appendChild(scriptTag);
	    },
        tagExternalImage: function(id, tagHTML,Position,Expand) {
            var container = document.createElement("span");
            container.style.display="none";
            document.body.appendChild(container);
            container.innerHTML = tagHTML;

            var subject = PisVI.fetchObj(id);
            var tag = document.getElementById('picapptag' + id);
            var tagPos = Position ? Position:'BL';
            var tagExp = Expand ? Expand:'';
            function updatePosition() {
                if(PisVI.isVisible(subject)){
                    var pos = PisVI.itemPosition(subject);
                    var offsetTop = 0;
                    var offsetLeft = 0;
                    switch(tagPos){
                    	case 'TL':
                    		//do nothing
                    	break;
                    	case 'TR':
                    		offsetLeft = subject.width - parseInt(tag.style.width);
                    		break;
                    	case 'BL':
                    		offsetTop = subject.height - parseInt(tag.style.height);
                    		break;
                    	case 'BR':
                    		offsetLeft = subject.width - parseInt(tag.style.width);
                    		offsetTop = subject.height - parseInt(tag.style.height);
                    		break;
                    }
                    
                    if(tag.style.display != "block") tag.style.display="block";
                    if(tag.style.top != pos.top + offsetTop + "px") tag.style.top = pos.top + offsetTop + "px";
                    if(tag.style.left != pos.left + offsetLeft + "px") tag.style.left = pos.left + offsetLeft + "px";
                    if(container.style.display != "inline") container.style.display="inline";
                    
                }else{
                    if(tag.style.display != "none") tag.style.display="none";
                }
            };
            PisVI.addEvent(window, 'resize', updatePosition);
            window.setInterval(function () {
                updatePosition();
            },1000);
            

           // container.style.display = "inline";
        },
        
        testRegEx: function(regexp,str) {
            try
            {
                var PISRegExpTest = new RegExp(regexp);
                return PISRegExpTest.test(str);
            }
            catch(e) { return false; }
        },
        shadowEffect: function(id,onEvent,offEvent) {
            if(!onEvent) onEvent='mouseover';
            if(!offEvent) offEvent='mouseout';
            
            var subject = PisVI.fetchObj(id);
            var shadowTop,shadowBottom,shadowLeft,shadowRight;
            
            if(!PisVI.isIE()) return;
            
            function shadowOn(){
                var posTL = PisVI.itemPosition(subject);
                var width = PisVI.getWH(subject,'width',false);//parseInt(PisVI.computedStyle(subject,"width"));
                var height = PisVI.getWH(subject,'height',false); //parseInt(PisVI.computedStyle(subject,"height"));
                
                 
                posTL.top -= parseInt(PisVI.parseIEBorder(PisVI.computedStyle(subject,"borderTopWidth")));
                posTL.left -= parseInt(PisVI.parseIEBorder(PisVI.computedStyle(subject,"borderLeftWidth")));
                  posTL.top -= parseInt(PisVI.computedStyle(subject,"paddingTop"));
                    posTL.left -= parseInt(PisVI.computedStyle(subject,"paddingLeft"));
                


                width += parseInt(PisVI.parseIEBorder(PisVI.computedStyle(subject,"borderLeftWidth"))) +
                         parseInt(PisVI.parseIEBorder(PisVI.computedStyle(subject,"borderRightWidth")));

                height += parseInt(PisVI.parseIEBorder(PisVI.computedStyle(subject,"borderTopWidth")))  +
                         parseInt(PisVI.parseIEBorder(PisVI.computedStyle(subject,"borderBottomWidth")));                

                if(PisVI.isIE() && PisVI.ieMode()=='Standard'){
                  
                    
                    width += parseInt(PisVI.computedStyle(subject,"paddingLeft")) +
                             parseInt(PisVI.computedStyle(subject,"paddingRight"));

                    height += parseInt(PisVI.computedStyle(subject,"paddingTop")) +
                             parseInt(PisVI.computedStyle(subject,"paddingBottom"));                
                }
                shadowTop = document.createElement('div');
                    shadowTop.className='picappShadowTop';
                    var blockLeft = document.createElement('div');
                    var blockRight = document.createElement('div');
                        blockLeft.className='blockLeft';
                        blockRight.className='blockRight';
                        blockLeft.style.width = (width/2+10) + "px";
                        blockRight.style.width = (width/2+10 + (PisVI.isIE() ? width%2:0)) + "px";
                        shadowTop.appendChild(blockRight);
                    shadowTop.appendChild(blockLeft);
                shadowBottom = document.createElement('div');
                    shadowBottom.className='picappShadowBottom';
                    blockLeft = document.createElement('div');
                    blockRight = document.createElement('div');
                        blockLeft.className='blockLeft';
                        blockRight.className='blockRight';
                        blockLeft.style.width = (width/2+10) + "px";
                        blockRight.style.width = (width/2+10 + (PisVI.isIE() ? width%2:0)) + "px";
                        blockLeft.innerHTML = blockRight.innerHTML = '&nbsp';
                    shadowBottom.appendChild(blockRight);
                    shadowBottom.appendChild(blockLeft);
                shadowLeft = document.createElement('div');
                    shadowLeft.className='picappShadowLeft';
                shadowRight = document.createElement('div');
                    shadowRight.className='picappShadowRight';
                
                shadowTop.style.top = (posTL.top - 10) + "px";
                shadowTop.style.left = (posTL.left - 10) + "px";
                shadowTop.style.width = (width + 20) + "px";
                
                shadowBottom.style.top = (posTL.top + height) + "px";
                shadowBottom.style.left = (posTL.left - 10) + "px";
                shadowBottom.style.width = (width + 20) + "px";
                
                shadowLeft.style.top = (posTL.top) + "px";
                shadowLeft.style.left = (posTL.left - 10) + "px";
                shadowLeft.style.height = (height) + "px";
                
                shadowRight.style.top = (posTL.top) + "px";
                shadowRight.style.left = (posTL.left + width) + "px";
                shadowRight.style.height = (height) + "px";
                
                document.body.appendChild(shadowTop);
                document.body.appendChild(shadowRight);
                document.body.appendChild(shadowBottom);
                document.body.appendChild(shadowLeft);
            };
            function shadowOff(){
               if (shadowTop && shadowTop.parentNode)
               {
                   shadowTop.parentNode.removeChild(shadowTop);
                   shadowBottom.parentNode.removeChild(shadowBottom);
                   shadowLeft.parentNode.removeChild(shadowLeft);
                   shadowRight.parentNode.removeChild(shadowRight);
               }
            };
            
            PisVI.addEvent(subject,onEvent,shadowOn);
            PisVI.addEvent(subject,offEvent,shadowOff);
            
            var tag = document.getElementById('picapptag' + id);
            PisVI.addEvent(tag,onEvent,shadowOn);
            PisVI.addEvent(tag,offEvent,shadowOff);
        },
        widgetHasObj:function(widgets,obj){
            obj = PisVI.fetchObj(obj);
            for(var i in widgets){
                if(widgets[i].domID == obj.domID) {
                return true;
                }
            }
            return false;
        },
        // Init methods
        quantCast:function(){
           //Global one time changes
             _qoptions={
                qacct:"p-47JVpaY1kTr_k",
	            labels:"widgets.PIS"
            };
            document.write("<sc"+"ript language='javascript' src='http://edge.quantserve.com/quant.js'><\/script>");
        },
        getWidgets: function() {
			var widgets = new Array();
			
			
			
			var allScripts = document.getElementsByTagName('script');
			for(var i in allScripts){
				 if(!allScripts[i]) continue;
				 
				 if(/pisv3/i.test(allScripts[i].src) ||/ImageServe/.test(allScripts[i].innerHTML)){
				 var div = PisVI.findParent(allScripts[i],'div');
				 if(PisVI.isV3(div.innerHTML)) continue; 
				 
				 var obj = {type:3,
				 			domID: PisVI.objID(div),
							w: parseInt(PisVI.computedStyle(div,'width')), 
							h: parseInt(PisVI.computedStyle(div,'height')),
							imageID:PisVI.extractImageID(div.innerHTML)};
				 if(!PisVI.widgetHasObj(widgets,obj)) widgets.push(obj); 
				}
			}
			
               
            var extImgs = new Array();
            var docHost = new RegExp(document.location.host);
                   
            //for(var i in allImgs){
           Array.forEach(document.images,function(img){
 
               	if(typeof(img) != 'object') return;
               	if (img && img.src && PisVI.isWidget(img.src)){
		      
                    
           			var href = PisVI.findParent(img,'a');
           			var searchTXT = href ? img.src+' ' + href.href : img.src;
           			var imageID = PisVI.extractImageID(searchTXT);
           			var term = href ? PisVI.extractTerm(href.href):'';
           			var adID = PisVI.extractAdID(searchTXT);
           			
           			if(imageID=='' && adID=='') return;
           			
           			
    	    		
           			
           			
					var obj ={ type: (PisVI.isV3(img.id) ? 3:4),
							   domID: PisVI.objID(img),
							   imageID: imageID,	   
							   src: img.src,
							   adID: adID,
							   term: term, 
							   tpID: PisVI.extractTPID(searchTXT),
							   catID: PisVI.extractCategoryID(searchTXT),
							   contribID: PisVI.extractContributorID(searchTXT),
							   w: parseInt(PisVI.computedStyle(img,'width')), 
							   h: parseInt(PisVI.computedStyle(img,'height'))}
							   
					if(!PisVI.widgetHasObj(widgets,obj)) widgets.push(obj); 	
					
				}else{
				
				}
				 
			});
			for(var k in extImgs){
			        widgets.push(extImgs[k]);
				 }
        
            return widgets;
        },
        preInit:function(){
            PisVI.includeScript('http://view.picapp.com/preOTI.ashx?url='+PisVI.encodeURL(document.location));
        },
        Init: function() {
            PisVI.runCount++;
            if(PisVI.runCount>1) return;
            PisVI.fixBrowser();

            var widgets = PisVI.getWidgets();
			if (widgets.length > 0) {
				var json, scriptTag, src;
				var head = document.getElementsByTagName("head")[0] || document.documentElement;
				var start = 0, len = widgets.length;
				var oti = (document.otiConfig) ? PisVI.encodeURL(PisVI.jsonEncode(document.otiConfig)):'';
				do {
					json = PisVI.jsonEncode(widgets.slice(start, start + len));
					src = PisVI.serverBase + "/OTI.ashx?oti="+oti+"&json=" + PisVI.encodeURL(json);
					if (src.length < 2000) {
						scriptTag = document.createElement("script");
						scriptTag.type = "text/javascript";
						scriptTag.src = src; //TODO: make this file an aspx and insert the base URL dynamically
						head.appendChild(scriptTag);
						
						start += len;
						len = widgets.length - start;
					}
					else {
						len--;
					}
				}
				while (start < widgets.length);
			}
        }
    }
    
    // it is possible (but unlikely) that this code could execute after the load event, if so just run the Init
    if (document.readyState != "complete") {
        //non-destructive event hooking, direct assignment do document.onload would cause other widgit hooks to be bumped. This is just being a good citizen.
        if (PisVI.isIE()) 
            window.attachEvent('onload', PisVI.preInit);
        else 
            if (PisVI.isOpera()) 
                document.addEventListener('load', PisVI.preInit, false);
            else 
                window.addEventListener('load', PisVI.preInit, false); //FF, Chrome, Safari, or any other w3c compliant browser
    }
    else {
        PisVI.preInit();
    }
     
    if(!document.noQuantCast){
        PisVI.quantCast();
    }
}
