/**
 * @author gabriel.somoza
 */
//*** CLASS: ImagePreloader -----------------------
/*CONSTRUCTOR*/
function ImagePreloader(p_aImages, p_iPreloaderId, p_fCallbackFinished, p_fCallbackPercent){
    //Callback functions
    this.fCallbackFinished = p_fCallbackFinished;
    this.fCallbackPercent = p_fCallbackPercent;
    
    //Class member variables
    this.preloader_id = p_iPreloaderId;
    this.processed = 0;
    this.loaded = 0;
    this.section_images = p_aImages;
    this.aImages = new Array;
    this.image_count = p_aImages.length;
}

//METHODS
/* <<< preloadImages() >>>
 * Does the preloading. Sliced from the constructor to avoid incoherence.
 */
ImagePreloader.prototype.preloadImages = function(){
    //Preload all images in array
    for (var i = 0; i < this.section_images.length; i++) {
        this.Preload(this.section_images[i]);
    }
}

/* <<< OnComplete () >>> 
 * Called when image is loaded AND object properties are updated.
 * Raises "events" (calls callback functions) depending on overall progress.
 */
ImagePreloader.prototype.OnComplete = function(){
    this.processed++;
    if (this.processed == this.image_count) {
        if (this.fCallbackFinished) {
            this.fCallbackFinished(this);
        }
    }
    else {
        if (this.fCallbackPercent) {
            //this.fCallbackPercent(Math.round((this.processed / this.image_count)) * 100);
        }
    }
}

/* <<< OnLoad() >>> 
 * Called when an image is loaded in to cache.
 */
ImagePreloader.prototype.OnLoad = function(){
    // 'this' pointer points to oImage Object because this function was previously assigned
    // as an event-handler for the oImage Object.
    this.isLoaded = true;
    this.imagePreloader.loaded++; // Access our Class with the Reference assigned previously..
    this.imagePreloader.OnComplete();
}

/* <<< Preload (image_source) >>> 
 * Preloads a image from source.
 */
ImagePreloader.prototype.Preload = function(image){
    var img = new Image;
    
    img.onload = ImagePreloader.prototype.OnLoad;
    
    img.imagePreloader = this; // Give the Image Object a Reference to our Class..
    img.loaded = false; // Custom value added to track state
    //Start loading the image
    img.source = image.source; // Original Source Path to Image (for later use)
    img.src = image.source; // Image Object Source Path
    this.aImages.push(img);
}

//*** CLASS: Section -----------------------
//CONSTRUCTOR
function Section(first_id, length, file_prefix){
    this.first_id = first_id;
    this.length = length;
    this.last_id = first_id + length;
    this.file_prefix = file_prefix;
    this.loaded = false;
}

//METHODS
Section.prototype.setImageSources = function(image_array){
    this.images = image_array;
}
//------------------------------------------

//*** CLASS: Section_Image -----------------------
//CONSTRUCTOR
function Section_Image(source, html_ID){
    this.source = source;
    this.id = html_ID;
}

Section_Image.prototype.toString = function(){
    return this.source;
}
//------------------------------------------

var sections = new Array; // Array of Section classes
var preloaded_sections = new Array;

/* BUILD SECTIONS */
var i = 1; //control variable
//BRIDAL BOUQUETS
sections.push(new Section(i, 19, "bouquets"));
i = sections[sections.length - 1].last_id + 1;
//BRIDE'S MAID BOUQUETS
sections.push(new Section(i, 13, "bride_bouquets"));
i = sections[sections.length - 1].last_id + 1;
//CHURCH FLOWERS
sections.push(new Section(i, 11, "church_flowers"));
i = sections[sections.length - 1].last_id + 1;
//RECEPTION CENTER PIECES
sections.push(new Section(i, 19, "center_pieces"));
i = sections[sections.length - 1].last_id + 1;
//STANDING SPRAYS
sections.push(new Section(i, 15, "standing_sprays"));
i = sections[sections.length - 1].last_id + 1;
//CASKET SPRAYS
sections.push(new Section(i, 19, "casket_sprays"));
i = sections[sections.length - 1].last_id + 1;
//HEARTS
sections.push(new Section(i, 19, "hearts"));
i = sections[sections.length - 1].last_id + 1;
//WREATHS & CROSSES
sections.push(new Section(i, 15, "w_crosses"));
i = sections[sections.length - 1].last_id + 1;
//FUNERAL BASKETS
sections.push(new Section(i, 19, "funeral_baskets"));
i = sections[sections.length - 1].last_id + 1;
//CUSTOM DESIGNS
sections.push(new Section(i, 19, "funeral_custom"));
i = sections[sections.length - 1].last_id + 1;
//CUSTOM ARRANGEMENTS
sections.push(new Section(i, 19, "custom_arrange"));
i = sections[sections.length - 1].last_id + 1;
//PLANTS & DISHGARDENS
sections.push(new Section(i, 9, "plants_dish"));
i = sections[sections.length - 1].last_id + 1;
//FRUIT & GOURMET BASKETS
sections.push(new Section(i, 1, "gift_basket"));
i = sections[sections.length - 1].last_id + 1;
//STUFFED ANIMALS & BALLONS
sections.push(new Section(i, 10, "balloons_bears"));

//NOW REVERSE!! I found out the order in the HTML was upside-down
//(don't ask me why!) afterhand... thanks God, this fixes it!
/**sections.reverse();**/
/*----------------------------------------------*/

/* BUILDS IMAGES INTO SECTIONS */
/* And builds IDs for each image */
var sPath = "";

for (var i = 0; i < sections.length; i++) { //for each section in sections
    var a = []; //Start a new temp array
    var id_string = ""; //To build html ID
    current_section = sections[i];
    
    //Fill a[] with predifined image paths...
    j = 1;
    while (j <= current_section.length + 1) {
        sPath = "images/";
        sPath = sPath + current_section.file_prefix + "_";
        sPath = sPath + (j < 10 ? "0" + j : j) + ".jpg"; //converts numbers like "1" into "01" and adds ".jpg"
        id_string = "section" + (i+1) + "-" + j;
        a.push(new Section_Image(sPath, id_string)); //Progressively build the temp array
        j++;
    }
    current_section.setImageSources(a); //... so store it inside the appropriate section
}

//========================================================================================================================//

/* GET_ELEMENT
 * Gets an element in the best possible way supported
 */
function getElement(eid){
    if (document.all) {
        res = document.all[eid];
        if (typeof res == 'undefined') {
            return document.getElementById(eid);
        }
        return document.all[eid];
    }
    else {
        return document.getElementById(eid);
    }
}

/* ----------------------------------------------------
 * GLOBAL
 */
var requested_section = 0; //Stores the current requested section to load
var splash_hidden = false;
/* TOGGLE ----------------------------------------------------
 * Toggles visibility of an object (usually DIVs)
 */
function toggle(obj, show){
    var e = getElement(obj);
	
	//If "show" is set, then do accordingly
    if (show == true) {
        e.style.display = '';
        return;
    }else if(show == false){
		e.style.display = 'none';
		return;
	}
	
	//another option is that "show" is undefined, then...
    if (e.style.display != 'none') {
        e.style.display = 'none';
    }
    else {
        e.style.display = '';
    }
}

/* FINISHED Callback ----------------------------------------------------
 * Called when a preload has been finished. This is the meeting point
 * between automatic preloading and requested preloading.
 */
function pCallbackFinished(preloader){
    //wconsole("- Callback Finished: " + preloader.preloader_id);
    
    if (preloader.preloader_id == 'initialImages') {
        //wconsole("-- Initial Images Loaded!");
        //Show the initial images
        //wconsole("-- Showing Initial Images...");
        toggle('preloader_container');
        //wconsole("-- Initial Images Displayed!");
        //Load section 0 before finishing the initialization
        loadSection(0);
        return true;
    } //--------------------------------
    
    sectionLoaded(preloader.preloader_id);
}

/* FINISHED Callback ----------------------------------------------------
 * Called when a preload has been finished.
 */
function pCallbackPercent(percent){
    //	//wconsole("Percent: " + percent + "%");
}

/* PRELOAD ----------------------------------------------------
 * From here we control the preloading of the whole page.
 */
function init_page(){
    //First preload <preloader> images!
    a_images = new Array(new Section_Image("images/loading.gif", "0"), new Section_Image("images/img_home.jpg", "0"), new Section_Image("images/loading_spacer.png", "0"), new Section_Image("images/bg.jpg", "0"));
    //wconsole("Initializing Page...");
    //wconsole("- Hiding Preloader Images...");
    toggle('preloader_container');
    //toggle('preloader_loader');
    //wconsole("- Preloader Images Hidden!");
    try {
        var myPreloader = new ImagePreloader(a_images, "initialImages", pCallbackFinished, pCallbackPercent);
        myPreloader.preloadImages();
    } 
    catch (e) {
        //wconsole("ERROR: " + e);
    }
}

/* loadSection ----------------------------------------------------
 * Loads the specified section id (base 0)
 */
function loadSection(id){
    a_images = sections[id].images;
    //wconsole("Loading Section <b>" + id + "</b>...");
    var myPreloader = new ImagePreloader(a_images, id, pCallbackFinished, pCallbackPercent);
    myPreloader.preloadImages();
}

/* SECTIONS_LEFT ----------------------------------------------------
 * Returns the number of sections left to load.
 * Quite self-explanatory.
 */
function sectionsLeft(){

    sections_left = 0; //counter
    // cycle through the sections array to check how many sections are yet to load
    for (var i = 0; i < sections.length; i++) {
        if (!sections[i].loaded) {
            sections_left++;
        }
    }
    //wconsole("-- Sections Left: " + sections_left);
    return sections_left;
}

/* LOAD_NEXT_SECTION ----------------------------------------------------
 * Loads the next section in sequence.
 */
function loadNextSection(){
    //wconsole("- Loading Next Section...");
    if (requested_section == 0) {
        for (var i = 0; i < sections.length; i++) {
            if (!sections[i].loaded) {
                //Load next section after a short timeout (to avoid stack overflow)
                setTimeout(function(){
                    loadSection(i)
                }, 50);
                break;
            }
        }
    }
    else { //requested_section != 0
        if (!sections[requested_section].loaded) { 
            loadSection(requested_section);
        } else {
            requested_section = 0;
            loadNextSection();
        }
    }
}

/* SHOW_SECTION(section_id)
 * Called when a section is clicked.
 */
function hideSplash(){
	//If the page was loaded, but the user hasn't clicked on any section to view
	if(!splash_hidden){
		toggle('preloader_splash', false);
		//$$('preloader_splash').fade('out');
		toggle('wrapper', true); //Force gallery to show
		splash_hidden = true;
	}
}

/* SECTION_LOADED ----------------------------------------------------
 * Called when a section finished loading.
 * Made a function for readability.
 */
function sectionLoaded(section){
    sections[section].loaded = true;
	
    if (section == requested_section) {
        //wconsole("-- Section was Requeseted.")
        // Reset the pointer to the requested section to allow
        // other sections to load automatically.
        requested_section = 0;
    }
    //Finishing the if instead of using else-if for the next condition
    //allows to resume the auto loading of section once requested section
    //has finished loading
    
    //Put the images in the HTML
    buildHTML(section);
    //If no section is currently requested to load by user
    if (sectionsLeft() > 0) {
		setTimeout(function() { loadNextSection(); }, 50);
    }
    else {
		//Hide "Loading..." div
        toggle("preloader_loader", false);
        return;
    }
}

/* W_CONSOLE ----------------------------------------------------
 * Write to Console (for debugging).
 */
/*function wconsole(s){
     c = getElement('console');
    
     if (c) {
    
     try{
    
     c.innerHTML += s + "<br>";
    
     }catch(e){
    
     c_counter++;
    
     c.innerHTML = c_counter.toString();
    
     }
    
     }
}*/

/* BUILD_HTML
 * Puts the src attribute into corresponding image tags, to show them on the view.
 */
function buildHTML(section_id){
    //wconsole("-- Building HTML...")
    section = sections[section_id];
    
    for (var i = 0; i < section.images.length; i++) {
        img = section.images[i];
        //So, once we figured out the id, get the image...
        html_img = getElement(img.id);
        ////wconsole("-- Processing: " + img.id + " -> " + img.source);
        //... and set it's src property with the corresponding path.
        html_img.src = img.source;
        html_img.height = 360; //reset it to 360 AGAIN (if not, it doesn't resize)
    }
}

/* LOAD_SECTION_ON_DEMAND
 * Loads a section on-demand
 */
function loadSectionOnDemand(section_id){
    //Check that the section_id is within limits
    //0 is out of bounds because it's always loaded at init
    if (!(section_id > 0 && section_id <= sections.length - 1)) {
        throw "loadSectionOnDemand: Section_id out of bounds (value is " + section_id + ");"
        return;
    }
    //Do not allow to load more than one section at a time on demand,
    //and don't load if the section has already been loaded.
    if (requested_section == 0 && (!sections[section_id].loaded)) {
        requested_section = section_id;
        //will load as soon as the last active section finishes loading.
    }
}

