﻿
var EnvoieAmi = new Class({
    Implements: [Options, ToElement],
    options: {
        topDistance: 4,
        labels: {
            close: 'close',
            required: 'Required',
            title: 'Send to a friend',
            name: 'Your name',
            friend_name: "Your friend's name",
            email: "Your friend's email",
            err_email: "Email invalid",
            message: 'Message',
            button: 'Submit',
            unknown: 'Unknown',
            success: 'Success',
            fail: 'Fail'
        },
        links: []
    },
    status: 'unknown',
    hidden: true,
    initialize: function(options){
        this.setOptions(options);
        this.bindLinks();
        this.createElements();
        this.display();
    },
    bindLinks: function(){
        (this.options.links || []).each((function(a){
            
            a.addEvent('click', (function(ev){
                this.show();
                ev.stop();
            }).bind(this));
            
        }).bind(this));
    },
    createElements: function(){
        var self = this;
        this.element = new Element('div', {
            'class': 'gen_wrap',
            'styles': {
                'display': 'none'
            }
        });
        var close = new Element('a', {
            'class': 'gen_close',
            'href': '#',
            'name': 'friend',
            'text': this.options.labels.close,
            'events': {
                'click': function(ev){
                    self.hide();
                    ev.stop();
                }
            }
        });
        close.inject( this.element );
        
        this.innerContainer = new Element('div', {
            'class': 'gen_inner'
        });
        this.innerContainer.inject( this );
        
        this.element.inject(document.body);
        
        var top = this.getTop();
        
        var ww = (window.getWidth() == 0) ? window.getScrollWidth() : window.getWidth();
        this.element.setStyles({top: top, display: ''});
        var size = this.element.getComputedSize()
        var left = (ww / 2) - (size.totalWidth / 2);
        this.element.setStyles({'left': left, 'display': 'none'});
    },
    getTop: function(){
        var wh = (window.getHeight() == 0) ? window.getScrollHeight() : window.getHeight();
        var st = 0;
        var top = st + (wh / this.options.topDistance);
        return top + window.getScroll().y;
    },
    display: function(isDefault){
        if((typeof isDefault) == "undefined")
            isDefault = true;
        else
            isDefault = !!isDefault;
        
        var oldContainer = this.innerContainer;
        this.innerContainer = new Element('div', {
            'class': 'gen_inner'
        });
        
        var h1 = new Element('h1', {
            'html': this.options.labels.title
        });
        h1.inject( this.innerContainer );
        
        var self = this;
        if(isDefault){
            this.form = new Element('form', {
                'action': baseURL + 'ajax/send_friend.aspx',
                'method': 'post'
            });
            this.form.inject( this.innerContainer );
            
            var ul = new Element('ul', {
                'class': 'gen_amis_form'
            });
            var form_data = [{
                label: this.options.labels.name,
                element: 'input',
                type: 'text',
                'class': 'text',
                name: 'name',
                required: true
            }, {
                label: this.options.labels.friend_name,
                element: 'input',
                type: 'text',
                'class': 'text',
                name: 'friend_name',
                required: true
            }, {
                label: this.options.labels.email,
                element: 'input',
                type: 'text',
                'class': 'text',
                name: 'email',
                required: true
            }, {
                label: this.options.labels.message,
                element: 'textarea',
                name: 'message'
            }, {
                element: 'input',
                type: 'button',
                'class': 'button',
                events: {
                    click: (function(ev){
                        var form = this.form;
                        var elements = form.getElements("input, textarea");
                        
                        var regex_required = /_+R_+/gi
                        var regex_email = /\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/
                        var email_input = form.getElement("input[id*=email]");
                        
                        elements = elements.filter(function(el){
                            if(!el.name)
                                return false;
                            return !!el.name.match(regex_required);
                        });
                        
                        var err = [];
                        var valid_email = true;
                        var valid = true;
                        elements.each(function(el){
                            if(!el.value){
                                err.push( el );
                                valid = false
                            }
                        });
                        if(email_input){
                            var email = ''+email_input.value;
                            if(!email.test(regex_email)){
                                valid = false;
                                valid_email = false;
                            }
                        }
                        
                        if(valid){
                            this.send();
                        } else {
                            err.each(function(el){
                                var label = el.getPrevious('label[for='+el.id+']');
                                var abbr = label.getElements('abbr')[0];
                                var span = label.getElements('span')[0];
                                if(abbr){
                                    el.fireEvent('change');
                                } else {
                                    abbr = new Element('abbr', {
                                        'text': ' *',
                                        'title': self.options.labels.required
                                    })
                                    if(span){
                                        abbr.injectBefore( span );
                                    } else {
                                        abbr.inject( label );
                                    }
                                    el.addEvent('change', function(ev){
                                        if(this.value){
                                            abbr.setStyle('display', 'none');
                                        } else {
                                            abbr.setStyle('display', '');
                                        }
                                    });
                                }
                            });
                            if(!valid_email){
                                var el = email_input
                                var label = el.getPrevious('label[for='+el.id+']');
                                var span = label.getElements('span')[0];
                                if(span){
                                    el.fireEvent('change');
                                } else {
                                    span = new Element('span', {
                                        'text': self.options.labels.err_email,
                                        'class': 'err blck'
                                    })
                                    span.inject( label );
                                    el.addEvent('change', function(ev){
                                        var email = ''+this.value;
                                        if(email.test(regex_email)){
                                            span.setStyle('display', 'none');
                                        } else {
                                            span.setStyle('display', '');
                                        }
                                    });
                                }
                            }
                        }
                        ev.stop();
                    }).bind(self)
                },
                value: this.options.labels.button
            }, {
                element: 'input',
                type: 'hidden',
                value: this.options.language,
                name: 'language'
            }, {
                element: 'input',
                type: 'hidden',
                value: ''+window.location,
                name: 'url'
            }];
            
            form_data.each(function(opt){
                var li = new Element('li');
                var name = 'gen_' +(opt.required ? 'R_' : '') + opt['name'];
                var el_options = {};
                
                if(opt.label){
                    new Element('label', {
                        'text': opt['label'],
                        'for': name
                    }).inject( li );
                } else {
                    li.addClass('nolabel');
                }
                if(opt.name)
                    el_options.name = el_options.id = name;
                if(opt.type){
                    el_options.type = opt.type;
                    if(opt.type == "hidden")
                        li.addClass('hide');
                }
                if(opt.value)
                    el_options.value = opt.value;
                if(opt['class'])
                    el_options['class'] = opt['class'];
                if(opt.events)
                    el_options.events = opt.events;
                var el = new Element(opt['element'], 
                    el_options
                );
                el.inject( li );
                li.inject( ul );
            });
            
            ul.inject( this.form );
        } else {
            new Element('p', {
                'class': 'gen_' + this.status,
                'text': this.options.labels[this.status]
            }).inject( this.innerContainer );
        }
        var fxOut = new Fx.Tween(oldContainer, {
            property: 'opacity'
        });
        fxOut.addEvent('complete', function(){
            oldContainer.dispose();
            self.innerContainer.setStyle('opacity', 0);
            self.innerContainer.inject( self )
            self.innerContainer.fade('in');
        });
        fxOut.start('1', '0');
        
        var fxMove = new Fx.Tween(this.element, {
            property: 'top'
        });
        
        if(this.hidden){
            this.element.setStyle('top', this.getTop());
        } else {
            var t1 = parseInt( this.element.getStyle('top') );
            var t2 = this.getTop();
            fxMove.start( t1, t2 );
        }
    },
    show: function(){
        if(this.hidden){
            var el = this.element;
            el.setStyles({'opacity':0, 'display':''});
            el.fade('in');
            this.hidden = false;
        }
    },
    hide: function(){
        if(!this.hidden){
            this.hidden = true;
            var el = this.element;
            
            var fxOut = new Fx.Tween(el, {
                property: 'opacity'
            });
            fxOut.addEvent('complete', function(){
                el.setStyle('display', 'none');
            });
            fxOut.start('1', '0');
        }
    }, 
    send: function(){
        var form = this.form;
        var self = this;
        var req = new Request({
            url:    form.action,
            method: form.method,
            onSuccess: (function(text, xml){
                this.status = text;
                this.display(false);
                setTimeout((function(){
                    this.hide();
                }).bind(this), 1000*10);
            }).bind(self)
        });
        req.send(form);
    }
});