/**** 
 * 
 * frameReady: Remote function calling for jQuery 
 * 
 * Version 1.2.0 
 * 
 * Copyright (c) 2007 Daemach (John Wilson) <daemach@gmail.com>, http://ideamill.synaptrixgroup.com 
 * Licensed under the MIT License: 
 * http://www.opensource.org/licenses/mit-license.php 
 *  
 *      Credit John Resig and his excellent book for the ready function concepts. 
 * 
 * ============================================================================================ 
 * Usage:       $.frameReady(function (function),target (string)[,options (map/object)]); 
 *  
 * Function: (function/required) An anonymous function to be run within the target frame. 
 * 
 * Target: (string/required) The target frame.  This must be a window object name (in quotes),  
 *              so work from the top down.  If you have 3 frames named topFrame, navFrame, mainFrame, and  
 *              an iframe inside of mainframe named iFrame, use "top.topFrame", "top.navFrame",  
 *              "top.mainFrame", "top.mainFrame.iFrame" respectively. 
 * 
 *      Options: (object/optional) Map of options in object literal form.  Options include: 
 * 
 *              remote: (boolean/ default true)  Run the function in the context of the target frame.  
 *                              If true, jQuery will be loaded in the target frame automatically and you can run  
 *                              jQuery selectors in the target frame as if they were local. ie: $("p") instead of  
 *                              $("p",top.mainFrame.document).  If false, jQuery will not be loaded automatically  
 *                              and you must use a context in jquery selectors. 
 *                               
 *                      load: (array or object)  jquery is loaded by default. You can pass a single object to  
 *                              frameReady, or an array of objects that will be loaded and tested in order.  2 types  
 *                              of files can be loaded.  Scripts        and stylesheets: 
 *                               
 *                              scripts: {type:"script", src:"/js/myscript.js", id:"_ms", test:"afunction"} 
 *                              stylesheets: {type:"stylesheet", src:"/css/mycss.css", id:"_ss"} 
 *                               
 *                                      type: (string/required) "script" for script files, "stylesheet" for stylesheets. 
 *                                      src: (string/required)  The source of the file, ie: /js/myscript.js. 
 *                                      id: (string/optional)  An id for the id attribute.  If one isn't provided it  
 *                                              will be generated. 
 *                                      test: (sting/optional) The name of a function that should exist once the script  
 *                                              is loaded properly.  Until this function becomes available, the script will  
 *                                              be considered not ready and no other files will be loaded.  If a test is not  
 *                                              provided, the next file will be loaded immediately.  Tests are not useful  
 *                                              with stylesheets. 
 * 
 *      One gotcha: You must have something other than space characters within the body tags of  
 *      target frame documents for frameReady to work properly.  A single character is enough.   
 *              The reason for this is a workaround for an iFrame bug in Firefox, of all things. 
 * ============================================================================================== 
 * 
 * Example:  
 * 
 *              $.frameReady(function(){ 
 *                $("<div>I am a div element</div>").prependTo("body"); 
 *              }, "top.mainFrame",  
 *              { load: [  
 *                      {type:"script",id:"_fr",src:"/js/jquery.frameReady.js",test: "$.frameReady"}, 
 *                      {type:"stylesheet",id:"_ss",src:"frameReady.css"}  
 *                      ] }  
 *              );  
 * 
 * 
 * Release Notes: 
 *       
 *      1.2.0 - Added provision for a local callback function; 
 *              Added functionality to reset frame information if frame unloads for any reason; 
 *                         
 *      1.1.0 - Added the ability to load scripts and stylesheets inside the target frame before 
 *                                      processing function stack; 
 *       
 ****/ 
  
if (typeof $daemach == "undefined") {  
        $daemach = {};  
        $daemach.debug = false;  // set this to true to enable logging 
        $daemach.log = function() { 
                if (!top.window.console || !top.window.console.log || !$daemach.debug) {  
                        return; 
                } else {  
                        top.window.console.log([].join.call(arguments,''));  
                } 
        } 
} 
 
if (typeof $daemach["frameReady"] == "undefined") {  
        $daemach["frameReady"] = {};  
} 
  
jQuery.frameReady = function(f,t,r,j) { 
         
        /************************************************************ 
                You must specify the path to your jquery.js file below!  
        *************************************************************/ 
         
        var jQueryPath = "/main/inc/lib/javascript/jquery.js"; 
         
        var u = "undefined";     
        var $fr = $daemach["frameReady"]; 
        var fn = t.split(".").join("_");         
        // create a branch 
        if (typeof $fr[fn] == u) {  
                $fr[fn] = {};  
                $fr[fn]["settings"] = {  
                        remote: true, 
                        jquery: true, 
                        load: [ {type:"script",id:"_jq", src:jQueryPath, test:"jQuery"} ], 
                        bLoaded: false, 
                        loadInit: [], 
                        callback: false 
                }; 
                $fr[fn]["target"] = t; 
        } 
        var fr = $fr[fn];        
        var frs = fr["settings"]; 
         
        if (fr.done) {  
                $daemach.log(fr.target + " is ready.  Running functions now."); 
                return (frs.remote) ? eval(fr.target).eval("(" + f.toString() + ")()") : f();  
        }; 
         
        // process arguments 
 
        for (var a=2;a<arguments.length;a++){ 
                var arg = arguments[a]; 
                 
                if ($.isFunction(arg)){ 
                        frs.callback = arg; 
                } else if (typeof arg == "object") { 
                        if (typeof arg.remote !== u) {  
                                frs.remote = arg.remote; 
                        }; 
                        if (typeof arg.jquery !== u) {  
                                frs.jquery = arg.jquery; 
                        }; 
                         
                        // if we're not running functions in the remote frame itself, no need for jQuery 
                        if (!frs.remote || !frs.jquery) {  
                                frs.load.pop();  
                        } 
                         
                        if (typeof arg.load !== u) { 
                                var bl = true; 
                                if (arg.load.constructor == Array && arg.load.length){ 
                                        for (var i=0;i<arg.load.length;i++){ 
                                                bl = true; 
                                                for (var h=0;h<frs.load.length;h++){ 
                                                        if (frs.load[h].src == arg.load[i].src) { bl=false; }; 
                                                } 
                                                if (bl) { frs.load.push(arg.load[i]); } 
                                        } 
                                } else if (typeof arg.load == "object") { 
                                        for (var h=0;h<frs.load.length;h++){ 
                                                if (frs.load[h].src == arg.load.src) { bl=false; }; 
                                        } 
                                        if (bl) { frs.load.push(arg.load); } 
                                } 
                        } 
                } 
        } 
 
        if (fr.timer) { 
                fr.ready.push(f); 
        } else { 
                fr.ready=[f]; 
                if (typeof addEvent !== "undefined"){ addEvent(window,"load",function(){ jQuery.isFrameReady(fn); }); }; 
                fr.timer = setInterval(function(){ jQuery.isFrameReady(fn); },13); 
        } 
} 
 
jQuery.isFrameReady = function(fn){ 
        var u = "undefined";     
        var $d = $daemach; 
        var fr = $d["frameReady"][fn]; 
        var frs = fr["settings"]; 
         
        if (fr.done) { return false; }; 
 
        var fx = eval(fr.target); 
        $d.log(fn, ": New Pass. Checking target"); 
        // make sure we have a target 
        if (typeof fx !== "undefined") { 
                $d.log(fn, ": Found target.  Checking DOM"); 
                var fd = fx.document; 
                 
                // make sure we have a DOM 
                if (fd && fd.getElementsByTagName && fd.getElementById && fd.body && fd.body.innerHTML.length) { 
                         
                        $d.log(fn, ": Found DOM"); 
                         
                        if (frs.load.length && !frs.bLoaded){ 
                                for (var i=0;i<frs.load.length;i++){ 
                                        var s = frs.load[i]; 
                                        var _test; 
                                        try { _test = eval('typeof fx.'+s.test+ ' !== "undefined"'); }  
                                        catch(ex){ _test = false;} 
                                        finally { $d.log(fn, ": Running test for script ",i,". ", (_test || !s.test) ? "Passed.":"Failed."); } 
 
                                        if ((_test || !s.test) && frs.loadInit[i]) { 
                                                frs.bLoaded = (typeof s.test == u) ? true : _test;  
                                                continue;  
                                        } else { 
                                                frs.bLoaded = false; 
                                                if (typeof frs.loadInit[i] == u){ 
                                                        var id = s.id || "frs_"+i; 
                                                        switch (s.type) { 
                                                                case "script" : 
                                                                        $d.log(fn, ": Loading script "+ i + " (" + s.src + ")"); 
                                                                        var ele=fd.createElement('script'); 
                                                                        ele.setAttribute('id', id); 
                                                                        ele.setAttribute('src', s.src); 
                                                                        fd.getElementsByTagName("body")[0].appendChild(ele); 
                                                                        void(ele); 
                                                                        frs.loadInit[i] = true; 
                                                                        break 
                                                                case "stylesheet" : 
                                                                        $d.log(fn, ": Loading stylesheet "+ i + " (" + s.src + ")"); 
                                                                        var ele=fd.createElement('link'); 
                                                                        ele.setAttribute('id', id); 
                                                                        ele.setAttribute('href', s.src); 
                                                                        ele.setAttribute('rel', "stylesheet"); 
                                                                        ele.setAttribute('type', "text/css"); 
                                                                        fd.getElementsByTagName("body")[0].appendChild(ele); 
                                                                        void(ele); 
                                                                        frs.loadInit[i] = true; 
                                                                break 
                                                                default : 
                                                                        $d.log(fn, ": Script "+i+" has a bad or missing type attribute..." ); 
                                                        } 
                                                } 
                                                break; 
                                        } 
                                } 
                        } else { 
                                clearInterval(fr.timer);         
                                fr.timer = null; 
 
                                fr.ready.push(function(){ window.frameReadyUnload = function(root, fn){ $(window).bind("unload",function(){ root.jQuery.frameReady.unload(fn); }); } }); 
                                 
                                $d.log(fn, ": Processing function stack:"); 
                                for (var i=0; i<fr.ready.length;i++){ 
                                        (frs.remote) ? fx.eval("(" + fr.ready[i].toString() + ")()") : fr.ready[i](); 
                                } 
                                 
                                fx.frameReadyUnload(window,fn); 
                                 
                                $d.log(fn, ": Function stack processing complete."); 
                                 
                                // we're done here.  let's have a beer. 
                                fr.ready = null; 
                                fr.done=true; 
                                 
                                if (frs.callback){  
                                        $d.log(fn, ": Found a callback.  Executing..."); 
                                        frs.callback();  
                                } 
                        } 
                } 
        }  
 
        $d.log(fn, ":"); 
} 
 
jQuery.frameReady.unload = function(fn){ 
        $daemach.log("Frame " + fn + " is unloading.  Resetting state.") 
        $daemach["frameReady"][fn].done = false; 
        $daemach["frameReady"][fn]["settings"].bLoaded = false; 
        $daemach["frameReady"][fn]["settings"].loadInit = []; 
} 


