/*
 * Author: Patrick Henderson path2727@gmail.com
 * March 2011
 *
 */




// Before we start trying to define carousel...
// see if it is already defined.
if( window.Carousel === undefined ) {

/**
 * This function might already be defined.
 * it sets the scope of a callback function and passes predefined
 * arguments.
 */
if (!Function.prototype.bind) { // check if native implementation available
        Function.prototype.bind = function(){
                var fn = this, args = Array.prototype.slice.call(arguments),
                object = args.shift();
                return function(){
                        return fn.apply(object,
                                        args.concat(Array.prototype.slice.call(arguments)));
                };
        };
}


/**
 * Constructor for the carousel.
 * 
 * Creates a new Carousel instance.
 *
 * @param {String or HTMLElement} div (Required) the id of the container div or the div object.
 * @param {Object} conf (Not required) a JSON object with configuration settings.
 * @param {Object} items (Not required) an array of the items to displaye.
 */
window.Carousel = function( div, conf, items ) {
	// Initialize element.
	if (typeof div == "string") {
		this.id = div;
		var el2 = document.getElementById( div );
		if( !def(el2) ) {
			log("element was undefined:"+div);
			el2 = document.createElement("div");
			el2.setAttribute("id", div );
			bd.appendChild( el2 );
		}
		this.element = el2;
	} else {
		if( def(div) ) {
			this.id = div.id;
			this.element = div;
		} else {
			log("Div is undefined");
		} 
	}
	if( def( conf ) ) {
		this.conf = conf;
	}
	if( def( items ) ) {
		this.items = items;
	}
	// Initialize the carousel object.
	this.init();
}; // window.Carousel.constructor



// Used to configure the carousel. 
// This is the value denoting that the carousel should be horizontal.
Carousel.horizontal = 999;
// This is the value denoting that the carousel should be vertical.
Carousel.vertical = 987;



/**
 * Object definition for a carousel object.
 */
window.Carousel.prototype = {
	/** String id of the main div for the carousel. */
	id: null,
	/** HTMLElement of the main div. */
	element: null,
	/** The configuration passed into the constructor. */
	conf: null,
	/** An array of item configurations. */
	items: null,
	/** An array of {HTMLElement} which contains the 'li' to move. */
	li: [],
	/** {HTMLElement} The 'UL' element inside the main div. */
	ul: null,
	/** {HTMLElement} of the Logo div. */
	logo: null,

	showCount: false,
	showCountNum: 1,
	showCountDiv: null,

	time1: null,
	time2: null,

	videos: new Array(),

	textDiv: null,

	oldWidth: -1,

	visible: true,

	/** TODO: populate the x position. */
	x: null,
	/** TODO: populate the y position. */
	y: null,
	middle: 0,
	/** Local helper variable denoting carousel should be horizontal. */
	horizontal: 999,
	/** Local helper variable with the value denoting the carousel should be vertical. */
	vertical: 987,
	/** {HTMLElement} of the next div. */
	next: null,
	/** {HTMLElement} of the prev div. */
	prev: null,
	pause: null,
	/** Value denoting that the left button has been pushed. */
	left: 0,
	/** Value denoting that the right button has been pushed. */
	right: 1,
	/** Value denoting that the up button has been pushed. */
	up: 2,
	/** Value denoting that the down button has been pushed. */
	down: 3,
	/** If this is true, we either set the carousel width to the parentNode width or the document width. */
	fullWidth: false,
	/** The leftmost or upper most item in the carousel. */
	leftEnd: null,
	/** The rightmost or lower most item in the carousel. */
	rightEnd: null,
	current: 0,
	oldCurrrent: 0,
	moveAnimation: false,
	changeTimer: null,
	opacityAnimation: false,
	/**
	 * Initialzies the application.
	 */
	init: function() {
		log("Carousel.init");
		// Default the configuration.
		this.defaultConf();
		log("conf:"+dump(this.conf) );
		log("init:"+this.element.id);
		this.li = new Array();
		// Initialize the document object model.
		this.initDOM();
		log("style:"+dump(this.element.style) );
		
		if( this.conf.changeTime > 0 ) {
			var t = this;
			setTimeout( function() {
			t.changeTimer = setInterval( function() {
				if( t.conf.orientation = Carousel.horizontal ) {
					t.moveRight(); 
				} else {
					t.moveUp();
				}
			}, t.conf.changeTime );
			}, 500 );
		}

	}, // init
        showByHeight: function() {
                if( !this.visible ) {
                        this.element.style.height = this.conf.panelHeight+"px";
                        this.element.style.marginBottom = "0px";
                        this.showDivs();
                        this.visible = true;
                }
        },
        hideByHeight: function() {
                if( this.visible ) {
                        this.element.style.height = "0px";
                        this.element.style.marginBottom = "100px";
                        this.visible = false;
                }
        },


	pauseAll: function() {
		alert("pause all");
	},
	/**
	 * This defaults the configuration.
	 * If the user doesn't provide certain configuration
	 * values, we default them here.
	 */
	defaultConf: function() {
		log("defaultConf");
		if( !def(this.conf) ) {
			this.conf = {};
		}
		if( !def( this.conf.logo) ) {
			this.conf.logo = false;
		}

		if( !def(this.conf.opacity) ) {
			this.conf.opacity = false;
		}
		if( !def(this.conf.moveAnimation) ) {
			this.moveAnimation = false;
		} else {
			this.moveAnimation = true;
		}

		if( !def( this.conf.opacityAnimation ) ) {
			this.opacityAnimation = false;
		} else {
			this.opacityAnimation = true;
		}

		if( !def( this.conf.changeTime ) ) {
			this.conf.changeTime = 0;
		}
		

		if( !def(this.conf.mutedVideos) ) {
			this.conf.mutedVideos = false;
		}

		if( !def( this.conf.logoWidth ) ) {
			this.conf.logoWidth = 300;
		}
		if( !def( this.conf.logoHeight ) ) {
			this.conf.logoHeight = 90;
		}
		if( !def( this.conf.panelWidth ) ) {
			this.conf.panelWidth = 200;
		}
		if( !def( this.conf.scrollWait ) ) {
			this.conf.scrollWait = 50;
		}

		if( this.conf.scrollWait < this.conf.moveAnimation ) {
			this.conf.scrollWait = this.conf.moveAnimation+(this.conf.moveAnimation/2);
		}
		var pos = getPosition(this.element);
		if( !def(this.conf.x) ) {
			this.conf.x = pos[0];
		}
		if( !def(this.conf.wait) ){
			this.conf.wait = true;
		}
		if( !def(this.conf.y) ) {
			this.conf.y = pos[1];
		}
		if( def(this.conf.showCount) && this.conf.showCount == true ) {
			if( !def(this.conf.showCountDiv) ) {
				alert("No showCountDiv");
			} else {
				var tscd = document.getElementById(this.conf.showCountDiv);
				if( tscd !== undefined ) {
					this.showCountDiv = tscd;
				} else {
					alert("couldn't find "+this.conf.showCountDiv);
				}
			}
		}
		if( def(this.conf.textDiv) ) {
			var textDiv = document.getElementById(this.conf.textDiv);
			if( def(textDiv) ) {
				this.textDiv = textDiv;
			}
		}
		if( !def(this.conf.centered) ) {
			this.conf.centered = false;
		}
		if( !def(this.conf.moveArrows) ) {
			this.conf.moveArrows = false;
		}
		if( !def(this.conf.auto) ) {
			this.conf.auto = false;
		}
		if( !def(this.conf.scroll) ) {
			this.conf.scroll = 1;
		}
		if( !def(this.conf.orientation) ) {
			this.conf.orientation = this.horizontal;
		}
		if( !def(this.conf.panelHeight) ) {
			this.conf.panelHeight = 200;
		}
		if( !def( this.conf.carouselWidth ) ) {
			if( this.conf.orientation == this.horizontal ) {
			this.conf.carouselWidth = 600;
			} else {
				this.conf.carouselWidth = 200;
			}
		} else {
			if( this.conf.carouselWidth == "100%" ) {
				this.fullWidth = true;
				//alert(this.element.parentNode.style.width);
				if( !def(this.element.parentNode.style.width) || this.element.parentNode.style.width == "" ) {
					log("page width");
					this.conf.carouselWidth = getWidth();
				} else {
					this.conf.carouselWidth = stripPx(this.element.parentNode.style.width);
				}
				//window.onresize = this.repos.bind(this,"test");
				addRepos( this.repos.bind( this, "test" ) );
			}
		}
		if( !def( this.conf.carouselHeight ) ) {
			if( this.conf.orientation == this.horizontal ) {
			this.conf.carouselHeight = 200;
			} else {
				this.conf.carouselHeight = 600;
			}
		}
	}, // defaultConf
	initLogo: function() {
                if( def(this.conf.logo) && this.conf.logo ) {
                        // Initialize logo.
                        this.logo = childClass( this.element, "logo");
                        if( this.logo ) {
                                log("logo found");
                        } else {
                                log("logo not found");
                                this.logo = document.createElement("div");
                                this.logo.setAttribute("class", "logo");
				// Make onclick go to main.
                                this.logo.setAttribute("onclick", "Kali.getContent('content', 'main', '', 480, Kali.mainHandler ); return false;");
				// Change the background image.

	                        this.logo.style.width = this.conf.logoWidth+"px";
                                this.logo.style.background = "url("+this.conf.logoImage+") 0 0 no-repeat";
                                this.logo.style.height = this.conf.logoHeight+"px";

                                log("logo2");

				// Change mouse to pointer.
                                this.logo.style.cursor = "pointer";
				// User can't select.
        	        	this.logo.style.userSelect = "none";
	                	this.logo.style.MozUserSelect = "none";
        		        this.logo.style.KhtmlUserSelect="none";
		                this.logo.style.WebkitUserSelect = "none";

                                log("logo3");

                                this.element.appendChild( this.logo );
                        }
                }
	},
	initUL: function() {
                // Initialize the UL.
                var ulElements = childElement( this.element, "UL");
                if( ulElements !== false ) {
                        log("ul found:"+this.id);
                        this.ul = ulElements;

	                if( (!def(this.ul.style.width) || this.ul.style.width == "" ) && def(this.conf.carouselWidth) ) {
        	                log("default width set");
                	        this.ul.style.width = this.conf.carouselWidth+"px";
	                }
        	        if( (!def(this.ul.style.height) || this.ul.style.height == "" ) && def(this.conf.carouselHeight) ) {
                	        log("default height set");
                        	this.ul.style.height = this.conf.carouselHeight+"px";
	                }

        	        this.ul.style.position = "relative";
                	var liElements = childElement( this.ul, "LI");
	                if( liElements ) {
        	                log("li found");
                	        this.li = liElements;
                        	for( var i = 0; i < this.li.length; i++ ) {
                                	var tli = this.li[i];
	                                tli.style.listStyleType = "none";
        	                        tli.style.width = this.conf.panelWidth+"px";
                	                tli.style.height = this.conf.panelHeight+"px";
					if( this.conf.opacity ) {
	
					}
	                        }
        	        } else {
                	        alert("li not found");
	                }
                } else {
                        log("ul not found:"+this.id);
                        if( def(this.items)) {
                                // Create the UL.
                                this.ul = document.createElement("ul");
                                this.ul.style.position = "relative";

		                if( (!def(this.ul.style.width) || this.ul.style.width == "" ) && def(this.conf.carouselWidth) ) {
                		        log("default width set");
		                        this.ul.style.width = this.conf.carouselWidth+"px";
                		}
		                if( (!def(this.ul.style.height) || this.ul.style.height == "" ) && def(this.conf.carouselHeight) ) {
                		        log("default height set");
		                        this.ul.style.height = this.conf.carouselHeight+"px";
		                }
                                this.element.appendChild( this.ul );
                                log("items length:"+this.items.length+"this.li.length:"+this.li.length );
                                for( var i = 0; i < this.items.length; i++ ) {
                                        // Create the LI.
                                        log("t");
                                        var item = this.items[i];
                                        log("this.id:"+this.id);
                                        this.li[i] = document.createElement("li");

					this.li[i].style.position = "absolute";
					if( i < this.items.length/2 ) {
	                                        this.li[i].style.left = (zero(this.position())+(this.conf.panelWidth*i))+"px";
					} else {
						this.li[i].style.left = (zero(this.position())-((this.items.length-i)*this.conf.panelWidth))+"px";
					}


					this.li[i].style.zIndex = 410;
                                        log("item type:"+item.type );
                                        if( item.type == "image" ) {
                                                // Create link.
                                                var anchor = document.createElement("a");
                                                //anchor.href = item.url;
                                                anchor.setAttribute("onclick", item.onclick);
                                                // Create image.
                                                var image = document.createElement("img");
                                                image.setAttribute("src",item.file);

						
                                                image.setAttribute("width", this.conf.panelWidth+"px");
                                                image.setAttribute("height", this.conf.panelHeight+"px");

						                                // User can't select.
		                                image.style.userSelect = "none";
                		                image.style.MozUserSelect = "none";
		                                image.style.KhtmlUserSelect="none";
                		                image.style.WebkitUserSelect = "none";
						// Update to make image have hand 
                		                image.style.cursor = "pointer";


                                                log("image.getAttribute(\"src\"):"+image.getAttribute("src") );
                                                // Append img to a.
                                                anchor.appendChild( image );
                                                // Append anchor to li.
                                                this.li[i].appendChild( anchor );
					} else if( item.type == "ad" ) {
						log("ad");
						if( def( item.contentDiv ) ) {
							log("content div set");
							var contentDiv = document.getElementById( 
								item.contentDiv 
							);
							if( def(contentDiv) ) {
								log("contentDiv not defined");
								this.li[i].innerHTML = contentDiv.innerHTML;
							}
						}
						if( def( item.url ) ) {
							this.li[i].setAttribute(
								"onclick", 
								"window.location.href = '"+item.url+"';"
							);
						}

					} else if( item.type == "video" ) {

						if( ie ) {
		                                        var d = document.createElement("div");
                		                        d.setAttribute("id", "video-"+i);
                                		        this.li[i].appendChild( d );
						} else {
							var video = document.createElement("video");
							video.setAttribute("id", "video-"+i);
							//video.setAttribute("style", "margin-left: 210px; margin-top: 120px;");
							if( this.conf.panelWidth > 1200 ) {
								video.setAttribute("style", "margin-left: "+((this.conf.panelWidth-1200)/2)+"px");
							}
							video.setAttribute("preload", "auto" );
							video.setAttribute("autobuffer", "true");
							video.setAttribute("poster", item.image );

							if( !chrome ) {
                                                        var source3 = document.createElement("source");
                                                        source3.setAttribute("type","video/mp4");
                                                        source3.setAttribute("src", item.mp4 );
                                                        video.appendChild( source3 );
							}
							if( !firefox ) {
							var source = document.createElement("source");
							source.setAttribute("src", item.ogv );
							source.setAttribute("type", "video/ogg");
							video.appendChild( source );
							}
						
							var source2 = document.createElement("source");
							source2.setAttribute("type","video/quicktime");
							source2.setAttribute("src", item.mov );
							video.appendChild( source2 );

                                                        var source4 = document.createElement("source");
                                                        source4.setAttribute("type","video/flv");
                                                        source4.setAttribute("src", item.flv );
                                                        video.appendChild( source4 );

                                                        var source5 = document.createElement("source");
                                                        source5.setAttribute("src", item.ogg );
                                                        source5.setAttribute("type", "video/ogg");
                                                        video.appendChild( source5 );



							var txtNode = document.createTextNode("Your browser does not support the video tag.");
							video.appendChild( txtNode );

							this.li[i].appendChild( video );
			
                var t = this;
                var c = this.conf;	
							video.addEventListener( "ended", function( e ) {
								video.currentTime = 0;
								video.play();
								if( def(c.mutedVideos) && c.mutedVideos ) {
									video.volume = 0;
								}
							}, false );
						}
                                        } else {
                                                this.li[i].innerHTML =item.type;
                                        }

                                        this.li[i].style.listStyleType = "none";
                                        // Append li to the ul.
                                        this.ul.appendChild( this.li[i] );




					if( item.type == "video" ) {
						if( ie ) {
		                                        var flashvars = {
                		                                "image": item.image,
                                		                "file":  item.flv,
                                                		"controlbar": "none",
		                                                "provider":"http",
                		                                "viral.oncomplete":"false",
                                		                "viral.onpause":"false",
                                                		"viral.allowmenu":"false"
		                                        };
                		                        var params = {
                                		                //"movie": "http://www.catholic.org/j/nc_player.swf",
                                                		"allowfullscreen":"false",
		                                                "allowscriptaccess":"always",
                		                                "wmode":"opaque"
		
                		                        };
                                		        var attributes = {
		                                                id:"video-"+i,
                		                                name:"video-"+i,
                                		                style:""//margin-left: 210px; margin-top: 120px;"
		                                        };
                var t = this;
                var c = this.conf;

                		                        var flashLoaded = function( e ) {
                                                		if( def(e.ref) ) {
		                                                jwplayer(e.ref).onReady( function() {
                                		                });
                                                		jwplayer(e.ref).onPlay( function() {
                		                                });
                                		                jwplayer(e.ref).onComplete( function() {
									jwplayer(e.ref).play();
									if( def(c.mutedVideos) && c.mutedVideos ) {
										jwplayer(e.ref).setVolume( 0 );
									}
									
		                                                });
                		                                }
		                                        }
	
							swfobject.embedSWF(
								'http://www.catholic.org/j/nc_player.swf', "video-"+i, 1200, 550, '9.0.115', 'true',
								 flashvars, params, attributes, flashLoaded
							);
						} else {
						}
					}


                                }
                        } else {
                                alert(
                                "Problem, ul not found and items"+
                                " not present:"+this.element.id);
                                this.ul = document.createElement("ul");
                                this.element.appendChild(this.ul);
                        }
                } // UL.
                this.ul.style.overflow = "hidden";
                this.ul.style.position = "relative";
                //this.ul.style.backgroundColor = "#050505";
                log("ul width:"+this.ul.style.width+" ul height:"+this.ul.style.height);
                // Initialize the ARROWS.

	}, // initUL
	initPause: function() {
		this.pause = childClass( this.element, "pause" );
                if( def( this.conf.pauseOn ) ) {
                        var n = this.pause;
                        var c = this.conf;
                        this.pause.onmouseover = function() {
                                n.setAttribute("class", c.pauseOn );
                        };
                        this.pause.onmouseout = function() {
                                n.setAttribute("class", "pause");
                        };
                }
		var t = this;
		var c = this.conf;
		var n = this.pause;
                this.pause.onclick = function() {
			if( n.getAttribute("class").indexOf("pause") != -1 || n.getAttribute("class").indexOf(c.pauseOn) != -1 ) {
				window.clearInterval( t.changeTimer );
				n.setAttribute("class", "play");
        	                t.pause.onmouseover = function() {
                	                n.setAttribute("class", c.playOn );
	                        };
        	                t.pause.onmouseout = function() {
                	                n.setAttribute("class", "play");
	                        };

			} else {
				n.setAttribute("class", "pause");
	                        t.pause.onmouseover = function() {
        	                        n.setAttribute("class", c.pauseOn );
                	        };
                        	t.pause.onmouseout = function() {
                                	n.setAttribute("class", "pause");
	                        };

                                if( c.orientation ==  Carousel.horizontal ) {
                                        t.moveRight();
                                } else {
                                        t.moveUp();
                                }
	                        t.changeTimer = setInterval( function() {
        	                        if( t.conf.orientation = Carousel.horizontal ) {
                	                        t.moveRight();
                        	        } else {
                                	        t.moveUp();
	                                }
        	                }, t.conf.changeTime );
			}
		};
	},
	initNext: function() {
                var next = childClass( this.element, "next");
                if( next ) {
                        if( def(next.length) ) {
                                next = next[0];
                        }
			//next.style.backgroundColor = "green";
                } else {
                        next = document.createElement("div");
                        //next.setAttribute("id","next");
                        next.setAttribute("class", "next");
                        this.element.appendChild( next );
                        next.style.position = "absolute";
                        next.style.zIndex = 460;
                        next.style.width = "80px";
                        next.style.height = "80px";
                        //next.style.backgroundColor = "green";
                        next.innerHTML = "NEXT";
                        if( this.conf.orientation == Carousel.horizontal ) {
                                next.style.left = (stripPx(this.element.style.width)+
                                (zero(stripPx(this.element.style.paddingLeft))*2)-stripPx(next.style.width))+"px";
                                log("next.style.left:"+next.style.left+" id:"+this.element.id);
                                log("this.element.style.width:"+this.element.style.width);

                                next.style.top = ((stripPx(this.element.style.height)/2)+
                                (zero(stripPx(this.element.style.paddingTop)))-(stripPx(next.style.height)/2))+"px";
                                log("this.element.style.width:"+this.element.style.width);
                                log("next.style.top:"+next.style.top+" id:"+this.element.id);
                        } else {
                                next.style.left = ((stripPx(this.element.style.width)/2)-(stripPx(next.style.width)/2))+"px";
                                log("zero:"+zero(stripPx(this.element.style.paddingTop)));
                                next.style.top = (stripPx(this.element.style.height)+zero(stripPx(this.element.style.paddingTop))*2-stripPx(next.style.height))+"px";
                        }
                        log("next:"+next.style.left+","+next.style.top);
                }
                this.next = next;

                var n = this.next;
                var c = this.conf;
		var t = this;
                if( c.orientation == Carousel.horizontal ) {
                        n.onclick = function() {
				if( c.changeTime > 0 ) {
					window.clearInterval( t.changeTimer );
	                                t.pause.onmouseover = function() {
        	                                t.pause.setAttribute("class", c.playOn );
                	                };
                        	        t.pause.onmouseout = function() {
                                	        t.pause.setAttribute("class", "play");
	                                };
					t.pause.setAttribute("class", "play");
				}
				t.moveRight();
			}
                } else {
                        n.onclick = function() {
                                if( c.changeTime > 0 ) {
                                	window.clearInterval( t.changeTimer );
	                                t.pause.onmouseover = function() {
        	                                t.pause.setAttribute("class", c.playOn );
                	                };
                        	        t.pause.onmouseout = function() {
                                	        t.pause.setAttribute("class", "play");
	                                };
					t.pause.setAttribute("class", "play");
                                }
                                t.moveDown();
                        }
                }

                this.next.style.userSelect = "none";

                this.next.style.MozUserSelect = "none";
                this.next.style.KhtmlUserSelect="none";
                this.next.style.WebkitUserSelect = "none";

                if( this.fullWidth && this.conf.moveArrows ) {
                        this.next.style.left = (stripPx(this.next.style.left)-17)+"px";
                }

                if( def( this.conf.nextOn ) ) {
                        this.next.onmouseover = function() {
                                n.setAttribute("class", c.nextOn );

				//alert("n.getAttribute(\"class\"):"+n.getAttribute("class") );

                        };
                        this.next.onmouseout = function() {
                                n.setAttribute("class", "next");

                        };
                }


		log("after next");

	}, // initNext
	initPrev: function() {
                // Previous.
                var prev = childClass( this.element, "prev");
                if( prev  ) {
                        if( def(prev.length) ) {
                        // Prev exists.
                                log("prev exists:"+this.element.id);
                                prev = prev[0];
                        } 
                        var text = "";
                        for( var title in prev.style ) {
                                var value = prev.style[title];
                                text += title+": "+value+";";
                        }
                        log("style:"+text);
                } else {
                        // Prev doesn't exist.
                        log("prev doesn't");
                        prev = document.createElement("div");
                        //prev.setAttribute("id","prev");
                        prev.setAttribute("class", "prev");
                        this.element.appendChild( prev );
                        prev.style.position = "absolute";
                        prev.style.width = "80px";
			prev.style.zIndex = 460;
                        prev.style.height = "80px";
                        //prev.style.backgroundColor = "green";
                        prev.innerHTML = "PREV";
                        log("prev orientation");
                        if( this.conf.orientation == Carousel.horizontal ) {
                                prev.style.left = 0+"px";
                                prev.style.top = ((stripPx(this.element.style.height)/2)+
                                zero(stripPx(this.element.style.paddingTop))-(stripPx(prev.style.height)/2))+"px";
                                log("prev.style.left:"+prev.style.left+" id:"+this.element.id);
                                log("prev.style.top:"+prev.style.top+" id:"+this.element.id);
                        } else {
                                prev.style.left = ((stripPx(this.element.style.width)/2)-
                                (stripPx(prev.style.width)/2))+"px";
                                prev.style.top = 0+"px";
                        }

                        log("prev:"+prev.style.left+","+prev.style.top);
                }
                this.prev = prev;
                this.prev.style.userSelect = "none";
                this.prev.style.MozUserSelect = "none";
                this.prev.style.KhtmlUserSelect="none";
                this.prev.style.WebkitUserSelect = "none";


                var n = this.prev;
                var c = this.conf;
                var t = this;   
                                        
                if( this.conf.orientation == Carousel.horizontal ) {
                        this.prev.onclick = function() {
                                if( c.changeTime > 0 ) {
                                window.clearInterval( t.changeTimer );
                                t.pause.onmouseover = function() {
                                        t.pause.setAttribute("class", c.playOn );
                                };
                                t.pause.onmouseout = function() {
                                        t.pause.setAttribute("class", "play");
                                };
				t.pause.setAttribute("class", "play");
                                }

                                t.moveLeft();
                        }
                } else {        
                        this.prev.onclick = function() {
                                if( c.changeTime > 0 ) {
                                window.clearInterval( t.changeTimer );
                                t.pause.onmouseover = function() {
                                        t.pause.setAttribute("class", c.playOn );
                                };
                                t.pause.onmouseout = function() {
                                        t.pause.setAttribute("class", "play");
                                };
				t.pause.setAttribute("class", "play");
                                }

                                t.moveUp();
                        }
                }    


		if( def( this.conf.prevOn ) ) {
			var p = this.prev;
			var c = this.conf;
			this.prev.onmouseover = function() {
				p.setAttribute("class", c.prevOn );
			};
			this.prev.onmouseout = function() {
				p.setAttribute("class", "prev");
			};
		}
                log("after prev:"+this.element.id);
	}, // initPrev
	/**
	 * Initialize the document object model.
 	 * Based on configuration or default configuration,
	 * positions, adds , moves the necessary divs or elements.
	 */
	initDOM: function() {
		if( this.conf.wait ) {
			this.element.style.display = "none";
		}
		log("initDOM");
		// Initialize the parent div.
		this.element.style.position = "relative";
		this.element.style.left = "0px";
		this.element.style.top = "0px";
		if( def(this.conf.carouselWidth) && !def(this.element.style.width) ) {
			log("width set");
			this.element.style.width = (this.conf.carouselWidth+(zero(stripPx(this.element.style.padding))*2))+"px";
		}
		if( def(this.conf.carouselHeight) && !def(this.element.style.width) ) {
			log("height set");
			this.element.style.height = (this.conf.carouselHeight+(zero(stripPx(this.element.style.padding))*2))+"px";
		}
		log("width:"+this.element.style.width+" height:"+this.element.style.height);


                this.element.style.overflow = "hidden";

		var t = this;
		// #####################
		// Initialize the logo.
		setTimeout( function() {
			t.initLogo();
		}, 200 );


		// ###################
		// Initialize the UL.
		setTimeout( function() {
			t.initUL();
		}, 200 );
	
		// Initialize the ARROWS.

		// #######################
		// Previous.
		setTimeout( function() {
			t.initPrev();
		}, 200 );

		// ######################
		// Next.
		setTimeout( function() {
			t.initNext();
		}, 200 );

		if( this.conf.changeTime > 0 ) {
		setTimeout( function() {
			t.initPause();
		}, 200 );
		}


		// #########################
		// Initiallize the positions of the 'li' 'prev' 'logo' and 'next'
		setTimeout( function() {
			t.initPos();
			t.element.style.display = "block";
			t.oldWidth = stripPx( t.element.style.width );
		}, 800 );
		//this.positionLI();
	}, // initDOM
	repos: function() {
		var width = stripPx(this.element.parentNode.style.width);

		if( this.fullWidth ) {
			//width = width - 15;
		}
		if(!def(width) ||  width == "" || width == 0 ) {
			width = getWidth();
		}
		if( this.fullWidth ) {
			// If full width, resize the carousel.
			this.element.style.width = width+"px";
		}

                if( this.conf.centered ) {
			log("this.ul.style.width:"+this.ul.style.width);
                        // If centered, repos the carousel items to center.
			this.ul.style.width = width+"px";
			log("this.ul.style.width:"+this.ul.style.width);
			// Reposition the panels.
			var toldw = this.oldWidth;
			var diff = 0;
			var oldPos = ((toldw/2)-(this.conf.panelWidth/2));
			log("oldPos:"+oldPos);
			var newPos = (((width)/2)-(this.conf.panelWidth/2));
			log("newPos:"+newPos);
			if( oldPos > newPos ) {
				// Shrinking.
				diff = -1*(oldPos-newPos);
			} else {
				// Growing.
				diff = newPos-oldPos;
			}
			log("pre diff:"+diff);
                        if( (oldPos+diff) < 0 || (oldPos+diff) > width ) {
                                diff = 0;
                        }

	                if( def( this.textDiv ) ) {
        	                this.textDiv.style.left = (newPos+120)+"px";
	                }


			if( this.conf.moveArrows ) {
                        this.next.style.left = (stripPx(this.element.style.width)+
                                (zero(stripPx(this.element.style.paddingLeft))*2)-stripPx(this.next.style.width))+"px";
			}

			log("newPos:"+newPos);
			log("diff:"+diff);
			for( var i = 0; i < this.li.length; i++ ) {
				this.li[i].style.left = (stripPx(this.li[i].style.left)+diff)+"px";
			}

	                // Position logo.
        	        if( this.conf.logo && def(this.logo) && def(this.logo.style)) {
                        	this.logo.style.left = (newPos+20)+"px";
	                        if( ie ) {
        	                        this.logo.style.visibility = "visible";
                	        } else {
	                                this.logo.style.display = "visible";
        	                }
                	        this.logo.style.zIndex = 480;
	                }



                }


		this.oldWidth = width; 
                log("REPOS width:"+this.element.style.width+" height:"+this.element.style.height);
	},
	position: function() {
		var retVal = 0;
		log(stripPx(this.ul.style.width));
		log(this.conf.panelWidth);
		//log("x:"+this.conf.x);
		//log("width:"+stripPx(this.element.style.width));
		//log("panelWidth:"+this.conf.panelWidth);
		if( this.conf.orientation == Carousel.horizontal ) {
			retVal = zero(
			((stripPx(this.ul.style.width))/2)-(this.conf.panelWidth/2)
			);
			if( this.fullWidth ) {
				retVal = retVal - 9;
			}
		}  else {
			retVal = (
				zero((stripPx(this.ul.style.width)/2) -
				(this.conf.panelWidth/2))
			);
		}
		return retVal;
	},
	showText: function() {
		if( def(this.textDiv) && this.items.length > 0 ) {
			this.textDiv.innerHTML = "";
			var num = this.showCountNum-1;
			var feature = this.items[num];
			var text = feature.text;
			if( def(text) ) {

				if( def(feature.url) ) {
					var anchor = document.createElement("a");
					anchor.setAttribute("href", feature.url );
					anchor.setAttribute("onclick", "window.location.href='"+feature.url+"'; return false;");
					anchor.setAttribute("style", "opacity: 1.0; filter: alpha( opacity=100); color: white;");
					anchor.innerHTML = feature.text;
					this.textDiv.appendChild( anchor );
				} else {
					this.textDiv.innerHTML = text;
				}
				if( ie ) {
					this.textDiv.style.visibility = "visible";
					this.textDiv.style.display = "block";
				} else {
					this.textDiv.style.display = "block";
				}
			}
		}
	},
	hideText: function() {
		if( def( this.textDiv ) ) {
			if( ie ) {
				this.textDiv.style.visibility = "hidden";
			} else {
				this.textDiv.style.display = "none";
			}
		}
	},
	showCount: function() {
		if( this.conf.showCount ) {
			if( def( this.showCountDiv ) ) {
				this.showCountDiv.innerHTML = this.showCountNum + " of " + this.li.length;
			}
		}
	},
	moveLeft: function() {
		log("moveLeft this.id:"+this.id);
		if( !this.moveAnimation && this.conf.scrollWait > 0 ) {
			// Disable the buttom.
			this.prev.onclick = function() {};
                        var n = this.prev;
                        var c = this.conf;
                        var t = this;
                        setTimeout( function() {
                                 n.onclick = function() {
                                       if( c.changeTime > 0 ) {
                                            window.clearInterval( t.changeTimer );
                                            t.pause.onmouseover = function() {
                                                      t.pause.setAttribute("class", c.playOn );
                                            };
                                            t.pause.onmouseout = function() {
                                                       t.pause.setAttribute("class", "play");
                                            };
						t.pause.setAttribute("class", "play");
                                        }
                                        t.moveLeft();
                                }
                       }, this.conf.scrollWait );
		}
		// Move the carousel.
		this.move( this.left );
		//alert("diff:"+(((this.time2-this.time1)/1000).toFixed( 5 ))  );
	},
	moveRight: function() {
		log("moveRight");
		if(  this.conf.scrollWait > 0 ) {
	                // Disable the buttom.
        	        this.next.onclick = function() {};
                	// Reinstate the button (after 300 millis).
			if( !this.moveAnimation && this.conf.scrollWait > 0 ) {
                		var n = this.next;
	        	        var c = this.conf;
		                var t = this;
	        	        setTimeout( function() {
		                        n.onclick = function() {
						if(c.changeTime > 0 ) {
                                		        window.clearInterval( t.changeTimer );
		                                        t.pause.onmouseover = function() {
                		                                t.pause.setAttribute("class", c.playOn );
                                		        };
		                                        t.pause.onmouseout = function() {
		                                                t.pause.setAttribute("class", "play");
                		                        };
							t.pause.setAttribute("class", "play");
                               			}
		                                t.moveRight();
					}
	                	}, this.conf.scrollWait-500 );
			}
		}
                // Move the carousel.
		this.move( this.right );
	},
	moveUp: function() {
                if( this.conf.changeTime > 0 ) {
                        window.clearInterval( this.changeTimer );
                        var t = this;
                        t.changeTimer = setTimeout( function() {
                                if( t.conf.orientation = Carousel.horizontal ) {
                                        t.moveRight();
                                } else {
                                        t.moveUp();
                                }
                        }, t.conf.changeTime );
                        if( def(this.pause) && (this.pause.getAttribute("class") == "play" ||                                 this.pause.getAttribute("class") == this.conf.playOn ) ) {
                                var n = this.pause;
                                var c = this.conf;
                                n.setAttribute("class","pause");
                                n.onmouseover = function() {
                                        n.setAttribute("class", c.pauseOn );
                                };
                                n.onmouseout = function() {
                                        n.setAttribute("class", "pause");
                                };

                        }
                }
		log("moveUp");
		if(  this.conf.scrollWait > 0 ) {
                	// Disable the buttom.
	                this.prev.onclick = function() {};
			if( !this.moveAnimation ) {
                		// Reinstate the button (after 300 millis).
	                	var t = this;
	        	        setTimeout( function() {
        	        	        t.prev.onclick = t.moveUp.bind( t, "test" );
	        	        }, this.conf.scrollWait );
			}
		}
                // Move the carousel.
		this.move( this.up );
	},
	moveDown: function() {
                if( this.conf.changeTime > 0 ) {
                        window.clearInterval( this.changeTimer );
                        var t = this;
                        t.changeTimer = setTimeout( function() {
                                if( t.conf.orientation = Carousel.horizontal ) {
                                        t.moveRight();
                                } else {
                                        t.moveUp();
                                }
                        }, t.conf.changeTime );
                        if( def(this.pause) && 
				(this.pause.getAttribute("class") == "play" || 
				this.pause.getAttribute("class") == this.conf.playOn ) ) {
                                var n = this.pause;
                                var c = this.conf;
                                n.setAttribute("class","pause");
                                n.onmouseover = function() {
                                        n.setAttribute("class", c.pauseOn );
                                };
                                n.onmouseout = function() {
                                        n.setAttribute("class", "pause");
                                };
                        }
                }
		log("moveDown");
		if(  this.conf.scrollWait > 0 ) {
                	// Disable the buttom.
	                this.next.onclick = function() {};
			if( !this.moveAnimation ) {
                		// Reinstate the button (after 300 millis).
	                	var t = this;
	        	        setTimeout( function() {
        	        	       t.next.onclick = t.moveDown.bind( t, "test" );
	        	        }, this.conf.scrollWait );
			}
		}
                // Move the carousel.
		this.move( this.down );
	},
	/**
	 *
	 */
	showDivs: function( current ) {
                // Call all of the showing divs.
                for( var ii = 0; ii < this.conf.scroll; ii++ ) {
                        var num = current + ii;
                        log("showing:"+num);
                        if( def(this.items[num].text) ) {
                                this.showText();
                        }
                        if( this.conf.opacity ) {
                           if( ie ) {
                                this.li[num].style.filter = "alpha( opacity=100)";
                           } else {
                                this.li[num].style.opacity = "1.0";
                           }
                        }
                        if( this.conf.scroll == 1 ) { //&& this.conf.logo ) {
                                log("handle logo");
                                if( def(this.items[num]) && (
                                this.items[num].type == "video" ||
                                this.items[num].type == "ad") ) {
					if( def(this.logo) ) {
                                        	this.logo.style.display = "none";
					}
                                } else {
					if( def(this.conf.logo) && this.conf.logo ) {
                                        	this.logo.style.display = "block";
					}
                                }
                                if( this.items[num].type == "video" ) {
					// If we are playing and videoTiem is set. Change to video time.
					if( this.conf.changeTime > 0 && def(this.conf.videoTime) &&
						 def(this.pause) && 
						 this.pause.getAttribute("class").indexOf("pause") != -1) {
						// Delete old interval.
						window.clearInterval( this.changeTimer );
						// Add new interval for video.
						var t = this;
						setTimeout( function() {
							window.clearInterval(t.changeTimer);
	                                                setTimeout( function() {
        	                                                if( t.conf.orientation = Carousel.horizontal ) {
                	                                                t.moveRight();
                        	                                } else {
                                	                                t.moveUp();
                                        	                }
							}, t.conf.videoTime );

	                                                t.changeTimer = setInterval( function() {
        	                                                if( t.conf.orientation = Carousel.horizontal ) {
                	                                                t.moveRight();
                        	                                } else {
                                	                                t.moveUp();
                                        	                }
                                                	}, t.conf.changeTime );
						}, t.conf.videoTime);
					}
                                       var overlay = document.getElementById("overlay-video"+num);
                                       if( !def( overlay ) ) {
                                               overlay = document.createElement("div");
                                               overlay.setAttribute("id", "overlay-video"+num);
                                               overlay.setAttribute(
                                                       "style",
                                                       "position: absolute; top: 0px; left: "+
                                                       this.li[num].style.left+"; width: "+
                                                        this.conf.panelWidth+"px; height: "+
                                                        this.conf.panelHeight+"px; z-index: 451; "+
                                                       "opacity: 0; filter: alpha( opacity=0.0);"
                                                );
                                                if( ie ) {
                                                        overlay.style.backgroundColor = "blue";
                                                }
                                                this.element.appendChild( overlay );
                                        }
                                        if( ie ) {
						jwplayer("video-"+num).play();
                                        } else {
						var video = document.getElementById("video-"+num);
						video.play();	
                                                
                                        }
                                        overlay.style.display = "block";
                                        if( def( this.items[num].onclick) ) {
                                                overlay.setAttribute("onclick", this.items[num].onclick );
                                        }
                                }
                        }
                }
	}, // showDivs
	/**
	 *
	 */
	hideDivs: function( current ) {
                for( var iii = 0; iii < this.conf.scroll; iii++ ) {
                        var num = current + iii;
                        log("hiding:"+num);
                        if( this.items[num].type == "video") {
                                var overlay = document.getElementById("overlay-video"+num);
                                if( def(overlay) ) {
                                        overlay.style.display = "none";
                                        overlay.setAttribute("onclick", "");
                                }
                                window.video = document.getElementById("video-"+num);
                                if( ie ) {
					jwplayer("video-"+num).pause();
                                } else {
                                        setTimeout("window.video.pause()", 250 );
                                }
                        }
                        if( this.conf.opacity ) {
                           if( ie ) {
                                this.li[num].style.filter = "alpha( opacity=40)";
                           } else {
                                this.li[num].style.opacity = "0.4";
                           }
                        }
                        if( def(this.items[num].text) ) {
                                this.hideText();
                        }
                }
	}, // hideDivs
	// TODO: provide a way to animate these movements... maybe with jquery to save time.
	move: function( dir ) {
		log("this.id2:"+this.id);
		this.oldCurrent = this.current;
		log("scroll:"+this.conf.scroll);
		if( this.moveAnimation !== false ) {
			log("moveAnimation");
                        var currentLeft = stripPx(this.li[0].style.left);
                        var currentTop = stripPx(this.li[0].style.top);
                        var newLeft = currentLeft;
                        var newTop = currentTop;
			var xDiff = 0;
			var yDiff = 0;
			switch( dir ) {
                        case this.left:
                                newLeft = currentLeft+this.conf.panelWidth*this.conf.scroll;
                                xDiff = newLeft-currentLeft;
                                break;
                        case this.right:
                                newLeft = currentLeft-this.conf.panelWidth*this.conf.scroll;
                                xDiff = newLeft-currentLeft;
                                break;
                        case this.up:
                                newTop = currentTop+this.conf.panelHeight*this.conf.scroll;
                                yDiff = newTop - currentTop;
                                break;
                        case this.down:
                                newTop = currentTop-this.conf.panelHeight*this.conf.scroll;
                                yDiff = newTop - currentTop;
                                break;
			}	
                        var conf = {
                                x: xDiff,
                                y: yDiff
                        };
			var tt = this;	
			var cb = function( dir ) {
				//alert("after:"+this.li[0].style.left);
				//alert("cb:"+dir);
				tt.changeCurrent( dir );


                var t = this;
		if( this.conf.orientation == Carousel.horizontal ) {
                	setTimeout( function() {
                        	t.prev.onclick = t.moveLeft.bind( t, "test" );
	                }, this.conf.scrollWait );
			setTimeout( function() {
				t.next.onclick = t.moveRight.bind( t, "test" );
			}, this.conf.scrollWait );
		} else {

                        setTimeout( function() {
                                t.prev.onclick = t.moveUp.bind( t, "test" );
                        }, this.conf.scrollWait );
                        setTimeout( function() {
                                t.next.onclick = t.moveDown.bind( t, "test" );
                        }, this.conf.scrollWait );

		}



			};	
			//alert("before:"+this.li[0].style.left);
			//alert("time:"+this.conf.moveAnimation);
			//alert("wait:"+this.conf.scrollWait);

			var anim = new Animate( this.li, conf, this.conf.moveAnimation, cb.bind( this, dir) );

			anim.animate();

		} else {
			for( var i = 0; i < this.li.length; i++ ) {
				var tli = this.li[i];
				var currentLeft = stripPx(tli.style.left);
				var currentTop = stripPx(tli.style.top);
				var newLeft = currentLeft;
				var newTop = currentTop;

				var xDiff = 0;
				var yDiff = 0;
				switch( dir ) {
				case this.left:
					newLeft = currentLeft+this.conf.panelWidth*this.conf.scroll;
					xDiff = newLeft-currentLeft;
					break;
				case this.right:
					newLeft = currentLeft-this.conf.panelWidth*this.conf.scroll;
					xDiff = newLeft-currentLeft;
					break;
				case this.up:
					newTop = currentTop+this.conf.panelHeight*this.conf.scroll;
					yDiff = newTop - currentTop;
					break;
				case this.down:
					newTop = currentTop-this.conf.panelHeight*this.conf.scroll;
					yDiff = newTop - currentTop;
					break;
				}


				this.li[i].style.left = newLeft+"px";
				this.li[i].style.top = newTop+"px";
			}

			this.changeCurrent( dir );


		}

	},

	changeCurrent: function( dir ) {
		//alert("change current");
                // Adjust the value of the current showing feature.
                switch( dir ) {
                case this.left:
                        this.current -= this.conf.scroll;
                        break;
                case this.right:
                        this.current += this.conf.scroll;
                        break;
                case this.up:
                        this.current -= this.conf.scroll;
                        break;
                case this.down:
                        this.current += this.conf.scroll;
                        break;
                }


                // If the current goes over the limits, adjust them.
                log("this.current:"+this.current);

                if( this.current < 0 ) {
                        this.current = this.li.length+this.current;
                }
                if( this.current > (this.li.length-1) ) {
                        this.current = this.current - (this.li.length);
                }
                //alert("this.current:"+this.current);

                // Show and hide divs.
                if( def(this.items) && this.items.length > 0 ) {
                        this.hideDivs( this.oldCurrent );
                        this.showDivs( this.current );
                }
                if( dir == this.left || dir == this.up ) {
                        this.showCountNum -= this.conf.scroll;
                        if( this.showCountNum <= 0 ) {
                           this.showCountNum = this.li.length+this.showCountNum;
                        }
                } else {
                        this.showCountNum += this.conf.scroll;
                        if( this.showCountNum > this.li.length ) {
                           this.showCountNum = this.showCountNum-this.li.length;
                        }
                }
                this.pop(dir);
                this.showCount();
                this.showText();
	},
	/**
	 * Takes divs from one side of the scroll area and appends them to the other side in
	 * the correct order.
	 */ 
	pop: function( dir ) {
		//alert( this );
		//alert("pop:"+dir+" leftMost:"+this.leftEnd+" rightMOst:"+this.rightEnd+" this.li.length:"+this.li.length);
		switch( dir ) {
		case this.left:
			var leftMost = this.li[this.leftEnd];
			var leftPos = zero(stripPx(leftMost.style.left));
			var num = -1;
			for( var i = 1; i <= this.conf.scroll;  i++ ) {
				var loc = leftPos-(i*this.conf.panelWidth);
				num = this.rightEnd;
				log("pop:"+num+" loc:"+loc);
				this.li[num].style.left = loc+"px";
				// Change right end for next loop.
				this.rightEnd = num-1;
				if( this.rightEnd < 0 ) {
					this.rightEnd = this.li.length-1;
				}
			}
			this.leftEnd = num;
			//alert("new right end:"+this.rightEnd);	
			break;
		case this.right:
			log("right");
			var rightMost = this.li[this.rightEnd];
			var rightPos = zero(stripPx(rightMost.style.left) );
			rightPos = rightPos + this.conf.panelWidth;
			var num = -1;
			for( var i = 0; i < this.conf.scroll; i++ ) {
				// 5 6 7
				num = this.leftEnd;
				var loc = rightPos+(i*this.conf.panelWidth);
				log("num:"+num+" loc:"+loc);
				this.li[num].style.left = loc+"px";
				this.leftEnd = num+1;
				if( this.leftEnd > (this.li.length-1) ) {
					this.leftEnd = 0;
				}
			}
			this.rightEnd  = num;
			//alert("new left end:"+this.leftEnd);
			break;
		case this.up:
                        var leftMost = this.li[this.leftEnd];
                        var leftPos = zero(stripPx(leftMost.style.top));
                        var num = -1;
                        for( var i = 1; i <= this.conf.scroll;  i++ ) {
                                var loc = leftPos-(i*this.conf.panelHeight);
                                num = this.rightEnd;
                                log("pop:"+num+" loc:"+loc);
                                this.li[num].style.top = loc+"px";
                                // Change right end for next loop.
                                this.rightEnd = num-1;
                                if( this.rightEnd < 0 ) {
                                        this.rightEnd = this.li.length-1;
                                }
                        }
                        this.leftEnd = num;
                        log("new right end:"+this.rightEnd);
			break;
		case this.down:
                        var rightMost = this.li[this.rightEnd];
                        var rightPos = zero(stripPx(rightMost.style.top) );
                        rightPos = rightPos + this.conf.panelHeight;
                        var num = -1;
                        for( var i = 0; i < this.conf.scroll; i++ ) {
                                // 5 6 7
                                num = this.leftEnd;
                                var loc = rightPos+(i*this.conf.panelHeight);
                                log("num:"+num+" loc:"+loc);
                                this.li[num].style.top = loc+"px";
                                this.leftEnd = num+1;
                                if( this.leftEnd > (this.li.length-1) ) {
                                        this.leftEnd = 0;
                                }
                        }
                        this.rightEnd  = num;
                        log("new left end:"+this.leftEnd);

			break;
		}
	},
	/**
	 * Initializes the positions of the scroll items for the first time.
	 */
	initPos: function() {
		if( this.conf.orientation == Carousel.horizontal ) {
		log("horizontal");
		var leftSet = false;
		var pos = this.position();

		var width = getWidth();
		if( this.conf.fullWidth ) {
			width = width - 18;
		}
		//log("width:"+width); // new
		//this.element.style.width = width+"px"; // new
		this.oldWidth = width;
		log("pos:"+pos);

		if( this.conf.centered ) {
	                if( def( this.textDiv ) ) {
        	                this.textDiv.style.left = (pos+130)+"px";
                	}
		}
		// Position logo.
		if( this.conf.logo && def(this.logo) && def(this.logo.style)) {
			//alert("init logo:"+pos);
			this.logo.style.left = (pos+20)+"px";
			if( ie ) {
				this.logo.style.visibility = "visible";
			} else {
				this.logo.style.display = "visible";
			}
			this.logo.style.zIndex = 480;	
		}
		for( var i = 0; i < this.li.length; i++ ) {
			this.li[i].style.position = "absolute";

                        if( this.conf.opacity && i != 0 ) {
                        if( ie ) {
                                this.li[i].style.filter = "alpha( opacity=40)";
                        } else {
                                this.li[i].style.opacity = "0.4";
                        }
                        }

			log("a li");
			if( i <= this.li.length/2 ) {
				log("pos:"+(pos+(i*this.conf.panelWidth)) );
				posDiv( 
				this.li[i], 
				pos+(i*this.conf.panelWidth), 0 );
				log("d1");
			} else {
				var i2 = this.li.length - i;
				posDiv( 
				this.li[i], 
				pos-(i2*this.conf.panelWidth), 0 );
			}

			if( i <= (this.li.length/2) ) {
				this.rightEnd = i;
			}
			if( !leftSet && i > (this.li.length/2) ) {
				this.leftEnd = i;
				leftSet = true;
			}
		}
		} else { // if( this.conf.orientation == Carousel.horizontal )
		log("vertical");
                var leftSet = false;
                var pos = this.position();
		log("pos:"+pos );
                for( var i = 0; i < this.li.length; i++ ) {
                        this.li[i].style.position = "absolute";
                        if( i <= this.li.length/2 ) {
                                log("pos:"+(pos+(i*this.conf.panelHeight)) );
                                posDiv(
                                this.li[i],
				0,
                                pos+(i*this.conf.panelHeight));
                                log("d1");
                        } else {
                                var i2 = this.li.length - i;
                                posDiv(
                                this.li[i],
				0,
                                pos-(i2*this.conf.panelHeight));
                        }

                        if( i <= (this.li.length/2) ) {
                                this.rightEnd = i;
                        }
                        if( !leftSet && i > (this.li.length/2) ) {
                                this.leftEnd = i;
                                leftSet = true;
                        }
                }

		}
		this.showText();
		this.showCount();
		log("init pos done:"+this.element.style.width);
	}
}; // window.Carousel.prototype

if( !def( window.Animate ) ) {

	window.Animate = function( divs, config, duration, cb ) {
		log("ANIMATE");
		if( def( divs ) && def(divs.length) && divs.length > 0 ) {
			this.tdivs = divs;
			if( def( duration) && !isNaN(duration) && duration != "" && duration != 0 ) {
				this.duration = duration;
				if( def( config ) && config != "" && config != 0 ) {
					this.conf = config;
				} else {
					alert("You must provide a configuration object.");
				}
			} else {
				alert("You must provide a duration. Needs to be number of millis.");
			}
		} else {
			alert("'divs' needs to be an array.");
		}
		if( def(cb) ){
			this.cb = cb;
		}

		log("ANIMATE2");
		this.init();
	};

	window.Animate.prototype = {
		tdivs: null,
		divs: null,
		duration: null,
		conf: null,
		// Count of items to animate.
		count: 0,
		// Per loop change.
		changeX: null,
		changeY: null,
		changeOpacity: null,
		// Start time of the animation.
		startTime: null,
		// Final.
		finalX: null,
		finalY: null,
		finalOpacity: null,
		// Current.
		x: null,
		y: null,
		cb: null,
		opacity: null,
		defaultConf: function() {
			log("Animate.defaultConf");
			if( !def( this.conf ) ) {
				this.conf = {};	
			}
			if( !def( this.conf.x ) ) {
				this.conf.x = 0;
			}
			if( !def( this.conf.y ) ) {
				this.conf.y = 0;
			}
			if( !def( this.conf.opacity ) ) {
				this.conf.opacity = 0;
			}
			if( !def( this.conf.interval ) ) {
				this.conf.interval = 13;
			}
			if( this.conf.x == 0 && this.conf.y == 0 && this.conf.opacity == 0 ) {
				alert("Nothing changes");
			}
		},
		init: function() {
			//alert("Animate.init");
                        // Init arrays.
			this.divs = new Array();
                        this.x = new Array();
                        this.y = new Array();
                        this.opacity = new Array();
                        this.changeX = new Array();
                        this.changeY = new Array();
                        this.changeOpacity = new Array();
                        this.finalX = new Array();
                        this.finalY = new Array();
                        this.finalOpacity = new Array();
			// Default the configuration.
			this.defaultConf();
			log('animate init 2');
			// Add the initial divs and conf to the list.
			this.add( this.tdivs, this.conf );
			log("done init");
		},
		// Add stuff to animate.
		add: function( adivs, conf ) {
			log("Animate.add:"+adivs.length);
			// Set animation values.
			var count = this.count;
			log("count:"+count);
			for( var i = 0; i < adivs.length; i++ ) {
				var div = adivs[i];
				log("loop:"+this.count+"|");
				log("loop");
				this.divs[count] = adivs[i];
				log("loop1");
				// Read initial values.
				this.x[count] = zero(stripPx(div.style.left));
				//alert("this.x["+count+"]:"+this.x[count]);
				//alert("div.style.opacity:"+div.style.opacity);
                                this.y[count] = zero(stripPx(div.style.top));
                                this.opacity[count] = parseFloat(div.style.opacity);
				log("loop2");
				// Compute change per loop and final resting spots.
				if( def( conf.x) && conf.x != 0 ) {
				if( conf.x > 0 ) {
                                        this.finalX[count] = this.x[count] + conf.x;
					this.changeX[count] = conf.x/(this.duration/this.conf.interval);
				} else {
					log("this.x["+count+"]: "+this.x[count]);
					this.finalX[count] = this.x[count] + conf.x;
					this.changeX[count] = (conf.x/(this.duration/this.conf.interval));
					//alert("this.changeX:"+this.changeX[count]);
				}
				} else {
					this.changeX[count] = 0;
				}

                                log("loop3");

				if( def(conf.y) && conf.y != 0 ) {
				if( conf.y > 0 ) {
					this.finalY[count] = this.y[count] + conf.y;
					this.changeY[count] = conf.y/(this.duration/this.conf.interval);
				} else {
					this.finalY[count] = this.y[count] + conf.y;
					this.changeY[count] = (conf.y/(this.duration/this.conf.interval));
				}
				} else {
					this.changeY[count] = 0;
				}

                                log("loop4");

				if( def( conf.opacity) && conf.opacity != 0 ) {
				if( conf.opacity > 0 ) {
					this.finalOpacity[count] = this.opacity[count] + conf.opacity;
					this.changeOpacity[count] = conf.opacity/(this.duration/this.conf.interval);
				} else {
					this.finalOpacity[count] = this.opacity[count] - conf.opacity;
					this.changeOpacity[count] = conf.opacity/(this.duration/this.conf.interval);
				}
				} else {
					this.changeOpacity[count] = 0;
				}

                                log("loop5");
	
				count++;
			}
			this.count = count;

//			alert("count:"+this.count+"|"+dump( this.divs ) );
		},

		totalCount: 0,
		animate: function( ) {
			if( this.startTime === null ) {
				this.startTime = new Date().getTime();
			}
			var currentTime = new Date().getTime();
			if( (currentTime-this.startTime) <= (10*(this.duration+(this.duration/2))) ) {	
				// Animate ONE LOOP.
				var count = 0;
				var change = false;
				for( var i = 0; i < this.divs.length; i++ ) {
					this.totalCount++;
					var div = this.divs[i];
					if(  this.changeX[count] != 0 ) {
						var newX = this.x[count] + this.changeX[count];
					
						if( this.totalCount % 50 == 0 && i == 1 ) {
							//alert("finalX:"+this.finalX[count]+"x:"+this.x[count] + "high:"+(this.finalX[count]+Math.abs(this.changeX[count]))+" low:"+(this.finalX[count] - Math.abs(this.changeX[count])) );
						}
						if( this.x[count] < (this.finalX[count]+Math.abs(this.changeX[count])) && 
							this.x[count] > (this.finalX[count] - Math.abs(this.changeX[count]))  ) { //|| (currentTime-this.startTime) > 2*(this.duration+(this.duration/4)) ) {
                                                        div.style.left = this.finalX[count]+"px";
                                                        this.x[count] = this.finalX[count];
						} else {
                                                        div.style.left = (newX)+"px";
                                                        this.x[count] = newX;
                                                        change = true;
						}
					}
					if( this.changeY[count] != 0 ) {
						var newY = this.y[count] + this.changeY[count];
						if(  this.y[count] < (this.finalY[count]+Math.abs(this.changeY[count])) && 
							this.y[count] > (this.finalY[count] - Math.abs(this.changeY[count])) ) { //|| (currentTime-this.startTime) > 2*(this.duration+(this.duration/4)) ) {

                                                        newY = this.finalY[count];

						} else {
							change = true;
						}
						div.style.top = (newY)+"px";
						this.y[count] = newY;
					}
					if( this.changeOpacity[count] != 0 ) {
						var newOpacity = this.opacity[count] + this.changeOpacity[count];
						if( this.opacity[count] < (this.finalOpacity[count] +Math.abs(this.changeOpacity[count])) && this.opacity[count] > (this.finalOpacity[count] - Math.abs(this.changeOpacity[count]))  ) { //|| (currentTime-this.startTime) > 2*(this.duration+(this.duration/4)) ) {
							
                                                        newOpacity = this.finalOpacity[count];
						} else {
							change = true;
						}
						div.style.opacity = newOpacity;
						div.style.filter = "alpha( opacity = "+(100*newOpacity)+" )";
						this.opacity[count] = newOpacity;
					}
					count++;
				}
				if( !change ) {
					if( def( this.cb ) ) {
						this.cb();
					}
				} else {
					// Callback.
					var t = this;
					setTimeout( function() {
						t.animate.apply(t, new Array() );
					}, this.conf.interval );

				}
			}
		}
	};
}

} // if( window.Carousel === undefined )





