Ext.namespace("PBS.config");
PBS.config.server_url = '';
PBS.config.site_url = 'http://www.pbs.org/teacherline';
PBS.config.media_url = 'http://www-tc.pbs.org/teacherline/media/';
PBS.config.cookie_domain = '.pbs.org';
PBS.config.cookie_path = '/';
PBS.config.cookie_expires = new Date(new Date().getTime()+(1000*60*60*24*7)); // 7 days
Ext.BLANK_IMAGE_URL = 'http://www-tc.pbs.org/teacherline/media/js/ext/2/resources/images/default/s.gif';
Ext.namespace("PBS.messages");

PBS.messages.default_element = 'ajax_message';
PBS.messages.default_shim = 'ajax_message_shim';

PBS.messages.display = function(config) {
    var config = PBS.messages.clean_config(config);
    var message_content = [];
    var message_class = 'ajax_message_container ';

    if(config.type == 'error') {
        message_class += 'err';
    }
    else {
        message_class += 'msg';
    }

    if(!config.global) {
        // TODO: add correct positional direction... not just "e"
        message_class += ' tag ' + config.direction;
        message_content.push({tag:'div', cls:'point'});

        var shim_style = '';
        var r = PBS.utils.get_bounding_region([config.element]);
        if(config.direction == 'n') {
            shim_style = PBS.utils.printf('position:absolute;top:{0}px;;left:{1}px;height:{2}px;width:{3}px;',r.top,r.left,0,r.width);
        }
        else if(config.direction == 's') {
            shim_style = PBS.utils.printf('position:absolute;top:{0}px;;left:{1}px;height:{2}px;width:{3}px;',r.bottom,r.left,0,r.width);
        }
        else if(config.direction == 'e') {
            shim_style = PBS.utils.printf('position:absolute;top:{0}px;;left:{1}px;height:{2}px;width:{3}px;',r.top,r.right,r.height,0);
        }
        else if(config.direction == 'w') {
            shim_style = PBS.utils.printf('position:absolute;top:{0}px;;left:{1}px;height:{2}px;width:{3}px;',r.top,r.left,r.height,0);
        }
        var shim = Ext.DomHelper.append(PBS.messages.default_shim, {
            tag:'div', cls:'ajax_shim_container', style:shim_style
        });
        Ext.id(shim);
        config.element = shim.id;
    }

    // Continue setting up message
    if(config.header) {
        message_content.push({tag:'h3', html:config.header});
    }
    message_content.push({tag:'p', children: [{tag:'strong', html: config.message}]});

    // Create message
    var el = Ext.DomHelper.append(config.element, {
        tag:'div', cls: message_class, children: message_content
    });
    Ext.id(el);

    config.container = (!config.global) ? config.element : el.id;

    PBS.messages.completed();
    Ext.get(config.element).setStyle('display', 'block');

    var clear_message = function() {
        if(Ext.get(this.element)) {
            Ext.get(this.element).fadeOut({endOpacity: 0, duration: 2, remove: true});
        }
    };
    clear_message.defer(config.delay, {'element':config.container});

    Ext.get(el.id).on('click', function() {
        if(Ext.get(this.element)) {
            Ext.get(this.element).remove();
        }
    }, {'element':config.container});
};

PBS.messages.loading = function() {
    Ext.get('pop_over').setStyle('display', 'block');
    Ext.get('pop_over_loading').setStyle('display', 'block');
    Ext.get('pop_over_content').setStyle('display', 'none');
};

PBS.messages.completed = function() {
    Ext.get('pop_over_content').setStyle('display', 'none');
    Ext.get('pop_over_loading').setStyle('display', 'none');
    Ext.get('pop_over').setStyle('display', 'none');
};

PBS.messages.display_popover = function() {
    // TODO: this whole scroll to the top thing is a temporary hack for IE6.
    // IE6 does not like the document mask, or to scroll the popover to the current location.
    if (document.documentElement && document.documentElement.scrollTop) {
        document.documentElement.scrollTop = 0;
    }
    else {
        document.body.scrollTop = 0;
    }
    Ext.get('pop_over').setStyle('display', 'block');
    Ext.get('pop_over_loading').setStyle('display', 'none');
    Ext.get('pop_over_content').setStyle('display', 'block');
};

PBS.messages.clean_config = function(config) {
    config = config || {};
    config.global = (config.element) ? false : true;
    config.element = config.element || PBS.messages.default_element;
    config.direction = config.direction || 'e';
    config.delay = config.delay || 5000;
    config.type = config.type || 'general';
    config.header = config.header || undefined;
    config.message = config.message || '';
    return config;
};

//TODO: DELETE
PBS.messages.sample_text = function() {
    PBS.messages.display_popover();
    Ext.DomHelper.overwrite('pop_over_content', {
        tag: 'div', children: [
            {tag: 'p', children: [
                {tag: 'a', href: 'javascript:PBS.messages.completed();', html: 'close'}
            ]},
            {tag: 'h2', children: [
                {tag: 'span', html: 'Sample Rating Comment'}
            ]},
            {tag: 'p', cls: 'note', html: 'Provide an eye catching subject phrase that will convey how this particular resource extended your knowledge, how it could be used by others, and/ or why you would or not recommend it.'},
            {tag: 'p', html: 'Subject: Helping students to read their textbooks.'},
            {tag: 'p', cls: 'note', html: 'Provide a brief description of the usefulness of the resource, how did it extend your knowledge and/or how would you recommend others to use it.'},
            {tag: 'p', html: 'This resource extended my understanding of how to help students read their textbooks and why it is important that they become fluent readers in math &mdash; I recommend it to all content area teachers with students that struggle to read their textbooks.'}
        ]})
};
//////////////////////////////////////////////////////
// TEMPORARY JS
// These function brought in from old discussions.js
// TODO: Refactor these functions to conform to new JS style.
/////////////////////////////////////////////////////

/////////////////////////////////////////////
// Dashboard temp scripts
// TODO: Optimize and enhance these and dash functions.
////////////////////////////////////////////////////////

String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); };

function isArray(obj) {
    if (!obj) return false;

    if (obj.constructor.toString().indexOf("Array") == -1)
        return false;
    else
        return true;
}

function toggle_dash(target_el,toggle_link,cid) {
    var cname;
    if (Ext.get(target_el).hasClass('hidden')) {
        Ext.get(target_el).removeClass('hidden');
        Ext.get(toggle_link).update('[ - ]');
        cname= escape(toggle_link+cid);
        Ext.state.Manager.clear(cname);
    } else {
        Ext.get(target_el).addClass('hidden');
        Ext.get(toggle_link).update('[ &#43; ]');
        cname = escape(toggle_link+cid);
        Ext.state.Manager.set(cname, target_el);
    }
}

function init_dash(cid) {
    var i, toggle_link, cname;
    for(i=1; i<=6; i=i+1){
        toggle_link = "tog"+i;
        cname = escape(toggle_link + cid);
        if(Ext.state.Manager.get(cname)){
            Ext.get(Ext.state.Manager.get(cname)).addClass('hidden');
            Ext.get(toggle_link).update('[ &#43; ]');
        }
    }
}

// Generic paragraph truncate function.
// Takes in a string and truncates it by n number of words, optionally appending endStr if it is not empty.
// TODO:  Allow numWords argument for regex.
function truncate_string(paragraph, numWords, endStr){
    var first_words = paragraph.match(/^\s*(\w+\s){10}/g);
    var new_paragraph = paragraph;

    if (first_words) {
        new_paragraph = first_words[0];

        if (endStr != '')
            new_paragraph += endStr;
    }

    return new_paragraph;
}

/////////////////////////////////////////////
//generic confirmation alert box function
//send a custom message generated in the template
function confirm_alert(message) {
    var answer = confirm(message);
    if (answer){
        return true;
    }
    else{
        return false;
    }
}
//generic toggle display function
function toggle_display(id){
    Ext.get(id).toggleClass('hidden');
}

// Setup cookie state provider.
var cp = new Ext.state.CookieProvider({
    'path': PBS.config.cookie_path,
    'expires': PBS.config.cookie_expires,
    'domain': PBS.config.cookie_domain
});
Ext.state.Manager.setProvider(cp);

///////////////////////////////////////////
//// Client properties taken from Mootools
var Client = {
    Engine: {'name': 'unknown', 'version': ''},
    Platform: {},
    Features: {}
};

//Client.Features
Client.Features.xhr = !!(window.XMLHttpRequest);
Client.Features.xpath = !!(document.evaluate);

if (window.opera) {
    Client.Engine.name = 'opera';
}
else if(window.ActiveXObject) {
    Client.Engine = {'name': 'ie', 'version': (Client.Features.xhr) ? 7 : 6};
}
else if(!navigator.taintEnabled) {
    Client.Engine = {'name': 'webkit', 'version': (Client.Features.xpath) ? 420 : 419};
}
else if(document.getBoxObjectFor != null) {
    Client.Engine.name = 'gecko';
}
Client.Engine[Client.Engine.name] = Client.Engine[Client.Engine.name + Client.Engine.version] = true;

// Setup window indicators of browser type.
window[Client.Engine.name] = window[Client.Engine.name + Client.Engine.version] = true;

//Client.Platform
Client.Platform.name = navigator.platform.match(/(mac)|(win)|(linux)|(nix)/i) || ['Other'];
Client.Platform.name = Client.Platform.name[0].toLowerCase();
Client.Platform[Client.Platform.name] = true;

//enable background image cache for internet explorer 6
if (Client.Engine.ie6) {
    try { document.execCommand("BackgroundImageCache", false, true); } catch(e) {}
};

Ext.namespace("PBS.utils");
PBS.utils.prevent_multiple_submits = function() {
    Ext.select('form').each(function(el) {
        el.on('submit', function(e) {
            // If the form has already been submitted, prevent re-submission.
            if(this.submitted) {
                e.preventDefault();
            }
            // Otherwise submit the form, disable resubmission, then reenable submission after 4 seconds.
            else {
                this.submitted = true;

                var reenable_submission = function() {
                    this.submitted = false;
                };
                reenable_submission.defer(4000, this);
            }
        })
    });
};

PBS.utils.setup_popups = function(base_id) {
    base = Ext
    if(base_id) {
        base = Ext.get(base_id);
    }
    base.select('a[rel="external"]').each(PBS.utils.setup_popup);
};

PBS.utils.setup_popup = function(el) {
    if(typeof(el) == 'string') {
        el = Ext.get(el);
    }
    el.on('click', function(e, el) {
        if(top.opener && !top.opener.closed) {
            top.opener.location.href = el.href;
            top.opener.focus();
            e.preventDefault();
        }
        else {
            var win = window.open(el.href, "opener");
            win.focus();
            e.preventDefault();
        }
    });
};

PBS.utils.create_callback = function(config) {
    config.preprocess = config.preprocess || function(options, success, response) {
        PBS.messages.completed();
    };
    config.failure = config.failure || function(options, response) {
        if(response.statusText && response.statusText == 'transaction aborted') {
            PBS.messages.display({type:'error', header:'Whoops!', message:'Your request has timed out. Please try again soon.'});
        }
        else {
            PBS.messages.display({type:'error', header:'Whoops!', message:'An error occured while processing your request. Please try again soon.'});
        }
    };
    config.success = config.success || function(options, response, data) {};

    return function(options, success, response) {
        var data;
        config.preprocess(options, success, response);
        if(!success) {
            config.failure(options, response);
        }
        else {
            data = Ext.decode(response.responseText);
            config.success(options, response, data);
        }
    };
};

PBS.utils.setup_textbox_teasers = function(root) {
    if(!root) {
        root = document.body;
    }

    if(!Ext.get(root)) {
        return;
    }

    Ext.get(root).select('label.input_value').each(function(el) {
        var input, old, blur_teaser;
        if(el.dom.htmlFor && Ext.get(el.dom.htmlFor)) {
            input = Ext.get(el.dom.htmlFor);
            if(input.dom.value === '') {
                input.set({'value': el.dom.innerHTML});
            }
            old = el.dom.innerHTML;
            blur_teaser = function(e, el) {
                if(this.dom.value === '') {
                    this.dom.value = old;
                }
            };
            input.fix_teaser = blur_teaser;
            input.getValueNoTeaser = function() {
                if(this.dom.value != old) {
                    return this.dom.value;
                }
                else {
                    return '';
                }
            };

            input.on('focus', function(e, el) {
                if(this.dom.value == old) {
                    this.dom.value = '';
                }
            });

            input.on('blur', blur_teaser);
            if(Ext.get(input.dom.form)) {
                Ext.get(input.dom.form).on('submit', function(e, el) {
                    if(this.dom.value == old) {
                        this.dom.value = '';
                    }
                }, input);
            }
            el.setStyle('display', 'none');
        }
    });
};

PBS.utils.printf = function(ostr) {
    var num, pattern, re, i;
    num = arguments.length;
    for (i = 1; i < num; i=i+1) {
        pattern = "\\{" + (i-1) + "\\}";
        re = new RegExp(pattern, "g");
        ostr = ostr.replace(re, arguments[i]);
    }
    return ostr;
};

Ext.namespace("PBS.utils.opener");
PBS.utils.opener.captured_submit_button = null;
PBS.utils.opener.submit_to_opener = function(the_form) {
    // If the opener is no longer alive, then submit normally.
    if(!self.opener) {
        return true;
    }

    var ob, newform, el;
    try {
        ob = Ext.get(self.opener.document.body);
        newform = Ext.get(the_form).wrap({tag:'div'}).dom.cloneNode(true);

        el = ob.insertHtml('beforeEnd', newform.innerHTML, true);
        if(PBS.utils.opener.captured_submit_button !== null) {
            Ext.DomHelper.append(el, {tag:'input', type:'hidden', 'name':PBS.utils.opener.captured_submit_button[0], 'value': PBS.utils.opener.captured_submit_button[1]});
        }
        self.opener.document.forms[self.opener.document.forms.length-1].submit();
        self.close();
        return false;
    }
    catch(e) {
        return true;
    }
};

PBS.utils.opener.capture_submit_button = function(p_button) {
    PBS.utils.opener.captured_submit_button = [ p_button.name, p_button.value ];
};

PBS.utils.get_element_dimensions = function(el_id) {
    var region = Ext.get(el_id).getRegion();
    return {
        height: region.bottom - region.top,
        width: region.right - region.left
    };
};

PBS.utils.get_bounding_region = function(element_ids) {
    var region, i, el_region;
    region = {
        top: 999999999,
        right: 0,
        bottom: 0,
        left: 999999999
    };

    for(i=0; i<element_ids.length; i=i+1) {
        el_region = Ext.get(element_ids[i]).getRegion();
        region.top = Math.min(region.top, el_region.top);
        region.right = Math.max(region.right, el_region.right);
        region.bottom = Math.max(region.bottom, el_region.bottom);
        region.left = Math.min(region.left, el_region.left);
        region.height = region.bottom - region.top;
        region.width = region.right - region.left;
        region.center_x = region.left + (region.width / 2);
        region.center_y = region.top + (region.height / 2);
    }
    return region;
};

PBS.utils.MouseCaptureRegion = new function() {};

PBS.utils.MouseCaptureRegion.register = function(element_ids, callback, args) {
    var regions = [];
    for(var i=0; i<element_ids.length; i=i+1) {
        regions.push(PBS.utils.get_bounding_region([element_ids[i]]));
    }

    var mouse_out_event = function(e, el) {
        var pageX, pageY, do_callback, region;
        pageX = e.getPageX();
        pageY = e.getPageY();
        do_callback = true;

        for(var i=0; i<this.regions.length; i=i+1) {
            region = this.regions[i];
            if(pageX >= region.left && pageX <= region.right && pageY >= region.top && pageY <= region.bottom) {
                do_callback = false;
            }
        }

        if(do_callback) {
            Ext.EventManager.removeListener(document, "mousemove", PBS.utils.MouseCaptureRegion.current_listener);
            PBS.utils.MouseCaptureRegion.current_listener = undefined;
            this.callback(this.args);
        }
    };

    if(PBS.utils.MouseCaptureRegion.current_listener) {
        Ext.EventManager.removeListener(document, "mousemove", PBS.utils.MouseCaptureRegion.current_listener);
        PBS.utils.MouseCaptureRegion.current_listener = undefined;
    }
    PBS.utils.MouseCaptureRegion.current_listener = mouse_out_event;
    Ext.EventManager.addListener(document, "mousemove", mouse_out_event, {callback:callback, regions:regions, args:args});
};

PBS.utils.MouseCaptureRegion.unregister = function() {
    if(PBS.utils.MouseCaptureRegion.current_listener) {
        Ext.EventManager.removeListener(document, "mousemove", PBS.utils.MouseCaptureRegion.current_listener);
        PBS.utils.MouseCaptureRegion.current_listener = undefined;
    }
};

PBS.utils.dynamic_form_post = function(url, data) {
    var dh, form_field_tags, i, el, key;
    dh = Ext.DomHelper;

    // Remove old form.
    if(Ext.get('pbs_utils_formpost')) {
        Ext.get('pbs_utils_formpost').remove();
    }

    // Create field templates.
    form_field_tags = [];
    for(i=0; i<data.length; i=i+1) {
        for(key in data[i]) {
            form_field_tags.push({tag:'input', type:'hidden', name:key, value:data[i][key]});
        }
    }

    // Create dynamic form.
    el = Ext.DomHelper.append(document.body, {
        tag:'form', cls:'hidden', id:'pbs_utils_formpost', action:url, method:'post', children: form_field_tags
    });

    // Submit form.
    Ext.get('pbs_utils_formpost').dom.submit();
};
Ext.namespace("PBS.widgets.tooltip");

PBS.widgets.tooltip.database = {};
PBS.widgets.tooltip.element_database = {};

PBS.widgets.tooltip.register = function(key, header, content) {
    PBS.widgets.tooltip.database[key] = {'header':header, 'content':content};
};

PBS.widgets.tooltip.register("teacher_favorite", "Teacher Favorite", "These are some of our most popular courses.");
PBS.widgets.tooltip.register("classroom_link", "Classroom Link", "To get the most out of your experience, these courses ask learners to implement lessons with their class or with a small group of students (options for those without access to students are available).");

PBS.widgets.tooltip.get = function(key) {
    if(PBS.widgets.tooltip.database[key]) {
        return PBS.widgets.tooltip.database[key];
    }
    return null;
};

PBS.widgets.tooltip.display = function(element, key) {
    Ext.id(element);
    // If we have already setup this element, do nothing.
    if(PBS.widgets.tooltip.element_database[element.id]) {
        return;
    }
    
    // Record that we have setup the tooltip for this element.
    PBS.widgets.tooltip.element_database[element.id] = key;

    // First - try to get the tip from the provided key.
    var tip = PBS.widgets.tooltip.get(key);
    
    if(!tip) {
        // Second - try to get the tip from the elements classes.
        if(element.className) {
            var element_classes = element.className.split(" ");
            for(var i=0; i<element_classes.length; i++) {
                tip = PBS.widgets.tooltip.get(element_classes[i]);
                if(tip) {
                    break;
                }
            }
        }
        
        if(!tip) {
            // Third - try to get the tip from the element's title.
            if(!element.title) return;
            var parts = element.title.split("|");
            if(parts.length == 1) {
                tip = {'content':parts[0].trim()};
            }
            else if(parts.length == 2) {
                tip = {'header':parts[0].trim(), 'content':parts[1].trim()};
            }
            else {
                return;
            }
        }
    }
    element.title = "";
    
    Ext.get(element).on("mouseover", function(e, el) {
        var tip = this.tip;
        Ext.get('tip').setStyle('display', 'block');
        var tip_body = [];
        if(tip.header) {
            tip_body.push({tag:'h4', html: tip.header});
        }
        tip_body.push({tag:'p', html: tip.content});
        
        var el = Ext.DomHelper.overwrite('tip', {
            tag:'div', children: [
                    {tag:'div', id:'tip_content', cls:'content', children: tip_body},
                    {tag:'span', cls:'tl'},
                    {tag:'span', cls:'tr'},
                        {tag:'span', cls:'bl'},
                    {tag:'span', cls:'br'},
                    {tag:'span', cls:'point'}
            ]}, true);

        var element_region = PBS.utils.get_bounding_region([this.element_id]);
        var tip_region = PBS.utils.get_bounding_region(['tip']);
        
        // The CSS style drops the point of the tooltip below the height of the tip element, so account for it.
        var TIP_POINT_Y_OFFESET = 13;
        var TIP_POINT_X_OFFSET = 9;
        
        var tip_x = element_region.center_x - (tip_region.width / 2) - TIP_POINT_X_OFFSET;
        var tip_y = element_region.top - tip_region.height - TIP_POINT_Y_OFFESET;
        
        if(!Ext.get(this.element_id).hasClass('center_tip')) {
            tip_x = e.getPageX() - (tip_region.width / 2) - TIP_POINT_X_OFFSET;
        }
        Ext.get('tip').setXY([tip_x, tip_y]);
    }, {'tip':tip, 'element_id':element.id});
    
    Ext.get(element).on("mouseout", function(e, el) {
        Ext.get('tip').setStyle('display', 'none');
    }, {'element_id': element.id});
};

PBS.widgets.tooltip.setup = function(root) {
    if(!Ext.get('tip')) {
        Ext.DomHelper.append(document.body, {tag:'div', id:'tip'});
        Ext.get('tip').setStyle('position', 'absolute');
    }
    Ext.get('tip').setStyle('display', 'none');
    
    if(!root) {
        root = document.body;
    }
    
    if(Ext.get(root)) {
        Ext.get(root).select('.tip').each(function(el) {
            PBS.widgets.tooltip.display(el.dom);
        });
    }
};

Ext.onReady(function() {
    PBS.widgets.tooltip.setup();
});
