function ImageGallery() {
    this.id_prefix;
    this.width;
    this.height;
    this.x;
    this.y;
    this.imgWidth = 1920;
    this.imgHeight = 1200;
    
    this.resizing = false;
    
    this.quality = 95;
    
    this.minWidth = 400;
    this.minHeight = 304;
    this.curCat = -1;
    this.curThumb = -1;
    this.curImg = -1;
    this.curAnchor = "center";
    
    this.igContainer;
    this.igImgContainer;
    this.igCurImg;
    this.igMenu;
    this.igLoading;
    this.oldImg;
    
    this.rootDir;
    
    this.curItem = null;
    
    this.onImgShow = null;
    
    this.categories = new Array();
    this.thumbCnt = 8;
    this.maxImages = 0;
    
    this.loadMgr = new LoadManager();
    var _self = this;
    this.loadMgr.loadHandler = function(item) { _self.imgLoad(item); }
    
    this.mode = 1;
    
    this.init = function(id_prefix) {
        this.id_prefix = id_prefix;
        this.igContainer = document.getElementById(id_prefix + "_igcontainer");
        this.igImgContainer = document.getElementById(id_prefix + "_igImgContainer");
        this.igLoading = document.getElementById(id_prefix + "_igLoading");
        this.igCurImg = document.getElementById(id_prefix + "_igImg");
        this.igMenu = document.getElementById(id_prefix + "_igMenu");
        
        var _self = this;
        this.igCurImg.onload = function() { _self.igLoading.style.display = "none"; };
        
        this.rootDir = document.location.href.substr(0, document.location.href.lastIndexOf("/") + 1);
        
        this.resize();
    }
    
    this.resize = function() {
            //Handle image resize;
            var sizeLoc = calcResize(windowWidth(), windowHeight(), this.imgWidth, this.imgHeight, this.curAnchor);
            this.igImgContainer.style.width = sizeLoc.width + "px";
            this.igImgContainer.style.height = sizeLoc.height + "px";
            this.igImgContainer.style.left = sizeLoc.x + "px";
            this.igImgContainer.style.top = sizeLoc.y + "px";
                
            this.width = sizeLoc.width;
            this.height = sizeLoc.height;
        
            for(var i = 0; i < this.categories.length; i++) {
                var cat = this.categories[i];
            
                for(var j = 0; j < cat.items.length; j++) {
                    cat.items[j].loaded = false;
                    cat.items[j].isLoading = false;
                }
            }
            
            if(!this.resizing) {
                this.resizing = true;
                
                var _self = this;
                setTimeout(function() { _self.reloadImages(); }, 1500);
            }
    }
    
    this.reloadImages = function() {
        this.resizing = false;
        if(this.curImg >= 0)
                this.showImage(this.curImg);
    }
    
    this.addCategory = function(cat) {
        this.categories[this.categories.length] = cat;
        if(cat.items.length > this.maxImages) {
            this.maxImages = cat.items.length;
        }
        /*
        for(var i in cat.items) {
            var item = cat.items[i];
            var _self = this;
            item.loadHandler = function(item) { _self.imgLoad(item) };
        }*/
    }
    
    this.showCategory = function(ind) {
        if(ind >= 0 && ind < this.categories.length && this.categories[ind].items.length > 0) {
            //this.curCat = ind;
            //this.curThumb = 0;
            //this.curImg = 0;
            this.displayImage(ind, 0);
            //this.displayThumbPage();
            //this.thumbClick(1);
        }
    }
    
    this.menuPage = function(inc) {
        var start = this.curThumb + inc;
        if(this.curCat >= 0 && start >= 0 && start <= this.categories[this.curCat].items.length) {
            this.curThumb = start;
            this.displayThumbPage();
        }
    }
    
    this.displayThumbPage = function() {
        var start = this.curThumb;
        if(this.curCat >= 0 && start >= 0 && start <= this.categories[this.curCat].items.length) {
            var cat = this.categories[this.curCat];
            for(var i = 0; i < this.thumbCnt; i++) {
                var tC = document.getElementById(this.id_prefix + "_thumb_container" + (i + 1));
                var tI = document.getElementById(this.id_prefix + "_thumb" + (i + 1));
                var itemInd = start + i;
                if(itemInd < cat.items.length) {
                    tI.style.visibility = "inherit";
                    tI.src = cat.items[itemInd].thumbnail_url;
                }
                else {
                    tI.style.visibility = "hidden";
                }
            }
        }
    }
    
    this.showMenu = function(show) {
        //this.igMenu.style.visibility = (show ? "visible" : "hidden");
        (show ? fadeIn(this.igMenu, 30) : fadeOut(this.igMenu, 30));
    }
    
    this.toggleMenu = function() {
        this.showMenu(this.igMenu.style.visibility != "visible");
    }
    
    this.showMenuControl = function(show) {
        var menuCntrl = document.getElementById(this.id_prefix + "_thumb_menu_control");
        if(menuCntrl.style.visibility != "visible") {
            var eff = (show ? new FadeInEffect(menuCntrl, 30) : new FadeOutEffect(menuCntrl, 30));
            eMgr.addEffect(eff);
        }
        eMgr.execute();
        //document.getElementById(this.id_prefix + "_thumb_menu_control").style.visibility = (show ? "visible" : "hidden");
    }
    
    this.thumbClick = function(thumb) {
        this.showImage(this.curThumb + (thumb - 1));
    }
    
    this.showImage = function(img) {
        this.loadMgr.reset();
        this.curImg = img;
        var cat = this.categories[this.curCat];
        if(this.onImgShow != null) {
            this.onImgShow();
        }
        
        var item = cat.items[this.curImg];
        this.curItem = item;
        this.curAnchor = item.anchor;
        if(!item.loaded) {
            this.igLoading.style.display = "";
            this.loadMgr.loadImage("http://www.sanjaykothari.com/templates/sanjaykothari/resize.php", this.width, this.height, this.quality, item);
            //item.loadImage("resize.php", this.width, this.height);
        }
        else {
            this.imgLoad(item);
        }
/*        var i;
        var cCat = this.curCat;
        var cImg = this.curImg;
        for(i = 0; i < 1; i++) {
            var ary = this.getNextImage(cCat, cImg);
            cCat = ary[0];
            cImg = ary[1];
            this.loadMgr.loadImage("resize.php", this.width, this.height, this.quality, this.categories[cCat].items[cImg]);
            //this.categories[cCat].items[cImg].loadImage("resize.php", this.width, this.height);
        }
        cCat = this.curCat;
        cImg = this.curImg;
        for(i = 0; i < 1; i++) {
            var ary = this.getPrevImage(cCat, cImg);
            cCat = ary[0];
            cImg = ary[1];
            this.loadMgr.loadImage("resize.php", this.width, this.height, this.quality, this.categories[cCat].items[cImg]);
            //this.categories[cCat].items[cImg].loadImage("resize.php", this.width, this.height);
        }*/
    }
    
    this.imgLoad = function(item) {
        if(this.curItem.image_url == item.image_url) {
            this.igCurImg.src = item.full_url;
            this.igCurImg.style.visibility = "visible";
            this.igLoading.style.display = "none";
            
            var base_addr = document.location.href.split('#')[0];
            document.location.href = base_addr + "#mode=" + this.mode + "&category=" + this.curCat + "&image=" + this.curImg;
        }
        //this.resize();
    }
    /*
    this.imgLoad = function(img_no) {
        var cur = document.getElementById(this.id_prefix + "_igCurImg" + img_no);
        if(img_no == this.curImg) {
            if(this.igCurImg != cur) {
                var oldCur = this.igCurImg;
                this.igCurImg = cur;
                this.igCurImg.style.visibility = "visible";
                oldCur.style.visibility = "hidden";
            }
            this.igLoading.style.visibility = "hidden";
        }
        this.categories[this.curCat].items[img_no].loaded = true;
        this.categories[this.curCat].items[img_no].image_url = cur.src;
        //this.resize();
    }*/
    
    this.nextImage = function() {
        var ary = this.getNextImage(this.curCat, this.curImg);
        
        this.displayImage(ary[0], ary[1]);
    }
    
    this.getNextImage = function(cC, cI) {
        var nImg = cI + 1;
        var nCat = cC;
        var cat = this.categories[nCat];
        if(nImg >= cat.items.length) {
            nImg = 0;
            nCat++;
            if(this.mode == 2) {
                nCat--;
            }
            if(nCat >= this.categories.length) {
                nCat = 0;
            }
            while(this.categories[nCat].items.length < 1 || this.categories[nCat].active == false) {
                nCat++;
                if(nCat >= this.categories.length) {
                    nCat = 0;
                }
            }
        }
        
        return new Array(nCat, nImg);
    }
    
    this.prevImage = function() {
        var ary = this.getPrevImage(this.curCat, this.curImg);
        
        this.displayImage(ary[0], ary[1]);
    }
    
    this.getPrevImage = function(cC, cI) {
        var nImg = cI - 1;
        var nCat = cC;
        var cat = this.categories[nCat];
        if(nImg < 0) {
            nCat--;
            if(this.mode == 2) {
                nCat++;
            }
            if(nCat < 0) {
                nCat = this.categories.length - 1;
            }
            while(this.categories[nCat].items.length < 1 || this.categories[nCat].active == false) {
                nCat--;
                if(nCat < 0) {
                    nCat = this.categories.length - 1;
                }
            }
            nImg = this.categories[nCat].items.length - 1;
        }
        
        return new Array(nCat, nImg);
    }
    
    this.syncPage = function() {
        var start = Math.floor(this.curImg / this.thumbCnt) * this.thumbCnt;
        this.curThumb = start;
        this.displayThumbPage();
    }
    
    this.displayImage = function(cat, img) {
        if(cat != this.curCat) {
            this.curCat = cat;
            this.igCurImg.style.visibility = "hidden";
        }
        this.showImage(img);
        
        this.syncPage();
    }
}

function ImageGalleryCategory(items) {
    this.items = new Array();
    this.active = true;
    
    if(items) {
        this.items = items;
    }
    
    this.addItem = function(item) {
        this.items[this.items.length] = item;
    }

    this.loadThumbs = function() {
        var i;
        for(i = 0; i < items.length; i++) {
            var img = new Image();
            img.src = this.items[i].thumbnail_url;
        }
    }
}

function ImageGalleryItem(image_url, thumbnail_url, anchor) {
    this.image_url = image_url;
    this.thumbnail_url = thumbnail_url;
    this.anchor = anchor;
    this.loaded = false;
    this.isLoading = false;
    this.full_url = "";
    
    this.loadHandler = null;
    
    if(!anchor) {
        this.anchor = "center";
    }
    
    if(thumbnail_url == null) {
        this.thumbnail_url = image_url;
    }
    
    this.loadImage = function(url, width, height, quality) {
        if(this.isLoading)
            return true;
        this.isLoading = true;
        var _self = this;
        var img = new Image();
        img.onload = function() { _self.imageLoaded(); };
        this.full_url = url + "?img=" + this.image_url + "&width=" + width + "&height=" + height + "&quality=" + quality;
        img.src = this.full_url;
        
        return false;
    }
    
    this.imageLoaded = function() {
        this.loaded = true;
        this.loadHandler(this);
    }
    
//    this.ldimg = new Image();
//    this.ldimg.src = this.thumbnail_url;
}

function LoadManager() {
    this.loadHandler = null;
    this.queue = new Array();
    this.cur = -1;
    this.isLoading = false;
    
    this.width;
    this.height;
    this.quality
    this.url;
    
    this.loadImage = function(url, width, height, quality, item) {
        this.width = width;
        this.height = height;
        this.quality = quality;
        this.url = url;
        this.queue[this.queue.length] = item;
        if(!this.isLoading) {
            this.isLoading = true;
            this.imgLoaded();
        }
    }
    
    this.reset = function() {
        this.queue = new Array();
        this.cur = -1;
        //this.printPicture();
    }
    
    this.imgLoaded = function(item) {
        if(item) {
            this.loadHandler(item);
            //alert(item.image_url);
        }
        //alert(this.cur + " == " + this.queue.length);
        this.cur++;
        //this.printPicture();
        if(this.cur >= this.queue.length) {
            //Reset
            this.reset();
            this.isLoading = false;
            //alert("done");
        }
        else {
            var item = this.queue[this.cur];
            var _self = this;
            item.loadHandler = function(itm) { _self.imgLoaded(item); }
            if(item.loadImage(this.url, this.width, this.height, this.quality)) {
                this.imgLoaded(item);
            }
            
            /*
            for(var i = 0; i < 2 && this.queue[this.cur] != null; i++) {
                this.cur++;
                item = this.queue[this.cur];
                item.loadHandler = function(itm) { _self.imgLoaded(item); }
                if(item.loadImage(this.url, this.width, this.height)) {
                    this.imgLoaded(item);
                }
            }*/
        }
    }
    
    this.printPicture = function() {
        var str = "";
        for(var i in this.queue) {
            var item = this.queue[i];
            
            if(i == this.cur)
                str += "<b>";
            
            str += i + ": " + item.image_url;
            
            if(i == this.cur)
                str += "</b>";
                
            str += "<br />";
        }
        DEBUG(str);
    }
}

function LoadGalleryThumbnail(item, ind) {
    var img = new Image();
    img.onload = function() {
        if(ind == item.length - 1) {
            return;
        }
        LoadGalleryThumbnail(item, ind + 1);
    }
    img.src = item[ind].thumbnail_url;
}

function LoadGalleryImage(item, ind) {
    var img = new Image();
    img.onload = function() {
        item[ind].loaded = true;
        if(ind == item.length - 1)
            return;
        LoadGalleryImage(item, ind + 1);
    }
    img.src = item[ind].image_url;
}

function calcResize(cWidth, cHeight, eWidth, eHeight, anchor) {
    var w = cWidth;
    var h = cHeight;
    var nWidth;
    var nHeight;
    var nX;
    var nY;
    var asr = (w / h) - (eWidth / eHeight);
    
    if(asr < 0) {
        nHeight = h;
        nWidth = Math.round((eWidth * nHeight) / eHeight);
        nY = 0;
        nX = Math.round((w / 2) - (nWidth / 2));
    }
    else {
        nWidth = w;
        nHeight = Math.round((eHeight * nWidth) / eWidth);
        nX = 0;
        nY = Math.round((h / 2) - (nHeight / 2));
    }
    
    if(anchor == "top" && nY < 0) {
        nY = 0;
    }
    else if(anchor == "bottom" && nY + nHeight > h) {
        nY -= nY + nHeight - h;
    }
    else if(anchor == "left" && nX < 0) {
        nX = 0;
    }
    else if(anchor == "right" && nX + nWidth > w) {
        nX -= nX + nWidth - w;
    }
        
    return new ElementLocationSize(nX, nY, nWidth, nHeight);
}

function ElementLocationSize(x, y, width, height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}

function DEBUG(text) {
    document.getElementById("debug").innerHTML = text;
}


function windowWidth() {
    var w = document.body.clientWidth;
    if(!w) {
        w = window.innerWidth;
    }
    if(!w) {
        w = document.documentElement.clientWidth;
    }
    
    return w;
}

function windowHeight() {
    var w = document.body.clientHeight;
    if(!w) {
        w = window.innerHeight;
    }
    if(!w) {
        w = document.documentElement.clientHeight;
    }
    
    return w;
}