Lvs = {};

Lvs.ImageLazyLoader = Class.create({
    img : null,

    loaded : false,

    initialize : function(img) {
        this.img = $(img);
    },

    wasLoaded : function() {
        return this.loaded;
    },

    isBelowTheFold : function() {
        return document.viewport.getHeight() + document.viewport.getScrollOffsets().top <= this.img.cumulativeOffset().top;
    },

    isAboveTheTop : function() {
        return document.viewport.getScrollOffsets().top >= this.img.cumulativeOffset().top + this.img.height;
    },

    lazyload : function() {
        if (!this.wasLoaded()) { this.load(); }
    },

    load : function() {
        if (!this.isAboveTheTop() && !this.isBelowTheFold()) {
            this.doLoad.bind(this).delay(0.1);
        }
    },

    doLoad : function() {
        this.img.src = this.img.attributes.getNamedItem('original').nodeValue;
        this.loaded = true;
    }
});

Lvs.ImageLoaderHandler = Class.create({
    className : null,

    objects : [],

    init : function() {
        this.initObjects();
        this.setObserver();
    },

    setClassName : function(className) {
        this.className = className;
    },

    initObjects : function() {
        this.getObjects().each(function(obj) { if (!obj.isBelowTheFold()) { obj.load(); } });
    },

    getObjects : function() {
        return this.objects.size() ? this.objects : this.createObjects();
    },

    createObjects : function() {
        this.objects = this.getImages().map(function(img) { return new Lvs.ImageLazyLoader(img); });
        return this.objects;
    },

    setObserver : function() {
        Event.observe(window, 'scroll', this.lazyload.bindAsEventListener(this));
    },

    getImages : function() {
        return $A(document.getElementsByClassName(this.className));
    },

    lazyload : function() {
        this.getObjects().each(function(obj) { obj.lazyload(); });
    }
});

Lvs.ImageLoaderHandlerModule = {
    getInstance : function() {
        if (this.instance === undefined) {
            this.instance = new this();
        }
        return this.instance;
    },

    regist : function(className) {
        Event.observe(window, 'load', function() { this.init(className); }.bindAsEventListener(this));
    },

    init : function(className) {
        if (this.isNotIE6()) {
            this.initLazyLoad(className);
        } else {
            this.initNotLazyLoad(className);
        }
    },

    initLazyLoad : function(className) {
        var handler = this.getInstance();
        handler.setClassName(className);
        handler.init();
    },

    initNotLazyLoad : function(className) {
        var handler = this.getInstance();
        handler.setClassName(className);
        handler.getObjects().each(function(obj) { obj.doLoad(); });
    },

    isNotIE6 : function() {
        return !Prototype.Browser.IE || (Prototype.Browser.IE && (typeof document.documentElement.style.maxHeight != "undefined"));
    }
};

Object.extend(Lvs.ImageLoaderHandler, Lvs.ImageLoaderHandlerModule);

Lvs.lazyLoadImage = function (className) {
    Lvs.ImageLoaderHandler.regist(className);
};
