/*******************************************
* Overlay displayer                        *
* UbiCast 2009 - 2012, all rights reserved *
* Author: Stephane Diemer                  *
*******************************************/

/* supported modes and required params for each mode:
"images":
    resource = {
        mode: "image",
        url: "url of image",
        title: "The title", // optionnal
        on_hide: function () { } // optionnal
    };
    or
    resource = "url of image";
"iframe":
    resource = {
        mode: "iframe",
        url: "url of iframe",
        title: "The title", // optionnal
        on_hide: function () { } // optionnal
    };
"html":
    resource = {
        mode: "html",
        html: "html code",
        title: "The title", // optionnal
        on_hide: function () { } // optionnal
    };
*/

// global function
function isinstance(obj, type) {
    if (typeof obj == "object") {
        var matching = obj.constructor.toString().match(new RegExp(type, "i")); 
        return (matching != null);
    }
    return false;
}


function OverlayDisplayer(name) {
    // params
    this.enable_effects = true;
    this.enable_transition_effects = true;
    this.messages = {
        loading: "Loading ...",
        error: "Image not Found",
        previous: "Previous",
        next: "Next"
    };
    this.name = name;
    this.margin = 30;
    this.title_height = 30;
    
    // vars
    this.max_width = 0;
    this.max_height = 0;
    this.image = null;
    this.displayed = false;
    this.top_bar_displayed = false;
    this.display_mode = null;
    this.changing = false;
    this.next_command = null;
    this.resources = null;
    this.current_index = 0;
    this.current_resource = null;
    this.no_fixed = false;
    
    var obj = this;
    $(window).ready(function() {
        obj._init();
    });
    $(window).resize(function() {
        obj.on_resize();
    });
}

OverlayDisplayer.prototype._init = function () {
    var extra_class = "";
    if (navigator.platform == "iPad" || navigator.platform == "iPhone" || navigator.platform == "iPod") {
        this.enable_effects = false;
        this.enable_transition_effects = false;
        this.no_fixed = true;
        extra_class = "no-fixed";
    }
    var html = "";
    html += "<div id=\""+this.name+"\" class=\"overlay "+extra_class+"\">";
    html += "    <div class=\"overlay-aligner\">";
    html += "        <div class=\"overlay-layer\">";
    html += "            <table class=\"overlay-table\"><tr><td>";
    html += "                <div class=\"overlay-loading\"><div class=\"overlay-loading-content\">"+this.messages.loading+"</div></div>";
    html += "            </td></tr></table>";
    html += "        </div>";
    html += "        <div class=\"overlay-layer\">";
    html += "            <table class=\"overlay-table\"><tr><td>";
    html += "                <div class=\"overlay-error\"><div class=\"overlay-error-content\">"+this.messages.error+"</div></div>";
    html += "            </td></tr></table>";
    html += "        </div>";
    html += "        <div class=\"overlay-layer overlay-element-layer\">";
    html += "            <table class=\"overlay-table\"><tr><td><div class=\"overlay-block\">";
    html += "                <div class=\"overlay-top-bar\">";
    html += "                    <div class=\"overlay-title\"></div>";
    html += "                    <div class=\"overlay-resources\"></div>";
    html += "                    <div class=\"overlay-close\" onclick=\"javascript: "+this.name+".hide();\"></div>";
    html += "                </div>";
    html += "                <div class=\"overlay-element-container\">";
    html += "                    <div class=\"overlay-element-content\"></div>";
    html += "                    <div class=\"overlay-hover-loading\"><div>"+this.messages.loading+"</div></div>";
    html += "                    <div class=\"overlay-previous\" onclick=\"javascript: "+this.name+".previous();\">";
    html += "                        <table class=\"overlay-table\"><tr><td><div class=\"overlay-btn-bg\">";
    html += "                            <div class=\"overlay-btn-icon\">"+this.messages.previous+"</div></div></td></tr></table></div>";
    html += "                    <div class=\"overlay-next\" onclick=\"javascript: "+this.name+".next();\">";
    html += "                        <table class=\"overlay-table\"><tr><td><div class=\"overlay-btn-bg\">";
    html += "                            <div class=\"overlay-btn-icon\">"+this.messages.next+"</div></div></td></tr></table></div>";
    html += "                </div>";
    html += "            </div></td></tr></table>";
    html += "        </div>";
    html += "        <div class=\"overlay-layer overlay-closer\" onclick=\"javascript: "+this.name+".hide();\"></div>";
    html += "    </div>";
    html += "</div>";
    $("body").append(html);

    this.on_resize();
}

OverlayDisplayer.prototype.on_resize = function () {
    this.max_width = $(window).width() - this.margin;
    this.max_height = $(window).height() - this.margin;
    if (this.top_bar_displayed)
        this.max_height -= this.title_height;
    if (this.max_width > 0)
        $("#"+this.name+" .overlay-element").css("max-width", this.max_width+"px");
    if (this.max_height > 0)
        $("#"+this.name+" .overlay-element").css("max-height", this.max_height+"px");
}

OverlayDisplayer.prototype._check_next_command = function () {
    if (this.next_command != null) {
        var fct = this.next_command.fct;
        var params = this.next_command.params;
        this.next_command = null;
        if (fct == "go_to_index")
            this.go_to_index(params);
        else if (fct == "change")
            this.change(params);
        else if (fct == "show")
            this.show(params);
        else if (fct == "hide")
            this.hide();
    }
}

OverlayDisplayer.prototype._check_title_display = function (title) {
    if (title == $("#"+this.name+" .overlay-title").html())
        return;
    
    var obj = this;
    if ((!title && (this.resources == null || this.resources.length < 2)) && obj.top_bar_displayed) {
        if (obj.enable_effects && obj.displayed) {
            $("#"+obj.name+" .overlay-top-bar").slideUp("fast", function() {
                obj.top_bar_displayed = false;
                obj.on_resize();
                $("#"+obj.name+" .overlay-title").html("");
            });
        }
        else {
            $("#"+obj.name+" .overlay-top-bar").css("display", "none");
            obj.top_bar_displayed = false;
            obj.on_resize();
            $("#"+obj.name+" .overlay-title").html("");
        }
    }
    else if (title) {
        if (obj.top_bar_displayed && obj.displayed) {
            if (obj.enable_transition_effects) {
                $("#"+obj.name+" .overlay-title").fadeOut("fast", function() {
                    $("#"+obj.name+" .overlay-title").html(title);
                    $("#"+obj.name+" .overlay-title").fadeIn("fast");
                });
            }
            else {
                $("#"+obj.name+" .overlay-title").html(title);
            }
        }
        else {
            $("#"+obj.name+" .overlay-title").html(title);
            if (obj.enable_effects && obj.displayed) {
                $("#"+obj.name+" .overlay-top-bar").slideDown("fast", function() {
                    obj.top_bar_displayed = true;
                    obj.on_resize();
                });
            }
            else {
                $("#"+obj.name+" .overlay-top-bar").css("display", "block");
                obj.top_bar_displayed = true;
                obj.on_resize();
            }
        }
    }
    else if ((this.resources != null && this.resources.length > 1)) {
        if (!title && obj.top_bar_displayed) {
            if (obj.enable_effects && obj.displayed)
                $("#"+obj.name+" .overlay-title").fadeOut("fast", function() {
                    $("#"+obj.name+" .overlay-title").html("");
                });
            else
                $("#"+obj.name+" .overlay-title").html("");
        }
        else if (!obj.top_bar_displayed) {
            if (obj.enable_effects && obj.displayed) {
                $("#"+obj.name+" .overlay-top-bar").slideDown("fast", function() {
                    obj.top_bar_displayed = true;
                    obj.on_resize();
                });
            }
            else {
                $("#"+obj.name+" .overlay-top-bar").css("display", "block");
                obj.top_bar_displayed = true;
                obj.on_resize();
            }
        }
    }
}


//---------------------------
// Image management
//---------------------------
OverlayDisplayer.prototype._load_image = function (resource, callback) {
    if (this.display_mode != "image") {
        this.display_mode = "image";
        var html = "<img class=\"overlay-element\" src=\"\" style=\"max-width: "+this.max_width+"px; max-height: "+this.max_height+"px;\"/>";
        if (navigator.appVersion.indexOf("MSIE 6") != -1 || navigator.appVersion.indexOf("MSIE 7") != -1)
            html = "<a href=\"javascript: "+this.name+".hide();\">"+html+"</a>";
        $("#"+this.name+" .overlay-element-content").html(html);
    }
    else {
        if (this.image != null && this.image.source == resource.url)
            return callback(true);
    }
    
    if (this.resources == null || this.resources.length < 2) {
        // allow overlay hide by clicking on image
        $("#"+this.name+" .overlay-element").attr("onclick", "javascript: "+this.name+".hide();");
    }
    else {
        // disallow overlay hide by clicking on image
        $("#"+this.name+" .overlay-element").removeAttr("onclick");
    }
    
    $("#"+this.name+" .overlay-hover-loading").css("display", "block");
    this.image = new Image();
    this.image.source = resource.url;
    this.image.src = resource.url;
    if (this.image.complete) {
        this.on_image_load(resource, callback);
    }
    else {
        var obj = this;
        this.image.onload = function () { obj.on_image_load(resource, callback); }
        this.image.onabort = function () { obj.on_image_load(resource, callback); }
        this.image.onerror = function () { obj.on_image_error(resource, callback); }
    }
}
OverlayDisplayer.prototype.on_image_load = function (resource, callback) {
    var obj = this;
    if (this.enable_transition_effects) {
        $("#"+obj.name+" .overlay-element").fadeOut("fast", function() {
            $("#"+obj.name+" .overlay-element").attr("src", obj.image.source);
            $("#"+obj.name+" .overlay-error").css("display", "none");
            $("#"+obj.name+" .overlay-hover-loading").css("display", "none");
            obj._check_title_display(resource.title);
            
            $("#"+obj.name+" .overlay-element").fadeIn("fast", function() { callback(true); });
        });
    }
    else {
        $("#"+obj.name+" .overlay-element").css("display", "block");
        
        $("#"+obj.name+" .overlay-element").attr("src", obj.image.source);
        $("#"+obj.name+" .overlay-error").css("display", "none");
        $("#"+obj.name+" .overlay-hover-loading").css("display", "none");
        obj._check_title_display(resource.title);
        
        callback(true);
    }
}
OverlayDisplayer.prototype.on_image_error = function (resource, callback) {
    $("#"+this.name+" .overlay-element-layer").css("display", "none");
    $("#"+this.name+" .overlay-element").css("display", "none");
    $("#"+this.name+" .overlay-error").css("display", "block");
    $("#"+this.name+" .overlay-hover-loading").css("display", "none");
    this._check_title_display(resource.title);
    //this.display_mode = null;
    callback(false);
}

//---------------------------
// Iframe management
//---------------------------
OverlayDisplayer.prototype._load_iframe = function (resource, callback) {
    var width = this.max_width + "px";
    if (resource.width)
        width = resource.width;
    var height = this.max_height + "px";
    if (resource.height)
        height = resource.height;
    
    if (this.display_mode != "iframe") {
        this.display_mode = "iframe";
        var html = "<iframe class=\"overlay-element\" src=\""+resource.url+"\" style=\"width: "+width+"; height: "+height+"; margin: 0; padding: 0; border: 0 none; vertical-align: top;\"></iframe>";
        $("#"+this.name+" .overlay-element-content").html(html);
    }
    else {
        $("#"+this.name+" .overlay-element").css("width", width);
        $("#"+this.name+" .overlay-element").css("height", height);
    }
    
    $("#"+this.name+" .overlay-hover-loading").css("display", "block");
    var obj = this;
    if (this.enable_transition_effects) {
        $("#"+obj.name+" .overlay-element").fadeOut("fast", function() {
            $("#"+obj.name+" .overlay-element").attr("src", resource.url);
            $("#"+obj.name+" .overlay-error").css("display", "none");
            $("#"+obj.name+" .overlay-hover-loading").css("display", "none");
            obj._check_title_display(resource.title);
            
            $("#"+obj.name+" .overlay-element").fadeIn("fast", function() { callback(true); });
        });
    }
    else {
        $("#"+obj.name+" .overlay-element").css("display", "block");
        
        $("#"+obj.name+" .overlay-element").attr("src", resource.url);
        $("#"+obj.name+" .overlay-error").css("display", "none");
        $("#"+obj.name+" .overlay-hover-loading").css("display", "none");
        obj._check_title_display(resource.title);
        
        callback(true);
    }
}

//---------------------------
// HTML management
//---------------------------
OverlayDisplayer.prototype._load_html = function (resource, callback) {
    if (this.display_mode != "html") {
        this.display_mode = "html";
        var html = "<div class=\"overlay-element\" style=\"max-width: "+this.max_width+"px; max-height: "+this.max_height+"px;\"></div>";
        $("#"+this.name+" .overlay-element-content").html(html);
    }
    
    $("#"+this.name+" .overlay-hover-loading").css("display", "block");
    var obj = this;
    if (this.enable_transition_effects) {
        $("#"+obj.name+" .overlay-element").fadeOut("fast", function() {
            $("#"+obj.name+" .overlay-element").html(resource.html);
            $("#"+obj.name+" .overlay-error").css("display", "none");
            $("#"+obj.name+" .overlay-hover-loading").css("display", "none");
            obj._check_title_display(resource.title);
            
            $("#"+obj.name+" .overlay-element").fadeIn("fast", function() { callback(true); });
        });
    }
    else {
        $("#"+obj.name+" .overlay-element").css("display", "block");
        
        $("#"+obj.name+" .overlay-element").html(resource.html);
        $("#"+obj.name+" .overlay-error").css("display", "none");
        $("#"+obj.name+" .overlay-hover-loading").css("display", "none");
        obj._check_title_display(resource.title);
        
        callback(true);
    }
}

//---------------------------
// Resources list functions
//---------------------------
OverlayDisplayer.prototype.go_to_index = function (index) {
    if (index >= this.resources.length || index < 0)
        return;
    
    $("#"+this.name+" .overlay-resources").html((index + 1) + " / " + this.resources.length);
    if (index > 0)
        $("#"+this.name+" .overlay-previous").css("display", "block");
    else
        $("#"+this.name+" .overlay-previous").css("display", "none");
    if (index < this.resources.length - 1)
        $("#"+this.name+" .overlay-next").css("display", "block");
    else
        $("#"+this.name+" .overlay-next").css("display", "none");
    if (this.changing) {
        this.next_command = { fct: "go_to_index", params: index };
    }
    else {
        if (this.current_index != index) {
            this.changing = true;
            
            this.current_index = index;
            var params = this.resources[this.current_index];
            var resource;
            if (typeof params == "string")
                resource = { mode: "image", url: params };
            else
                resource = params;
            
            var obj = this;
            this._load_resource(resource, function (passed) {
                $("#"+obj.name+" .overlay-loading").css("display", "none");
                obj.changing = false;
                obj._check_next_command();
            });
        }
    }
}
OverlayDisplayer.prototype.next = function () {
    if (this.next_command != null && this.next_command.fct == "go_to_index") {
        index = this.next_command.params;
        if (this.resources != null && this.resources.length > 0 && index + 1 < this.resources.length)
            this.go_to_index(index + 1);
    }
    else {
        if (this.resources != null && this.resources.length > 0 && this.current_index + 1 < this.resources.length)
            this.go_to_index(this.current_index + 1);
    }
}
OverlayDisplayer.prototype.previous = function () {
    if (this.next_command != null && this.next_command.fct == "go_to_index") {
        index = this.next_command.params;
        if (this.resources != null && this.resources.length > 0 && index - 1 >= 0)
            this.go_to_index(index - 1);
    }
    else {
        if (this.resources != null && this.resources.length > 0 && this.current_index - 1 >= 0)
            this.go_to_index(this.current_index - 1);
    }
}



OverlayDisplayer.prototype._set_resources = function (params) {
    this.resources = null;
    this.current_index = 0;
    
    var first_resource;
    if (typeof params == "string") {
        $("#"+this.name+" .overlay-resources").css("display", "none");
        $("#"+this.name+" .overlay-previous").css("display", "none");
        $("#"+this.name+" .overlay-next").css("display", "none");
        first_resource = { mode: "image", url: params };
    }
    else if (isinstance(params, "array")) {
        this.resources = params;
        this.current_index = 0;
        if (params.start_index && params.start_index > 0 && params.start_index < params.length)
            this.current_index = params.start_index;
        if (params.length > 1) {
            $("#"+this.name+" .overlay-resources").html((this.current_index + 1) + " / " + params.length);
            $("#"+this.name+" .overlay-resources").css("display", "block");
            if (this.current_index > 0)
                $("#"+this.name+" .overlay-previous").css("display", "block");
            else
                $("#"+this.name+" .overlay-previous").css("display", "none");
            if (this.current_index < params.length - 1)
                $("#"+this.name+" .overlay-next").css("display", "block");
            else
                $("#"+this.name+" .overlay-next").css("display", "none");
        }
        else {
            $("#"+obj.name+" .overlay-resources").css("display", "none");
            $("#"+this.name+" .overlay-previous").css("display", "none");
            $("#"+this.name+" .overlay-next").css("display", "none");
        }
        if (typeof params[this.current_index] == "string")
            first_resource = { mode: "image", url: params[this.current_index] };
        else
            first_resource = params[this.current_index];
    }
    else {
        $("#"+this.name+" .overlay-resources").css("display", "none");
        $("#"+this.name+" .overlay-previous").css("display", "none");
        $("#"+this.name+" .overlay-next").css("display", "none");
        first_resource = params;
    }
    return first_resource;
}

OverlayDisplayer.prototype._load_resource = function (resource, callback) {
    var obj = this;
    if (resource.mode == "image") {
        // image mode
        // resource must contain: url
        obj._load_image(resource, function (passed) { obj.current_resource = resource; callback(passed); });
    }
    else if (resource.mode == "iframe") {
        // iframe mode
        // resource must contain: url
        obj._load_iframe(resource, function (passed) { obj.current_resource = resource; callback(passed); });
    }
    else if (resource.mode == "html") {
        // html mode
        // resource must contain: html
        obj._load_html(resource, function (passed) { obj.current_resource = resource; callback(passed); });
    }
    else {
        this.current_resource = resource;
        callback(false);
    }
}

OverlayDisplayer.prototype.change = function (params) {
    if (this.changing) {
        this.next_command = { fct: "change", params: params };
    }
    else {
        this.changing = true;
        
        var first_resource = this._set_resources(params);
        
        this._check_title_display(first_resource.title);
        $("#"+this.name+" .overlay-loading").css("display", "block");
        
        var obj = this;
        var element_layer_hidden = false;
        if (this.displayed && this.display_mode != first_resource.mode)
            element_layer_hidden = true;
        
        if (element_layer_hidden) {
            if (obj.enable_effects) {
                $("#"+obj.name+" .overlay-element-layer").fadeOut("fast", function() {
                    obj._execute_on_hide_callback();
                    obj._load_resource(first_resource, function (passed) {
                        $("#"+obj.name+" .overlay-loading").css("display", "none");
                        if (passed)
                            $("#"+obj.name+" .overlay-element-layer").fadeIn("fast");
                        obj.changing = false;
                        obj._check_next_command();
                    });
                });
            }
            else {
                $("#"+obj.name+" .overlay-element-layer").css("display", "none");
                obj._execute_on_hide_callback();
                obj._load_resource(first_resource, function (passed) {
                    $("#"+obj.name+" .overlay-loading").css("display", "none");
                    if (passed)
                        $("#"+obj.name+" .overlay-element-layer").css("display", "block");
                    obj.changing = false;
                    obj._check_next_command();
                });
            }
        }
        else {
            obj._execute_on_hide_callback();
            obj._load_resource(first_resource, function (passed) {
                $("#"+obj.name+" .overlay-loading").css("display", "none");
                obj.changing = false;
                obj._check_next_command();
            });
        }
    }
}

OverlayDisplayer.prototype.show = function (params) {
    if (this.changing) {
        this.next_command = { fct: "show", params: params };
    }
    else {
        if (this.displayed)
            return this.change(params);
        
        this.changing = true;
        
        var first_resource = this._set_resources(params);
        
        this._check_title_display(first_resource.title);
        $("#"+this.name+" .overlay-loading").css("display", "block");
        
        var obj = this;
        var element_layer_hidden = !this.displayed;
        if (this.display_mode != first_resource.mode) {
            $("#"+obj.name+" .overlay-element-layer").css("display", "none");
            element_layer_hidden = true;
        }
        
        this._show(function () {
            obj._load_resource(first_resource, function (passed) {
                $("#"+obj.name+" .overlay-loading").css("display", "none");
                if (element_layer_hidden && passed)
                    if (obj.enable_effects)
                        $("#"+obj.name+" .overlay-element-layer").fadeIn("fast");
                    else
                        $("#"+obj.name+" .overlay-element-layer").css("display", "block");
                obj.changing = false;
                obj._check_next_command();
            });
        });
    }
}

OverlayDisplayer.prototype.hide = function () {
    if (this.changing) {
        this.next_command = { fct: "hide", params: null };
    }
    else {
        if (!this.displayed)
            return;
        
        this.changing = true;
        var obj = this;
        this._hide(function () {
            obj._execute_on_hide_callback();
            obj.changing = false;
            obj._check_next_command();
        });
    }
}


OverlayDisplayer.prototype._show = function (callback) {
    if (this.displayed)
        return callback();
    
    $("#"+this.name+" .overlay-loading").css("display", "none");
    
    if (this.no_fixed) {
        //alert("ios " + $(document).width() + " " + $(document).height() + " " + $(document).scrollTop());
        $("#"+this.name).css("width", $(document).width()+"px");
        $("#"+this.name).css("height", $(document).height()+"px");
        $("#"+this.name+" .overlay-table").css("height", "auto");
        $("#"+this.name+" .overlay-block").css("margin-top", ($(document).scrollTop()+10)+"px");
    }
    
    var obj = this;
    if (this.enable_effects) {
        $("#"+obj.name).fadeIn("fast", function() {
            $("#"+obj.name+" .overlay-loading").css("display", "none");
            obj.displayed = true;
            callback();
        });
    }
    else {
        $("#"+obj.name).css("display", "block");
        obj.displayed = true;
        callback();
    }
}
OverlayDisplayer.prototype._hide = function (callback) {
    if (!this.displayed)
        return callback();
    
    var obj = this;
    if (this.enable_effects) {
        $("#"+obj.name).fadeOut("fast", function() {
            $("#"+obj.name+" .overlay-element-layer").css("display", "none");
            obj.displayed = false;
            callback();
        });
    }
    else {
        $("#"+obj.name).css("display", "none");
        $("#"+obj.name+" .overlay-element-layer").css("display", "none");
        obj.displayed = false;
        callback();
    }
}

OverlayDisplayer.prototype._execute_on_hide_callback = function () {
    if (this.current_resource == null || !this.current_resource.on_hide)
        return;
    
    try {
        this.current_resource.on_hide();
    }
    catch (e) {
        //alert(e);
    }
}


