/*  Facebox for Prototype, version 1.1
 *
 *    Version 1.2        2009-10-19    :: Iframe support and a change in the way that classes are handled
 *    Version 1.1        2009-08-28
 *
 *  Version 1.1 By Keith Perhac http://blog.japanesetesting.com/
 *  Version 1.0 By Scott Davis, htp://blog.smartlogicsolutions.com
 *
 *  Heavily based on Facebox by Chris Wanstrath - http://famspam.com/facebox
 *  First ported to Prototype by Phil Burrows - http://blog.philburrows.com
 *
 *  Licensed under the MIT:
 *  http://www.opensource.org/licenses/mit-license.php
 *
 *
 *  Dependencies:   prototype & script.aculo.us + images & CSS files from original facebox
 *  
 *  Usage:          Append 'rel="facebox"' to an element to call it inside a so-called facebox.
 *                  Chaging the rel to "facebox[CLASSNAME1 CLASSNAME2 etc]" will append the class 
 *                  "CLASSNAME1 CLASSNAME2 etc" to the facebox content.
 *                  
 *                   Additionally, you can specify a link to be opened in an iframe by adding the
 *                  relation "iframe" to the link: ie.
 *                  rel="facebox iframe"
 *                  This can be combined with the class functions as well
 *                  rel="facebox[class1 class2] iframe"                
 *
 *--------------------------------------------------------------------------*/

var Facebox = Class.create({
    initialize    : function(extra_set){
        if ($('facebox')){
            Element.remove('facebox');
        }
        this.settings = {
            opacity        : 0.25,
            overlay        : true,
            fadeDuration   : 0.300,
            loading_image  : '/core/common/face/images/loading.gif',
            close_image    : '/core/common/face/images/closelabel.gif',
            image_types    : new RegExp('\.' + ['png', 'jpg', 'jpeg', 'gif'].join('|') + '$', 'i'),
            inited         : true,    
            facebox_html   : new Template('\
              <div id="facebox" style="display:none;"> \
                <div class="popup"> \
                  <table class="faceboxtable"> \
                    <tbody id="facebox-tbody"> \
                      <tr> \
                        <td class="tl"/><td class="b"/><td class="tr"/> \
                      </tr> \
                      <tr> \
                        <td class="b"/> \
                        <td class="body"> \
                          <div class="faceboxHeader"> \
                          </div> \
                          <div class="faceboxContent" id="facebox_content"> \
                          </div> \
                          <div class="faceboxFooter"> \
                            <a href="#" class="close"> \
                              <img src="#{close_image}" title="close" class="close_image" /> \
                            </a> \
                          </div> \
                        </td> \
                        <td class="b"/> \
                      </tr> \
                      <tr> \
                        <td class="bl"/><td class="b"/><td class="br"/> \
                      </tr> \
                    </tbody> \
                  </table> \
                </div> \
              </div>')
        };

        if (extra_set) Object.extend(this.settings, extra_set);
        $$('body').first().insert({bottom: this.settings.facebox_html.evaluate({close_image: this.settings.close_image})});


        this.preload = [ new Image(), new Image() ];
        this.preload[0].src = this.settings.close_image;
        this.preload[1].src = this.settings.loading_image;

        fb = this;
        $$('#facebox .b:first, #facebox .bl, #facebox .br, #facebox .tl, #facebox .tr').each(function(elem){
            fb.preload.push(new Image());
            fb.preload.slice(-1).src = elem.getStyle('background-image').replace(/url\((.+)\)/, '$1');
        });

        this.facebox = $('facebox');
        this.contentWrapper = this.facebox.select(".faceboxContent").first();
        this.header = $$('#facebox .body .faceboxHeader').first();
        this.footer = $$('#facebox .body .faceboxFooter').first();

        this.keyPressListener    = this.watchKeyPress.bind(this);
        this.overlayCloseClicker = this.close.bind(this)

        this.watchClickEvents();
        Event.observe($$('#facebox .close').first(), 'click', function(e){
            Event.stop(e);
            fb.close()
        });
        Event.observe($$('#facebox .close_image').first(), 'click', function(e){
            Event.stop(e);
            fb.close()
        });
        Event.observe(window, 'resize', function(e){
            fb.setLocation();
        });
    },
    
    watchKeyPress    : function(e){
        // Close if espace is pressed or if there's a click outside of the facebox
        if (e.keyCode == Event.KEY_ESC) {
            this.close();
        }
    },

    watchClickEvents    : function(){ 
        var f = this;       
        $$('a[rel^=facebox], img.facebox').each(function(elem){  
            elem.observe('click', function(evt){     
                // console.log("here's what f is :: "+ f);
                evt.stop();
                f.click_handler(elem, evt);
            });
        });
    },
    
    loading    : function() {
        if ($$('#facebox .loading').length == 1) return true;

//        contentWrapper = $$('#facebox .content').first();
//        contentWrapper.childElements().invoke("remove");
//        contentWrapper.insert({bottom: '<div class="loading"><img src="'+this.settings.loading_image+'"/></div>'});
//        this.contentWrapper.childElements().invoke("remove");
        this.contentWrapper.update('');
        this.contentWrapper.insert({bottom: '<div class="loading"><img src="'+this.settings.loading_image+'"/></div>'});

        this.setLocation();
        Event.observe(document, 'keypress', this.keyPressListener);
    },
    
    reveal    : function(data, klass, style){
        var fb = this;

        this.loading();
//        box = $('facebox');
//        if (!box.visible()) {
        if (!$('facebox').visible()) {
            fb.open();
        }

//        contentWrapper = $$('#facebox .content').first();
//        contentWrapper.className = 'content';
        this.contentWrapper.className = 'faceboxContent';

        if (klass) {
//            contentWrapper.addClassName(klass);
            this.contentWrapper.addClassName(klass);
        }

        //Set H/W or any other styles (also clears styles)
        this.contentWrapper.writeAttribute('style', style);
        
//        contentWrapper.childElements().invoke("remove");
//      contentWrapper.insert({bottom: data});
/*
        var content = new Element('div').update(data);
        var test = content.select("body");
        if (content.select("body").first() == null) {
            content = data;
        } else {
            content = content.select("body").innerHTML;
        }
        var el = new Element('div', {id: 'testMark'}).update(content);
*/
        var el = new Element('div').update(data);
        this.attachFormHandler(el);
//        contentWrapper.insert({bottom: el});

        this.contentWrapper.hide();
        this.contentWrapper.update(el);

if (Object.isElement(data)) {
    data.show();
}

        load = $$('#facebox .loading').invoke("remove");
//        $$('#facebox .body').first().childElements().invoke("show");

        if (Object.isElement(this.myElement)) {
            var fbTitle = this.myElement.readAttribute('title');
            if (fbTitle != null && fbTitle.length > 0) {
                this.contentWrapper.insert({
                    top: new Element('h1', {'class': 'faceboxTitle'}).update(fbTitle)
                });
            }
        }

        this.setLocation();
//        this.setLocation().delay(this.settings.fadeDuration+0.5);

        el.select("textarea.growable").each(function(ta){
            new GrowableTextarea(ta);
        });
        Event.observe(document, 'keypress', this.keyPressListener);
    },
    
    open    : function(){
        if ($('facebox_overlay') == null) {
            $$("body").first().insert('<div id="facebox_overlay" class="facebox_hide"></div>', 'bottom');
        }
        fb = this;
        $('facebox_overlay').hide().addClassName("facebox_overlayBG");
        $('facebox_overlay').observe('click', this.overlayCloseClicker);
//$('facebox_overlay').setOpacity(this.settings.opacity).show();
//$('facebox_overlay').setOpacity(0.7).show();
$('facebox_overlay').show();
$('facebox').show();
/*
        new Effect.Parallel([
            new Effect.Appear('facebox_overlay', {sync: true, to: this.settings.opacity}),
            new Effect.Appear('facebox', {sync: true})
        ], {duration: this.settings.fadeDuration});
*/
    },
    
    close        : function(){
        Event.stopObserving(document, 'keypress', this.keyPressListener);
        new Effect.Parallel([
            new Effect.Fade($('facebox_overlay'), {sync: true, from: this.settings.opacity}),
            new Effect.Fade($('facebox'),         {sync: true})
        ], {duration: this.settings.fadeDuration, afterFinish: function(){$$("#facebox_overlay").invoke("removeClassName", "facebox_overlayBG").invoke("addClassName", "facebox_hide");}});
    },
    
    setLocation: function(){
        if (!this.facebox.visible()) {
            return;
        }

        var pageScroll = document.viewport.getScrollOffsets();
/*
        $('facebox').setStyle({
            'top': pageScroll.top + (document.viewport.getHeight()/ 10) + 'px',
            'left': String(document.viewport.getWidth()/2 - $('facebox').getWidth()/2) + 'px'
        });
*/
        //$$('#facebox .body .footer').first().show();//childElements().invoke("show");
        this.footer.show();

        // BEGIN: Crapola to get the content height to be valid
        $('facebox').setStyle({
          'top': '5000px'
        });

        this.contentWrapper.setStyle({
            height: 'auto'
        });

        $$('#facebox .body').first().childElements().invoke("show");
        this.contentWrapper.show();
        $('facebox').show();

        var bogus;
        bogus = this.contentWrapper.getHeight();
        bogus = this.header.getHeight();
        bogus = this.footer.getHeight();
//        alert("content: "+contentHeight2);
//        $$('#facebox .body').first().childElements().invoke("show");
//        $('facebox').hide();
        // END: Crapola to get the content height to be valid

        var doWait = function(){
            $$('#facebox .body').first().childElements().invoke("show");

//            if (!Object.isUndefined(this.beforeResize) && Object.isFunction(this.beforeResize)) {
//                this.beforeResize();
//            }

            var minMarginPercentage = 0.025; // 2.5%
//          var contentHeight = this.contentWrapper.getHeight();
            var faceboxNonContentHeight;
            var maxViewHeight;

//          var contentWrapper = $$('#facebox .content').first();
            var contentHeight;
            if (this.facebox.hasClassName('iframe')) {
//                faceboxNonContentHeight = $('facebox').getHeight() - contentHeight;
    //            faceboxNonContentHeight = $('facebox').getHeight();
      //          faceboxNonContentHeight = 150;
                faceboxNonContentHeight  = this.header.getHeight();
                faceboxNonContentHeight += this.footer.getHeight();
                faceboxNonContentHeight += 40;  // border
  //              faceboxNonContentHeight -= $('facebox').select('tr').last().getHeight();
                maxViewHeight = Math.max(0, Math.round((1-2*minMarginPercentage)*(document.viewport.getHeight()-faceboxNonContentHeight)));
                contentHeight = maxViewHeight;

                var iframe = this.facebox.select('iframe').first();
                if (iframe != null) {
                    iframe.setStyle({height:maxViewHeight+'px'});
                }
            } else {
                contentHeight = this.contentWrapper.getHeight();
                faceboxNonContentHeight = $('facebox').getHeight() - contentHeight;
                maxViewHeight = Math.max(0, Math.round((1-2*minMarginPercentage)*(document.viewport.getHeight()-faceboxNonContentHeight)));
            }

//            var viewportHeight = document.viewport.getHeight()-100;
//            var maxViewHeight = Math.max(0, Math.round((1-2*minMarginPercentage)*(document.viewport.getHeight()-faceboxNonContentHeight)));
/*
            var minMarginTop = 0.025;
//            var maxViewHeight = Math.round(document.viewport.getHeight()*0.85)-100;
            var viewportHeight = document.viewport.getHeight()-100;
            var maxViewHeight = Math.round(document.viewport.getHeight()*(1-(2*minMarginTop)));
*/

            var top = Math.round(document.viewport.getHeight()*minMarginPercentage);
            if (contentHeight >= maxViewHeight) {
                this.contentWrapper.setStyle({
                    height: maxViewHeight+'px',
                    overflow: 'auto',
                    width: (this.contentWrapper.getWidth()+20)+'px'
                });
                $('facebox').setStyle({width: ($('facebox').getWidth()+20)+'px'});
            } else {
//                top += Math.max(0, Math.round((maxViewHeight-contentHeight)/2));
                top = Math.round((document.viewport.getHeight()-this.facebox.getHeight())*0.25);
            }
//            var left = Math.round((document.viewport.getWidth() - $('facebox').getWidth())/2);
            var newTop = (contentHeight < 5) ? (Math.round(document.viewport.getHeight()*minMarginPercentage)) : top;
            $('facebox').setStyle({
                'top': /*pageScroll.top + */newTop + 'px',
                'left': String(document.viewport.getWidth()/2 - $('facebox').getWidth()/2) + 'px'
            });
            this.contentWrapper.show();
        }
        doWait.bind(this).defer();
    },
    
    new_box_for_url: function(url) {
        var fb = this;
        fb.open();
        var klass = '';
        var style = 'display:block; width:800px;';
        fb.ajax(url, klass, style);
    },
    
    ajax: function(url, klass, style){
        var urlExtra = (String(url).include('?')) ? '&ajax=1' : '?ajax=1'

        var fb = this;
        new Ajax.Request(url + urlExtra, {
            method: 'get',
            evalScripts: true,
            onFailure: function(transport){
                fb.reveal(transport.responseText, klass, style);
            },
            onComplete: function(transport){
                fb.reveal(transport.responseText, klass, style);
            },
            onException: function(){
                alert('exception');
            }
        });
    },
    
    click_handler    : function(elem, e){
        this.facebox.removeClassName('iframe');
        this.contentWrapper.update('');

        elem = $(elem);
        this.myElement = $(elem);

        this.beforeResize = null;

        var klass = '';
        var style = '';
        if (elem.hasAttribute('rel')) {
            // support for rel="facebox[inline_popup]" syntax, to add a class
            klass = elem.rel.match(/\[(.+)\]/);
            if (klass) klass = klass[1];
            
            // support for rel="facebox{width:300px; color:blue;}" syntax, to add style
            style = elem.rel.match(/\{(.+)\}/);
            if (style) style = style[1];
        }



        this.loading();
        e.stop();


        // div
        this.open();

        if (elem.hasAttribute('rel') && elem.rel.match(/iframe/)) {
            fb = this;
            url = elem.href;
            var el = new Element('iframe', {'src':url, 'scrolling':'auto'});
            this.facebox.addClassName('iframe');
/*
            this.beforeResize = function(){
                var p = this.contentWrapper.up('.body');
//                alert('height:'+(p.getHeight()-15)+'px\nwidth:'+(p.getWidth()-15)+'px');
                el.setStyle({
//                    height: (p.getHeight()-15)+'px',
//                    width:  (p.getWidth()-15)+'px'
                    height: (document.viewport.getHeight()-250)+'px',
                    width:  (p.getWidth()-25)+'px'
                });
            }.bind(this);
*/
//            fb.reveal('<iframe src="' + url + '" scrolling="auto">Your browser does not support iframes.</iframe>', klass, style);
            fb.reveal(el, klass, style);

        } else if (elem.hasAttribute('href') && elem.href.match(/#/)){
            var url                = window.location.href.split('#')[0];
            var target        = elem.href.replace(url+'#','');
            // var data            = $$(target).first();
            var d            = $(target);
            // create a new element so as to not delete the original on close()
            var data = new Element(d.tagName);
            data.innerHTML = d.innerHTML;
            this.reveal(data, klass, style);

        } else if (((elem.tagName.toLowerCase() == 'img') && elem.hasClassName('facebox') && elem.hasAttribute('src')) || (elem.hasAttribute('rel') && elem.href.match(this.settings.image_types))) {
            if ((elem.tagName.toLowerCase() == 'img') && elem.hasAttribute('src')) {
                var imageSrc = elem.src;

                var matchingClasses = $w(elem.className).find(function(test) {
                    return test.startsWith('faceboxU');
                });
                if (matchingClasses.length > 0) {
                    if (!imageSrc.include('?')) {
                        imageSrc += "?";
                    }
                    imageSrc += (imageSrc.include('?') ? "&" : "?") + matchingClasses.substr(8);
                }
            } else {
                var imageSrc = elem.href;
            }
            fb = this;

            var image = new Image();
            image.onload = function() {
//                alert('<div class="image"><img src="' + image.src + '" /></div>');
                fb.reveal('<div class="image"><img src="' + image.src + '" /></div>', klass, style);
//                fb.reveal(image, klass, style);
            }
            image.src = imageSrc;

//            fb.reveal('<div class="image"><img src="' + imageSrc + '" /></div>', klass, style);

        } else {
            // Ajax
            url = elem.href;
            fb = this;
            fb.ajax(url, klass, style);
        }
    },


    attachFormHandler    : function(el) {
        el.select("form").each(function(form){
            Event.stopObserving(document, this.keyPressListener);
            $('facebox_overlay').stopObserving('click', this.overlayCloseClicker);

            if (form.hasClassName('fbFormStandard')) {
                form.observe('submit', function(evt) {
                    evt.stop();
                    form.select('.fbErrorsShow').invoke('hide');
                    form.select('.fbErrorsClass').invoke('removeClassName', 'fbErrorsClass');

                    var params = $H(Form.serialize(form, true));
                    params.set('ajax', 1);
                    var myAjax = new Ajax.Request(
                        form.action,
                        {
                            method: 'post',
                            parameters: params,
                            onSuccess: function(t, json) {
                                if ((json != undefined)) {
    //                              alert('handler-2');
                                    if (json.success != undefined) {
                                        var myJSONObject = eval("(" + t.responseText + ")");
    //                                  alert('handler-3');
                                        if (json.success) {
                                            // Form submitted successfully
                                          
                                            // Display javascript alert if sent
                                            if (!Object.isUndefined(myJSONObject.fbAlert)) {
                                                alert(myJSONObject.fbAlert);
                                            }
                                            // Redirect to url if sent
                                            if (!Object.isUndefined(myJSONObject.fbRedirect)) {
                                                window.location = myJSONObject.fbRedirect;
                                            } else {
                                                if (!Object.isUndefined(myJSONObject.fbSuccess)) {
                                                    // Display success message if provided
                                                    var content = new Element('div').update(myJSONObject.fbSuccess);
                                                    if (content.select("body").first() != null) {
                                                        content = content.select("body").innerHTML;
                                                    }
                                                    el.update(content);
                                                } else {
                                                    // Display default success message
                                                    el.update("<h1>Your information has been submitted</h1>");
                                                }
                                                fb.setLocation();
                                            }

                                        } else {
                                            // Form submitted with error response
                                          
                                            // Display javascript alert if sent
                                            if (!Object.isUndefined(myJSONObject.fbAlert)) {
                                                alert(myJSONObject.fbAlert);
                                            }

                                            // Set form error classes if provided
                                            if (!Object.isUndefined(myJSONObject.fbErrorsShow) && Object.isArray(myJSONObject.fbErrorsShow)) {
                                                myJSONObject.fbErrorsShow.each(function(fbErr){
                                                    var el = $(fbErr+'fbErrorsShow');
                                                    if (Object.isElement(el)) {
                                                        el.addClassName('fbErrorsClass');
                                                        el.show();
                                                    }
                                                });
                                            }

                                            // Display errors if provided
                                            var errs = el.select('.fbFormErrors').first();
                                            if (!Object.isUndefined(myJSONObject.fbErrors) && Object.isElement(errs)) {
                                                var content = new Element('div').update(myJSONObject.fbErrors);
                                                if (content.select("body").first() != null) {
                                                    content = content.select("body").first();
                                                }
                                                errs.update(content);
                                                errs.show();
                                                form.enable();
                                                //errs.scrollIntoView(false);
                                            }
                                            //new Effect.ScrollTo(errs, {duration:1.0, offset:-50, queue:{position: 'end', scope: 'testing'}});
                                            //new Effect.Highlight($('errs'), {duration:4.0, queue:{position: 'end', scope: 'testing'}});
                                            form.enable();
                                        }

                                  } else {
                                      alert("ERROR SUBMITTING FORM");
                                  }
                                }
                            },
                            onFailure: function(t, json) {
                                form.enable();
                                alert('failure');
                            }
                        }
                    );
                    setTimeout(function(){form.enable();}, 10000);
                    form.disable();
                });
            }
        });
    }

});


var facebox;
document.observe("dom:loaded", function(){
    facebox = new Facebox();
});

