/* Image Wrapper
* Public Interface:
* -----------------
* 
* img_initAllThumbnails() must be called after thumbnails are placed and before they can be used
* img_init_thumbnail(thumbnail) - initialize one thumbnail (ex. after being dynamically added) - thumbnail div should be passed
* 
* Thumbnail object properties:
*  thumbnail.setNumComments(n) - set the number of comments displayed in brackets
*  thumbnail.isOpen()
*  thumbnail.overlay - if open, it points to the current overlay object
* 
* callbacks:
* img_onInitThumbnail(thumbnail) - if defined, it will be called with each thumbnail initialization
* img_onCommentsOpen(comm) - called when comment box is being opened
* 
*/

img_animation_rate = 15;
img_comments_anim_speed = 100; /* Duration of comments entry animation */
img_open_speed = 80;
img_close_speed = 80;
img_full_speed = 80;
img_comments_transition_speed = 100; /* Transition between comments and normal view */
img_top_button_speed = 150;
img_active_movie = null;

function img_interpol() {
    if (!document.interpol) img_init_interpol();
    return document.interpol;
}

/* Responsible for animating. Triggers a function every frame. */
function img_init_interpol() {
    var interpol = { step: img_animation_rate, running: false, targets: [], loops: [] };

    interpol.add = function(func, done, time) {
        interpol.targets.push({ time: time, phase: 0, func: func, done: done });
        interpol.start();
    }
    interpol.loop = function(func) {
        interpol.loops.push(func);
        interpol.start();
    };

    interpol.start = function() {
        if (interpol.running) return;
        interpol.running = setInterval('img_interpol().animate();', interpol.step);
    }
    interpol.stop = function() {
        if (interpol.running) clearInterval(interpol.running);
        interpol.running = false;
    }
    interpol.animate = function() {
        for (var i = 0; i < interpol.loops.length; i++) {
            if (!interpol.loops[i] || !interpol.loops[i](interpol.step / 1000)) interpol.loops[i] = null;
        }
        var loo = new Array();
        for (var i = 0; i < interpol.loops.length; i++) {
            if (interpol.loops[i]) loo.push(interpol.loops[i]);
        }
        interpol.loops = loo;

        var tar = new Array();
        for (var i = 0; i < interpol.targets.length; i++) {
            if (interpol.targets[i].phase / interpol.targets[i].time >= 1.0) {
                if (interpol.targets[i].done) interpol.targets[i].done();
                interpol.targets[i].finished = true;
            }
        }
        for (var i = 0; i < interpol.targets.length; i++) {
            if (!interpol.targets[i].finished) tar.push(interpol.targets[i]);
        }
        interpol.targets = tar;

        if (interpol.targets.length < 1 && interpol.loops.length < 1) interpol.stop();

        for (var i = 0; i < interpol.targets.length; i++) {
            interpol.targets[i].phase += interpol.step;
            var p = interpol.targets[i].phase / interpol.targets[i].time;
            interpol.targets[i].func(p > 1 ? 1 : p);
        }
    }

    document.interpol = interpol;
}

function img_fromButton(button) {
    while (button.className != 'imageContainer' && button.id != 'img-overlay') button = button.parentNode;
    return button;
}

function img_byClass(root, type, cl) {
    var a = root.getElementsByTagName(type);
    for (var i = 0; i < a.length; i++) { if (a[i].className == cl) return a[i]; }
    return null;
}

function img_byTag(root, type) {
    var a = root.getElementsByTagName(type);
    if (a.length < 1) return null;
    return a[0];
}

function img_selectDefined(a) {
    for (var i = 0; i < a.length; i++) if (a[i] != 0 && a[i] != undefined) return a[i];
    return 0;
}

function img_init_comments(comm, overlay) {
    comm.overlay = overlay;
    comm.state = 'closed';
    comm.time = img_comments_anim_speed;
    comm.style.display = 'none'; // should already be in this state

    comm.full_width = img_getStyle(comm, 'width');
    comm.full_height = img_getStyle(comm, 'height');

    if (!(comm.full_width > 0 && comm.full_height > 0)) {
        /* Some browsers can only get style when element is displayed.
        * For such ones, we quickly show invisible, overlayed elements,
        * get the styles and hide it again. */

        comm.style.visibility = 'hidden';
        comm.style.position = 'absolute'; /* not to mess with others positions */
        comm.style.display = 'block';

        comm.overlay.style.visibility = 'hidden';
        comm.overlay.style.display = 'block';

        comm.full_width = img_getStyle(comm, 'width');
        comm.full_height = img_getStyle(comm, 'height');

        comm.overlay.style.display = 'none';
        comm.overlay.style.visibility = '';

        comm.style.display = 'none';
        comm.style.position = '';
        comm.style.visibility = '';
    }

    comm.scroll = img_makeScrollable();
    comm.appendChild(comm.scroll);
    comm.scroll.updateDim();

    comm.ajax_frame = comm.scroll.getInner();
    img_init_ajax_frame(comm.ajax_frame);
    comm.ajax_frame.onAjaxLoad = function() {
        var num_block = img_byClass(comm.ajax_frame, 'div', 'numComments');
        if (num_block) {
            var num = parseInt(num_block.innerHTML);
            if (!isNaN(num)) comm.overlay.active.setNumComments(num);
        }
    };
    comm.ajax_frame.onContentChange = function() {
        comm.scroll.updateDim();
    };

    comm.getAjax = function() {
        return comm.ajax_frame;
    };
    comm.getInner = function() {
        return comm.scroll.getInner();
    };
    comm.refreshInner = function() {
        comm.scroll.updateDim();
    };
    comm.isOpen = function() {
        return comm.state == 'open';
    };
    comm.isClosed = function() {
        return comm.state == 'closed';
    }
    comm.open = function() {
        comm.openAnd(null);
    };
    comm.openAnd = function(after) {
        if (img_onCommentsOpen) img_onCommentsOpen(comm);
        comm.style.height = '1px';
        comm.style.display = 'block';
        comm.state = 'animating';
        img_interpol().add(
			function(p) { var v = (p * comm.full_height); if (v < 1 || isNaN(v)) v = 1; comm.style.height = v + 'px'; comm.scroll.updateDim(); },
			function() { comm.state = 'open'; if (after) after(); },
			comm.time
		);
    };
    comm.close = function() {
        comm.closeAnd(null);
    };
    comm.closeAnd = function(after) {
        if (!isNaN(comm.full_height)) comm.style.height = comm.full_height + 'px';
        comm.style.display = 'block';
        comm.state = 'animating';
        img_interpol().add(
			function(p) { var v = ((1 - p) * comm.full_height); if (v < 1 || isNaN(v)) v = 1; comm.style.height = v + 'px'; comm.scroll.updateDim(); },
			function() { comm.state = 'closed'; comm.style.display = 'none'; if (after) after(); },
			comm.time
		);
    };
    comm.hide = function() {
        comm.style.display = 'none';
        comm.state = 'closed';
    };
}

function img_interpolateVal(a, b, p) {
    return a + (b - a) * p;
}

function img_interpolateRect(a, b, p) {
    return {
        x: img_interpolateVal(a.x, b.x, p),
        y: img_interpolateVal(a.y, b.y, p),
        w: img_interpolateVal(a.w, b.w, p),
        h: img_interpolateVal(a.h, b.h, p)
    };
}

function img_init_rect(rect) {
    rect.getRect = function() {
        var x = 0, y = 0;
        var cur = rect;
        while (cur.offsetParent) {
            x += cur.offsetLeft;
            y += cur.offsetTop;
            cur = cur.offsetParent;
        }
        return { x: x, y: y, w: rect.offsetWidth, h: rect.offsetHeight };
    };
    rect.setRect = function(r) {
        if (!isNaN(r.x)) rect.style.left = r.x + 'px';
        if (!isNaN(r.y)) rect.style.top = r.y + 'px';
        if (r.w && !isNaN(r.w)) rect.style.width = r.w + 'px';
        if (r.h && !isNaN(r.h)) rect.style.height = r.h + 'px';
    };
    rect.animateTo = function(r, time, done) {
        var from = rect.getRect();
        var to = r;
        img_interpol().add(
			function(p) { rect.setRect(img_interpolateRect(from, to, p)) },
			function() { rect.setRect(to); if (done) done(); },
			time
		);
    };
    rect.is_rect = true;
}

function img_getMousePos(ev) {
    if (!ev) ev = window.event;
    if (ev.pageX || ev.pageY) return { x: ev.pageX, y: ev.pageY };
    else return {
        x: ev.clientX + document.body.scrollLeft - document.body.clientLeft,
        y: ev.clientY + document.body.scrollTop - document.body.clientTop
    };
}

function img_registerEvent(el, ev, cb) {
    if (el.addEventListener) el.addEventListener(ev, cb, false);
    else if (el.attachEvent) el.attachEvent('on' + ev, cb);
}

function img_unregisterEvent(el, ev, cb) {
    if (el.removeEventListener) el.removeEventListener(ev, cb, false);
    else if (el.detachEvent) el.detachEvent('on' + ev, cb);
}

function img_subVector(a, b) {
    return { x: a.x - b.x, y: a.y - b.y };
}

function img_addVector(a, b) {
    return { x: a.x + b.x, y: a.y + b.y };
}

function img_rectCenter(r) {
    return { x: r.x + (r.w / 2), y: r.y + (r.h / 2) };
};

function img_layRectCentered(r, c) {
    return { x: c.x - (r.w / 2), y: c.y - (r.h / 2), w: r.w, h: r.h };
};

function img_layRectInside(r, lim) {
    var ret = { x: r.x, y: r.y, w: r.w, h: r.h };

    var xd = (r.x + r.w) - (lim.x + lim.w);
    var yd = (r.y + r.h) - (lim.y + lim.h);
    if (xd > 0) ret.x -= xd;
    if (yd > 0) ret.y -= yd;

    if (ret.x < lim.x) ret.x = lim.x;
    if (ret.y < lim.y) ret.y = lim.y;

    return ret;
};

function img_getPageRect() {
    var ret = { x: 0, y: 0 };
    if (window.innerHeight && window.scrollMaxY) {
        ret.w = window.innerWidth + window.scrollMaxX;
        ret.h = window.innerHeight + window.scrollMaxY;
    } else if (document.body.scrollHeight > document.body.offsetHeight) {
        ret.w = document.body.scrollWidth;
        ret.h = document.body.scrollHeight;
    } else {
        ret.w = document.body.offsetWidth;
        ret.h = document.body.offsetHeight;
    }

    var scr = img_getScreenRect();
    ret.w = Math.max(ret.w, scr.w);
    ret.h = Math.max(ret.h, scr.h);

    return ret;
};

function img_getScreenRect() {
    return {
        x: img_selectDefined([self.pageXOffset, document.documentElement.scrollLeft, document.body.scrollLeft]),
        y: img_selectDefined([self.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop]),
        w: img_selectDefined([self.innerWidth, document.documentElement.clientWidth, document.body.clientWidth]),
        h: img_selectDefined([self.innerHeight, document.documentElement.clientHeight, document.body.clientHeight])
    };
}

function img_positionOverlay(overlay, w, h) {
    var rect = { x: 0, y: 0, w: w, h: h };
    var scr = img_getScreenRect();
    var page = img_getPageRect();
    rect = img_layRectCentered(rect, img_rectCenter(scr));
    rect = img_layRectInside(rect, page);
    return rect;
};

function img_hasClass(el, cl) {
    var a = el.className.split(' ');
    for (var i in a) {
        if (a[i] == cl) return true;
    }
    return false;
}

function img_make_shared_embed() {
    var emb = {
        obj: document.getElementsByTagName('object')[0],
        emb: document.getElementsByTagName('embed')[0],

        set: function(url) {
            document.img_qt.SetResetPropertiesOnReload(false);
            document.img_qt.SetURL(url);
        },

        resize: function(w, h) {
            var e = document.getElementsByTagName('embed');
            if (e.length > 0) {
                e[0].height = h;
                e[0].width = w;
            }
            var o = document.getElementsByTagName('object');
            if (o.length > 0) {
                o[0].height = h;
                o[0].width = w;
            }
        },

        place: function(x, y) {
            if (document.getElementById('img_qt_div') != null) {
                document.getElementById('img_qt_div').style.top = y + 'px';
                document.getElementById('img_qt_div').style.left = x + 'px';
            }
        },

        hide: function() {
            this.place(-10000, -10000);
        },

        pause: function() {
            document.img_qt.Stop();
        }
    }

    document.img_shared_embed = emb;
}

function img_shemb() {
    return document.img_shared_embed;
}

function img_init_image(thumbnail) {
    var img = document.createElement('img');
    img.className = 'imagePopupImage';
    img.src = thumbnail.full_src;

    img_init_dragpoint(img);

    img.waitForPreload = function(done) {
        var tmp = new Image(); /* We must create it this way to make Opera happy */
        tmp.src = img.src;

        img_interpol().loop(function() {
            if (!tmp.complete) {
                thumbnail.start_loading_anim();
                return true;
            }
            img.full_x = tmp.width;
            img.full_y = tmp.height;
            thumbnail.stop_loading_anim();
            if (done) done();
        });
    };
    img_init_rect(img);
    img.setWidth = function(w) {
        var h = w * img.full_y / img.full_x;
        img.setDim(w, h);
    };
    img.setDim = function(w, h) {
        img.style.width = w + 'px';
        img.style.height = h + 'px';
    }

    return img;
}

function img_init_video(thumbnail) {
    var vid = document.createElement('div');
    vid.className = 'imagePopupImage';

    vid.innerHTML = '<img><iframe name="img_frm" frameborder=0 style="border: none;">';

    vid.img = vid.getElementsByTagName('img')[0];
    vid.frame = vid.getElementsByTagName('iframe')[0];

    vid.img.src = thumbnail.img.src;
    vid.img.style.visibility = 'hidden';
    vid.img.aspect = thumbnail.img.getRect().h / thumbnail.img.getRect().w;

    vid.full_x = 640;
    vid.full_y = 480;
    if (thumbnail.full_x) vid.full_x = thumbnail.full_x;
    if (thumbnail.full_y) vid.full_y = thumbnail.full_y;

    vid.cur_x = -1;
    vid.cur_y = -1;
    vid.video_visible = true;

    vid.style.textAlign = 'left';

    vid.waitForPreload = function(done) {
        img_interpol().loop(function() {
            if (done) done();
            return false;
        });
    };
    img_init_rect(vid);
    vid.setWidth = function(w) {
        if (w == vid.cur_x) return;
        var h = w * vid.full_y / vid.full_x;
        vid.setDim(w, h);
    };
    vid.setDim = function(w, h) {
        if (w == vid.cur_x && h == vid.cur_y) return;

        if (vid.anim && vid.video_visible) {
            vid.frame.style.position = 'absolute';
            vid.frame.style.left = '-10000px';
            vid.img.style.visibility = 'visible';
            vid.video_visible = false;
        }

        if (!vid.anim) {
            vid.frame.style.left = '';
            vid.frame.style.position = '';
        }

        if (vid.video_visible) {
            vid.frame.style.width = w + 'px';
            vid.frame.style.height = h + 16 + 'px';

            // resize inside

            if (vid.frame.contentDocument && vid.frame.contentDocument.img_qt) {
                vid.frame.contentDocument.img_qt.width = w;
                vid.frame.contentDocument.img_qt.height = h + 16;
            }

            if (window.attachEvent && !window.opera) { /* IE */
                if (window.frames && window.frames['img_frm'] && window.frames['img_frm'].img_qt) {
                    window.frames['img_frm'].img_qt.width = w;
                    window.frames['img_frm'].img_qt.height = h + 16;
                }
            }
        }

        if (vid.img) {
            vid.img.style.height = w * vid.img.aspect + 'px';
            vid.img.style.width = w + 'px';
        }

        vid.style.height = h + 16 + 'px';
        vid.style.width = w + 'px';

        vid.cur_x = w;
        vid.cur_y = h;
    }

    vid.onStartAnimation = function() {
        if (vid.frame.contentDocument && vid.frame.contentDocument.img_qt) vid.frame.contentDocument.img_qt.Stop();
        if (window.attachEvent && !window.opera) {
            if (window.frames && window.frames['img_frm'] && window.frames['img_frm'].img_qt) window.frames['img_frm'].img_qt.Stop();
        }
        vid.anim = true;
    };
    vid.onStopAnimation = function() {
        vid.anim = false;
        vid.video_visible = true;



        if (!vid.frame_loaded) {
            if (vid.img) vid.img.style.visibility = 'hidden';
            vid.frame.style.visibility = 'visible';

            var a = vid.cur_x;
            vid.cur_x = -1;
            vid.setWidth(a);

            var link = thumbnail.full_src;
            var x = vid.full_x;
            var y = vid.full_y + 16;

            var content = '<html><head><style>body {margin: 0; padding: 0; overflow: hidden;}</style></head><body><object id="img_qt" height="' + y + '" width="' + x + '" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab"><param name="movie" value="' + link + '"><param name="src" value="' + link + '"><param name="controller" value="true"><param name="autoplay" value="false"><param name="scale" value="aspect"><param name="wmode" value="transparent"><param name="cache" value="false"><param name="quality" value="high"><embed type="video/quicktime" src="' + link + '" id="img_qt_embed" name="img_qt" scale="aspect" enablejavascript="true" autoplay="false" width="' + x + '" height="' + y + '"></object></body></html>';
            var doc = vid.frame.contentDocument;
            if (doc == undefined || doc == null) doc = vid.frame.contentWindow.document;
            doc.open();
            doc.write(content);
            doc.close();

            img_interpol().add(function(p) { }, function() {
                var a = vid.cur_x;
                vid.cur_x = -1;
                vid.setWidth(a);
            }, 30);

            vid.frame_loaded = true;

        } else {

            vid.frame.style.width = vid.cur_x + 'px';
            vid.frame.style.height = vid.cur_y + 16 + 'px';

            if (vid.frame.contentDocument && vid.frame.contentDocument.img_qt) {
                vid.frame.contentDocument.img_qt.width = vid.cur_x;
                vid.frame.contentDocument.img_qt.height = vid.cur_y + 16;
            }

            if (window.attachEvent && !window.opera) { /* IE */
                if (window.frames && window.frames['img_frm'] && window.frames['img_frm'].img_qt) {
                    window.frames['img_frm'].img_qt.width = vid.cur_x;
                    window.frames['img_frm'].img_qt.height = vid.cur_y + 16;
                }
            }

            img_interpol().add(function(p) { }, function() {
                if (vid.img) vid.img.style.visibility = 'hidden';
                vid.frame.style.left = '';
            }, 100);
        }

    };

    return vid;
}

function img_init_dragpoint(dp) {
    dp.onmousedown = function(ev) {
        var cur = dp;
        while (cur && !cur.is_draggable) cur = cur.parentNode;
        if (cur.is_draggable) cur.startDrag(ev);
    }
    dp.is_dragpoint = true;
}

function img_init_draggable(drag) {
    drag.startDrag = function(ev) {
        if (drag.onStartDrag) drag.onStartDrag();
        drag.dragging = true;
        var mouse = img_getMousePos(ev);
        var pos = drag.getRect();
        drag.drag_diff = img_subVector(mouse, pos);

        img_registerEvent(document, 'mousemove', drag.mouseMove);
        img_registerEvent(document, 'mouseup', drag.endDrag);
        document.onmousedown = function() { return false; } /* This is used to prevent selection dragging bugs (found somewhere and it works) */
        return false;
    };
    drag.mouseMove = function(ev) {
        if (!drag.dragging) return;
        if (drag.onDrag) drag.onDrag();
        var mouse = img_getMousePos(ev);
        var diff = drag.drag_diff;
        var pos = img_subVector(mouse, diff);
        drag.setRect(pos);
        return false;
    };
    drag.endDrag = function() {
        drag.dragging = false;
        img_unregisterEvent(document, 'mousemove', drag.mouseMove);
        img_unregisterEvent(document, 'mouseup', drag.endDrag);
        document.onmousedown = null;
        if (drag.onEndDrag) drag.onEndDrag();
        return false;
    };
    drag.dragging = false;
    drag.drag_diff = null;
    drag.is_draggable = true;
    if (!drag.is_rect) img_init_rect(drag); /* rect must be implemented on draggable element */
}

function img_getStyle(el, style) {
    var r;
    if (document.defaultView && document.defaultView.getComputedStyle) {
        style = style.replace(/([A-Z])/g, '-$1').toLowerCase(); /* convert to dash notation */
        r = parseInt(document.defaultView.getComputedStyle(el, "").getPropertyValue(style));
    } else if (el.currentStyle) {
        r = parseInt(el.currentStyle[style]);
    }
    if (isNaN(r)) return 0;
    return r;
}

function img_init_overlay(overlay) {
    overlay.active = false;
    overlay.is_full = false;

    overlay.open = function() {
        if (overlay.is_movie) {
            if (img_active_movie) {
                img_active_movie.closeAnd(function() {
                    overlay.open();
                });
                return;
            } else {
                img_active_movie = overlay;
            }
        }

        overlay.showAnim(false);
    };
    overlay.openWithComments = function() {
        if (overlay.is_movie) {
            if (img_active_movie) {
                img_active_movie.closeAnd(function() {
                    overlay.openWithComments();
                });
                return;
            } else {
                img_active_movie = overlay;
            }
        }

        overlay.showWithComments();
    };
    overlay.close = function() {
        overlay.closeAnd(null);
    };
    overlay.closeAnd = function(done) {
        overlay.hideAnim(function() {
            if (overlay.active.whenClosed) {
                overlay.active.whenClosed();
            }
            overlay.detach();
            if (overlay.is_movie) {
                if (img_active_movie == overlay) img_active_movie = null;
            }
            if (done) done();
        });
    };
    overlay.setActive = function(thumbnail) {
        overlay.active = thumbnail;
        overlay.desc.innerHTML = thumbnail.desc.innerHTML;

        overlay.image_div.innerHTML = ''; /* clean up */
        overlay.full_image = img_init_image(thumbnail);

        if (thumbnail.popup_type == 'quicktime') {
            overlay.full_image = img_init_video(thumbnail);
            overlay.is_movie = true;
        } else {
            overlay.full_image = img_init_image(thumbnail);
            overlay.is_movie = false;
        }

        overlay.image_div.appendChild(overlay.full_image);
    };
    overlay.getImgRect = function() {
        if (overlay.__emb) {
            return overlay.__emb.getRect();
        } else if (overlay.__img) {
            return overlay.__img.getRect();
        }
        return { x: 0, y: 0, w: 200, h: 200 };
    }
    overlay.attach = function() {
        img_byTag(document, 'body').appendChild(overlay);
        if (overlay.is_movie) {
            overlay.style.zIndex = img_getStyle(overlay, 'zIndex') + 1;
        }
    };
    overlay.detach = function() {
        if (overlay.parentNode) overlay.parentNode.removeChild(overlay);
    };
    overlay.reattach = function() {
        if (!overlay.is_movie) {
            overlay.detach();
            overlay.attach();
        }
    };
    overlay.onStartDrag = function() {
        overlay.image_div.style.cursor = 'move';
        overlay.reattach();
        overlay.just_dragged = true;
    };
    overlay.onDrag = function() {
        overlay.just_dragged = false;
        if (overlay.full_image.onMove) overlay.full_image.onMove();
    };
    overlay.onEndDrag = function() {
        if (overlay.full_image.onMove) overlay.full_image.onMove();
        overlay.image_div.style.cursor = '';
        if (overlay.just_dragged) {
            overlay.close();
        }
    };
    overlay.rectThisToImage = function(r) {
        var div = overlay.img.parentNode; //!XXX maybe something more elegant...
        var inner = overlay.inner;
        var x_off = img_getStyle(inner, 'borderLeftWidth') + img_getStyle(div, 'marginLeft') + img_getStyle(overlay, 'paddingLeft');
        var y_off = img_getStyle(div, 'marginTop') + img_getStyle(overlay, 'paddingTop');
        var x_lose = x_off + img_getStyle(inner, 'borderRightWidth') + img_getStyle(div, 'marginRight') + img_getStyle(overlay, 'paddingRight');
        var y_lose = y_off + img_getStyle(div, 'marginBottom') + img_getStyle(overlay, 'paddingBottom'); //!XXX maybe not needed.
        return {
            x: r.x + x_off,
            y: r.y + y_off,
            w: r.w - x_lose,
            h: r.h - y_lose
        };
    };
    overlay.rectImageToThis = function(r) {
        var div = overlay.img.parentNode; //!XXX maybe something more elegant...
        var inner = overlay.inner;
        var x_off = img_getStyle(inner, 'borderLeftWidth') + img_getStyle(div, 'marginLeft') + img_getStyle(overlay, 'paddingLeft');
        var y_off = img_getStyle(div, 'marginTop') + img_getStyle(overlay, 'paddingTop');
        var x_lose = x_off + img_getStyle(inner, 'borderRightWidth') + img_getStyle(div, 'marginRight') + img_getStyle(overlay, 'paddingRight');
        var y_lose = y_off + img_getStyle(div, 'marginBottom') + img_getStyle(overlay, 'paddingBottom'); //!XXX maybe not needed.
        return {
            x: r.x - x_off,
            y: r.y - y_off,
            w: r.w + x_lose,
            h: r.h + y_lose
        };
    };

    overlay.image_this_const = null;
    overlay.initConsts = function() {
        var div = overlay.image_div;
        var inner = overlay.inner;
        overlay.image_this_const = (img_getStyle(inner, 'borderLeftWidth') + img_getStyle(inner, 'borderRightWidth') + img_getStyle(div, 'marginLeft') + img_getStyle(overlay, 'paddingLeft') + img_getStyle(div, 'marginRight') + img_getStyle(overlay, 'paddingRight'));
    };

    overlay.widthImageToThis = function(w) {
        if (!overlay.image_this_const) overlay.initConsts();
        return w + overlay.image_this_const;
    };
    overlay.widthThisToImage = function(w) {
        if (!overlay.image_this_const) overlay.initConsts();
        return w - overlay.image_this_const;
    };
    overlay.widthCommentsToThis = function(w) {
        var inner = overlay.inner;
        return w + img_getStyle(inner, 'borderLeftWidth') + img_getStyle(inner, 'borderRightWidth');
    };
    overlay.widthCommentsToImage = function(w) {
        var div = overlay.image_div;
        var inner = overlay.inner;
        return w - img_getStyle(div, 'marginLeft') - img_getStyle(overlay, 'paddingLeft') - img_getStyle(div, 'marginRight') - img_getStyle(overlay, 'paddingRight');
    };

    overlay.fitWidth = function() {
        var a = overlay.widthImageToThis(overlay.full_image.full_x);
        var b = img_getScreenRect().w - 32; /* Scrollbars */

        var base_height = overlay.active.getRect().h - overlay.active.img.getRect().h;
        var top_buttons = 0;
        top_buttons = Math.max(top_buttons, overlay.close_button.full_h);
        top_buttons = Math.max(top_buttons, overlay.move_area.full_h);
        base_height += top_buttons;

        var img_height = img_getScreenRect().h - base_height;
        var img_width = (overlay.full_image.full_x / overlay.full_image.full_y) * img_height;


        var c = overlay.widthImageToThis(img_width);

        var r = 'none';
        if (!isNaN(a) && (r == 'none' || a < r)) r = a;
        if (!isNaN(b) && (r == 'none' || b < r)) r = b;
        if (!isNaN(c) && (r == 'none' || c < r)) r = c;

        return r;
    };
    overlay.fullWidth = function() {
        return overlay.widthImageToThis(overlay.full_image.full_x);
    };
    overlay.commentsWidth = function() {
        return overlay.widthCommentsToThis(overlay.comments.full_width);
    };

    overlay.showAnim = function(with_comments) {
        var th = overlay.active;
        overlay.full_image.waitForPreload(function() {
            var w = overlay.fitWidth();
            overlay.showAnimCentered(w, false, function() {
                overlay.disableFull();
                overlay.showButtons();
                if (with_comments) overlay.comments.open();
            });
        });
    };

    overlay.showWithComments = function() {
        var th = overlay.active;
        overlay.full_image.waitForPreload(function() {
            var w = overlay.commentsWidth();
            overlay.showAnimCentered(w, true, function() {
                overlay.disableFull();
                overlay.full_button.style.display = 'none';
                overlay.comments.open();
            });
        });
    };

    overlay.showAnimCentered = function(w, with_comments, done_anim) {
        var initial_pos = overlay.active.getRect();
        if (overlay.active.popup_initial_width) {
            initial_pos.w = overlay.widthImageToThis(parseInt(overlay.active.popup_initial_width));
            initial_pos.x += (overlay.active.getRect().w - initial_pos.w) / 2;
        }

        if (overlay.full_image.onStartAnimation) overlay.full_image.onStartAnimation();

        overlay.showAt(initial_pos);

        var h = overlay.full_image.full_y * w / overlay.full_image.full_x;

        /* Modify height by the amount of elements under it - so the overlay is really centered */
        var the_h = overlay.getRect().h;
        the_h -= overlay.full_image.getRect().h;
        h += the_h;
        if (with_comments) h += overlay.comments.full_height;

        var top_buttons = 0;
        top_buttons = Math.max(top_buttons, overlay.close_button.full_h);
        top_buttons = Math.max(top_buttons, overlay.move_area.full_h);
        h += top_buttons;

        var dest = img_positionOverlay(overlay, w, h);

        dest.y += top_buttons;

        overlay.animateToDimensions(img_open_speed, dest, function() {
            if (overlay.full_image.onStopAnimation) overlay.full_image.onStopAnimation();
            if (done_anim) done_anim();
        });
    }

    overlay.openComments = function() {
        overlay.reattach();
        if (overlay.comments.isOpen()) return;

        if (overlay.full_image.onStartAnimation) overlay.full_image.onStartAnimation();

        overlay.disableFull();
        var w = overlay.commentsWidth();
        overlay.full_button.style.display = 'none';
        overlay.animateToWidth(img_comments_transition_speed, w, function() {
            if (overlay.full_image.onStopAnimation) overlay.full_image.onStopAnimation();
            overlay.comments.open();
        });
    };
    overlay.closeComments = function() {
        if (overlay.active.has_image_view) {
            overlay.reattach();
            if (!overlay.comments.isOpen()) return;

            var w = overlay.fitWidth();

            if (overlay.full_image.onStartAnimation) overlay.full_image.onStartAnimation();

            overlay.comments.closeAnd(function() {
                overlay.animateToWidth(img_comments_transition_speed, w, function() {
                    overlay.showButtons();
                    if (overlay.full_image.onStopAnimation) overlay.full_image.onStopAnimation();
                });
            });
        } else { /* If the full image view is not present (handled by external script), close overlay instead of switching views */
            overlay.close();
        }
    };

    overlay.showButtons = function() {
        if (!overlay.buttons_hidden) return;
        overlay.buttons_hidden = false;

        img_interpol().add(
			function(p) {
			    var v = ((p) * overlay.close_button.full_h);
			    if (v < 1 || isNaN(v)) v = 1;
			    overlay.close_button.style.top = '-' + v + 'px';
			    overlay.close_button.style.height = v + 'px';
			    overlay.close_button.style.display = 'block';
			},
			null,
			img_top_button_speed
		);

        img_interpol().add(
			function(p) {
			    var v = ((p) * overlay.move_area.full_h);
			    if (v < 1 || isNaN(v)) v = 1;
			    overlay.move_area.style.top = '-' + v + 'px';
			    overlay.move_area.style.height = v + 'px';
			    overlay.move_area.style.display = 'block';
			},
			null,
			img_top_button_speed
		);

        if (overlay.isFull()) overlay.full_button.style.display = 'none';
        else overlay.full_button.style.display = '';
    };
    overlay.hideButtons = function() {
        if (overlay.buttons_hidden) return;
        overlay.buttons_hidden = true;

        overlay.full_button.style.display = 'none';
        overlay.close_button.style.display = 'none';
        overlay.move_area.style.display = 'none';
    };

    overlay.enableFull = function() {
        overlay.is_full = true;
        overlay.showButtons();
    };
    overlay.disableFull = function() {
        overlay.is_full = false;
        overlay.showButtons();
    };
    overlay.isFull = function() {
        if (overlay.is_full || overlay.fullWidth() == overlay.fitWidth()) {
            return true;
        } else {
            return false;
        }
    };
    overlay.openFull = function() {
        overlay.reattach();
        if (overlay.full_image.onStartAnimation) overlay.full_image.onStartAnimation();
        overlay.enableFull();
        var w = overlay.fullWidth();
        overlay.animateToWidth(img_full_speed, w, function() {
            if (overlay.full_image.onStopAnimation) overlay.full_image.onStopAnimation();
        });
    };
    overlay.closeFull = function() {
        overlay.reattach();
        if (!overlay.isFull() || overlay.fullWidth() == overlay.fitWidth()) return;
        overlay.disableFull();
        var w = overlay.fitWidth();
        overlay.animateToWidth(img_full_speed, w, function() {
        });
    };

    overlay.toggleComments = function() {
        if (overlay.comments.isOpen()) overlay.closeComments();
        else if (overlay.comments.isClosed()) overlay.openComments();
    };

    overlay.hideAnim = function(done_anim) {
        var th = overlay.active;
        var from = overlay.getImgRect(); //overlay.img.getRect();
        var to = th.img.getRect();

        if (overlay.full_image.onStartAnimation) overlay.full_image.onStartAnimation();

        overlay.hideButtons();

        if (!overlay.comments.isClosed()) {
            if (overlay.comments.isOpen()) {
                overlay.comments.closeAnd(function() {
                    overlay.hideAnim(done_anim);
                });
            } else {
                img_interpol().loop(function() {
                    if (!overlay.comments.isClosed()) return true;
                    overlay.hideAnim(done_anim);
                    return false;
                });
            }
            return;
        }

        var initial_pos = overlay.active.getRect();
        if (overlay.active.popup_initial_width) {
            initial_pos.w = overlay.widthImageToThis(parseInt(overlay.active.popup_initial_width));
            initial_pos.x += (overlay.active.getRect().w - initial_pos.w) / 2;
        }

        overlay.animateToDimensions(img_close_speed, initial_pos, function() {
            overlay.style.display = 'none';
            if (done_anim) done_anim();
        });
    };

    overlay.animateToWidth = function(duration, to, done) {
        var ra = overlay.getRect();
        var rb = overlay.getRect();

        rb.w = to;
        // height stays 'the same', so top border will not move -- this is good

        rb = img_layRectCentered(rb, img_rectCenter(ra));
        rb = img_layRectInside(rb, img_getPageRect());
        overlay.animateToDimensions(duration, rb, done);
    };

    overlay.animateToDimensions = function(duration, to, done) {

        var from = overlay.getRect();
        img_interpol().add(function(p) {
            overlay.setDimensions(img_interpolateRect(from, to, p));
        }, function() { if (done) done(); }, duration);
    };

    overlay.setDimensions = function(pos) {

        if (!isNaN(pos.x)) overlay.style.left = pos.x + 'px';
        if (!isNaN(pos.y)) overlay.style.top = pos.y + 'px';

        var a = overlay.widthThisToImage(pos.w);
        var b = overlay.full_image.full_x;
        var width = Math.min(a, b);

        overlay.full_image.setWidth(width);

        if (!isNaN(pos.w)) overlay.style.width = pos.w + 'px';
    };
    overlay.showAt = function(pos) {
        overlay.setDimensions(pos);
        overlay.style.display = 'block';
        overlay.attach();
    };

    overlay.after_init = true;
}

function img_makeTag(parent, type, className, inner) {
    var el = document.createElement(type);
    if (className) el.className = className;
    if (inner) el.innerHTML = inner;
    parent.appendChild(el);
    return el;
}

function img_make_overlay(thumbnail) {
    var overlay = document.createElement('div');
    overlay.className = 'imageOverlay';
    overlay.style.position = 'absolute';
    overlay.style.display = 'none';
    var inner = img_makeTag(overlay, 'div', 'overlayInner', null); /* hack for different IE6 boxing model */
    overlay.inner = inner;
    overlay.image_div = img_makeTag(inner, 'div', 'imageDiv', null);
    overlay.full_button = img_makeTag(inner, 'div', 'imageFullButton', null);
    overlay.full_button.title = 'Expand to actual size';
    overlay.desc = img_makeTag(inner, 'div', 'imageTitle', null);
    overlay.close_button = img_makeTag(inner, 'div', 'imageCloseButton', null);
    overlay.move_area = img_makeTag(inner, 'div', 'imageMoveArea', null);

    img_init_dragpoint(overlay.move_area);

    if (thumbnail.download_button) {
        overlay.download_button = img_makeTag(inner, 'div', 'imageDownloadButton', thumbnail.download_button.innerHTML);
    }
    overlay.comments = img_makeTag(inner, 'div', 'imageComments', null);
    if (thumbnail.comments_button) {
        overlay.comments_button = img_makeTag(inner, 'div', 'imageCommentsButton', thumbnail.comments_button.innerHTML);
        overlay.comments_num = img_byClass(overlay.comments_button, 'span', 'imageNumComments');
    }

    img_init_rect(overlay);
    img_init_overlay(overlay);
    img_init_draggable(overlay);

    overlay.attach();

    /* Because of IE, getting styles can be done only after appending to
    * the rest of document. That is why comments are initialized after attach(); */
    img_init_comments(overlay.comments, overlay);

    overlay.close_button.full_h = img_getStyle(overlay.close_button, 'height');
    overlay.move_area.full_h = img_getStyle(overlay.move_area, 'height');

    overlay.detach();

    overlay.setActive(thumbnail);

    if (overlay.comments_button) {
        overlay.comments_button.onclick = function() {
            overlay.toggleComments();
        };
    }
    overlay.close_button.onclick = function() {
        overlay.close();
    };
    overlay.full_button.onclick = function() {
        overlay.openFull();
    }

    overlay.hideButtons();

    return overlay;
}

function img_parseValues(str, obj) {
    /* Parse string name=value pairs separated by semicolons and put into an object */
    var a = str.split(';');
    for (var i = 0; i < a.length; i++) {
        var v = a[i].split('=');
        if (v.length < 2) continue;

        while (v[0].charAt(0) == ' ' || v[0].charAt(0) == '\n' || v[0].charAt(0) == '\t') {
            v[0] = v[0].substring(1, v[0].length);
        }
        while (v[1].charAt(0) == ' ' || v[1].charAt(0) == '\n' || v[1].charAt(0) == '\t') {
            v[1] = v[1].substring(1, v[1].length);
        }

        if (v[1].match(/^[0-9]*$/)) v[1] = parseInt(v[1]);

        if (v[1] == 'true' || v[1] == 'yes') v[1] = true;
        if (v[1] == 'false' || v[1] == 'no') v[1] = false;

        obj[v[0]] = v[1];
    }
}

function img_init_thumbnail(thumbnail) {

    /* Nasty chunk of code, rebuilding the thumbnail markup */
    thumbnail.img = img_byTag(thumbnail, 'img');
    thumbnail.download_button = img_byClass(thumbnail, 'div', 'imageDownloadButton');
    thumbnail.comments_button = img_byClass(thumbnail, 'div', 'imageCommentsButton');
    thumbnail.comments_num = img_byClass(thumbnail, 'span', 'imageNumComments');

    thumbnail.inner = img_makeTag(thumbnail, 'div', 'thumbnailInner');
    var inner = thumbnail.inner;

    thumbnail.image_slot = thumbnail.img.parentNode;

    if (thumbnail.download_button) {
        thumbnail.removeChild(thumbnail.download_button);
    }
    if (thumbnail.comments_button) {
        thumbnail.removeChild(thumbnail.comments_button);
    }

    /* loading anim */
    thumbnail.loading_anim = img_makeTag(inner, 'div', 'imageLoadingIcon', null);
    thumbnail.loading_anim.style.display = 'none';

    /* Full source */
    thumbnail.full_src = thumbnail.image_slot.href;
    if (thumbnail.image_slot) thumbnail.removeChild(thumbnail.image_slot);

    /* Default parameters */
    thumbnail.has_image_view = true;
    thumbnail.popup_initial_width = null;
    thumbnail.popup_type = 'image';

    /* Load parameters and dispose the block */
    thumbnail.params = img_byClass(thumbnail, 'div', 'imageParamBlock');
    if (thumbnail.params) {
        img_parseValues(thumbnail.params.innerHTML, thumbnail);
        thumbnail.params.parentNode.removeChild(thumbnail.params);
    }

    if (thumbnail.has_image_view) {
        thumbnail.className = 'imageContainer enabledPopup';
    } else {
        thumbnail.className = 'imageContainer disabledPopup';
    }

    /* image with surrounding rect (now this is a transformed 'a' tag) */
    inner.appendChild(thumbnail.image_slot);

    /* title */
    thumbnail.desc = img_makeTag(inner, 'div', 'imageTitle', thumbnail.img.title);

    /* buttons */
    if (thumbnail.download_button) {
        inner.appendChild(thumbnail.download_button);
    }
    if (thumbnail.comments_button) {
        inner.appendChild(thumbnail.comments_button);
    }

    img_init_rect(thumbnail);
    img_init_rect(thumbnail.img);
    img_init_rect(thumbnail.image_slot);

    /* Resize to fit image */
    thumbnail.style.visibility = 'hidden';

    var img = new Image();
    img.src = thumbnail.img.src;
    img_interpol().loop(function() {
        if (!img.complete) return true;
        thumbnail.fitImage();
        thumbnail.style.visibility = 'visible';
        return false;
    });

    thumbnail.image_slot.onclick = function() {
        if (thumbnail.has_image_view) {
            thumbnail.open();
        }
        return false;
    };

    if (thumbnail.comments_button) {
        thumbnail.comments_button.onclick = function() {
            thumbnail.openWithComments();
        };
    }

    thumbnail.overlay = null;

    thumbnail.fitImage = function() {
        var image_width = null;

        if (thumbnail.img.width) {
            image_width = thumbnail.img.width;
        }
        if (thumbnail.img.style.width) {
            image_width = parseInt(thumbnail.img.style.width);
        }

        var div = thumbnail.image_slot;
        var inner = thumbnail.inner;
        var outer_width = 0 + image_width + img_getStyle(inner, 'borderLeftWidth') + img_getStyle(inner, 'borderRightWidth') + img_getStyle(div, 'marginLeft') + img_getStyle(thumbnail, 'paddingLeft') + img_getStyle(div, 'marginRight') + img_getStyle(thumbnail, 'paddingRight');

        var inner_width = outer_width - img_getStyle(inner, 'borderLeftWidth') - img_getStyle(inner, 'borderRightWidth');

        if (!isNaN(outer_width)) thumbnail.style.width = outer_width + 'px';
        if (!isNaN(inner_width)) inner.style.width = inner_width + 'px';
    };
    thumbnail.isOpen = function() {
        if (thumbnail.overlay) return true; else return false;
    };
    thumbnail.open = function() {
        if (thumbnail.isOpen()) {
            if (thumbnail.overlay.comments.isOpen()) thumbnail.overlay.closeComments();
            else thumbnail.overlay.close();
        } else {
            thumbnail.overlay = img_make_overlay(thumbnail);
            thumbnail.overlay.open();
        }
    };
    thumbnail.openWithComments = function() {
        if (thumbnail.isOpen()) {
            if (!thumbnail.overlay.comments.isOpen()) thumbnail.overlay.openComments();
            else thumbnail.overlay.close();
        } else {
            thumbnail.overlay = img_make_overlay(thumbnail);
            thumbnail.overlay.openWithComments();
        }
    };
    thumbnail.whenClosed = function() {
        thumbnail.overlay = null;
    };
    thumbnail.start_loading_anim = function() {
        thumbnail.loading_anim.style.display = 'block';
    };
    thumbnail.stop_loading_anim = function() {
        thumbnail.loading_anim.style.display = 'none';
    };
    thumbnail.setNumComments = function(n) {
        if (img_onUpdateNumComments) img_onUpdateNumComments(thumbnail, n);

        if (!thumbnail.comments_num) return;
        thumbnail.comments_num.innerHTML = n;
        if (thumbnail.isOpen()) {
            thumbnail.overlay.comments_num.innerHTML = n;
        }
    };

    if (img_onInitThumbnail) img_onInitThumbnail(thumbnail);

    thumbnail.is_thumbnail = true;
}

function img_ajax_request(address, data, success, fail) {
    var ajax = null;

    if (window.XMLHttpRequest) {
        ajax = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        try {
            ajax = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                ajax = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) { }
        }
    }

    if (!ajax) {
        alert('Error, your browser doesn\'t support AJAX.');
    }

    ajax.onreadystatechange = function() {
        if (ajax.readyState == 4) {
            if (ajax.status == 200) {
                if (success) success(ajax.responseText);
            } else {
                if (fail) fail();
            }
        }
    };

    /* Fix address issues */
    var a = address.split('?');
    var base_addr = '';
    var params = '';
    if (a.length > 0) base_addr = a.shift();
    if (a.length > 0) params = a.join('?');

    ajax.open("POST", base_addr + '?' + params, true);
    ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    ajax.setRequestHeader("Content-Length", data.length);
    ajax.send(data);
}

function img_init_ajax_frame(div) {
    div.is_ajax_frame = true;
    div.is_loading = false;

    div.load = function(url, params) {
        if (div.is_loading) return;
        div.setLoading(true);

        var pairs = [];
        for (var i in params) {
            if (i == '') continue;
            if (params[i] == '') {
                pairs.push(escape(i));
            } else {
                pairs.push(escape(i) + '=' + escape(params[i]));
            }
        }

        var data = pairs.join('&');

        img_ajax_request(url, data, function(resp) {
            div.setLoading(false);
            div.innerHTML = resp;

            /* Setup child forms to act inside ajax frame */
            var a = div.getElementsByTagName('form');
            for (var i = 0; i < a.length; i++) {
                img_setup_ajax_form(a[i]);
            }

            if (div.onContentChange) div.onContentChange();
            if (div.onAjaxLoad) div.onAjaxLoad();
        }, function() {
            div.setLoading(false);
            div.innerHTML = 'Error loading data.';
            if (div.onContentChange) div.onContentChange();
        });
    };

    div.setLoading = function(x) {
        if (x) {
            var msg = document.createElement('div');
            msg.className = 'ajaxLoading';
            div.appendChild(msg);
            if (div.onContentChange) div.onContentChange();
        } else {

        }
        div.is_loading = x;
    };

}

function img_parent_ajax_frame(el) {
    var cur = el;
    while (cur && !cur.is_ajax_frame) {
        cur = cur.parentNode;
    }
    return cur;
}

function img_on_ajax_link(ev) {
    var e = ev || event;
    var target = e.target || e.srcElement;
    var href = target.href;
    var par = img_parent_ajax_frame(target);
    par.load(href, {});

    return false;
}

function img_on_ajax_form(ev) {
    var e = ev || event;
    var form = e.target || e.srcElement;
    var par = img_parent_ajax_frame(form);

    var params = {};
    for (var i = 0; i < form.elements.length; i++) {
        params[form.elements[i].name] = form.elements[i].value;
    }

    par.load(form.action, params);

    return false;
}

function img_setup_ajax_form(f) {
    img_registerEvent(f, 'submit', function(ev) {
        img_on_ajax_form(ev);
        if (ev.preventDefault) ev.preventDefault();
        return false;
    });
}

function img_set_ajax_num_comments(el, num) {
    var par = img_parent_ajax_frame(el);
    par.thumbnail.setNumComments(num);
}

function img_initAllThumbnails() {
    var a = document.getElementsByTagName('div');
    for (var i = 0; i < a.length; i++) {
        if (a[i].className == 'imageContainer') {
            if (!a[i].is_thumbnail) {
                img_init_thumbnail(a[i]);
            }
        }
    }
}

function img_onInitThumbnail(th) {

}

/* Called when comment box is being opened */
function img_onCommentsOpen(comm) {
    comm.getAjax().load('comments.aspx', { id: comm.overlay.active.image_id });
};

/* Example. Insert desired num comments update handler */
function img_onUpdateNumComments(thumbnail, new_num) {
    try {
        var commentsnum = document.getElementById('hCommentsValue');
        var btn = document.getElementById('btnComments');

        if (btn != null && commentsnum != null) {
            var newnum = parseInt(commentsnum.getAttribute("value"));
            var count = newnum + 1;
            var total = "Comments ( " + newnum.toString() + " )";
            btn.innerHTML = total;
            commentsnum.setAttribute("Value", count);
        }
    }
    catch (Error) {
        //alert(Error);
    }
}

//img_registerEvent(window, 'load', function() {
//	img_make_shared_embed();
//	img_initAllThumbnails();
//});

function pageLoadedHandler(sender, args) {
    img_make_shared_embed();
    img_initAllThumbnails();
}

var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(pageLoadedHandler);

if (typeof (Sys) == 'undefined')
    Sys.Application.notifyScriptLoaded();  
