//use Cookie
//simple template
var Template = new Class({
    Implements: Options,
    options: {
        'before': '%',
        'after': '%'
    },
    
    initialize: function(string, options){
        this.string = string;
        this.setOptions(options);
        this.regExp = new RegExp(this.options.before.escapeRegExp() + '([\\w-]+)' + this.options.after.escapeRegExp(), 'g');
    },
    
    parse: function(data){
        var options = this.options;
        return this.string.replace(this.regExp, function(match){
            return $pick(data[match.substring(options.before.length, match.length - options.after.length)], '');
        });
    }
});

Fx.Scroll = new Class({
    Extends: Fx,
    options: {
        offset: {x: 0, y: 0},
        wheelStops: true
    },

    initialize: function(element, options){
        this.element = this.subject = $(element);
        this.parent(options);
        var cancel = this.cancel.bind(this, false);

        if ($type(this.element) != 'element') this.element = $(this.element.getDocument().body);

        var stopper = this.element;

        if (this.options.wheelStops){
            this.addEvent('start', function(){
                stopper.addEvent('mousewheel', cancel);
            }, true);
            this.addEvent('complete', function(){
                stopper.removeEvent('mousewheel', cancel);
            }, true);
        }
    },

    set: function(){
        var now = Array.flatten(arguments);
        this.element.scrollTo(now[0], now[1]);
    },

    compute: function(from, to, delta){
        return [0, 1].map(function(i){
            return Fx.compute(from[i], to[i], delta);
        });
    },

    start: function(x, y){
        if (!this.check(x, y)) return this;
        var offsetSize = this.element.getSize(), scrollSize = this.element.getScrollSize();
        var scroll = this.element.getScroll(), values = {x: x, y: y};
        for (var z in values){
            var max = scrollSize[z] - offsetSize[z];
            if ($chk(values[z])) values[z] = ($type(values[z]) == 'number') ? values[z].limit(0, max) : max;
            else values[z] = scroll[z];
            values[z] += this.options.offset[z];
        }
        return this.parent([scroll.x, scroll.y], [values.x, values.y]);
    },

    toTop: function(){
        return this.start(false, 0);
    },

    toLeft: function(){
        return this.start(0, false);
    },

    toRight: function(){
        return this.start('right', false);
    },

    toBottom: function(){
        return this.start(false, 'bottom');
    },

    toElement: function(el){
        var position = $(el).getPosition(this.element);
        return this.start(position.x, position.y);
    }
});

//start Fx.Slide
Fx.Slide = new Class({
    Extends: Fx,

    options: {
        mode: 'vertical'
    },

    initialize: function(element, options){
        this.addEvent('complete', function(){
            this.open = (this.wrapper['offset' + this.layout.capitalize()] != 0);
            if (this.open && Browser.Engine.webkit419) this.element.dispose().inject(this.wrapper);
        }, true);
        this.element = this.subject = $(element);
        this.parent(options);
        var wrapper = this.element.retrieve('wrapper');
        this.wrapper = wrapper || new Element('div', {
            styles: $extend(this.element.getStyles('margin', 'position'), {overflow: 'hidden'})
        }).wraps(this.element);
        this.element.store('wrapper', this.wrapper).setStyle('margin', 0);
        this.now = [];
        this.open = true;
    },

    vertical: function(){
        this.margin = 'margin-top';
        this.layout = 'height';
        this.offset = this.element.offsetHeight;
    },

    horizontal: function(){
        this.margin = 'margin-left';
        this.layout = 'width';
        this.offset = this.element.offsetWidth;
    },

    set: function(now){
        this.element.setStyle(this.margin, now[0]);
        this.wrapper.setStyle(this.layout, now[1]);
        return this;
    },

    compute: function(from, to, delta){
        return [0, 1].map(function(i){
            return Fx.compute(from[i], to[i], delta);
        });
    },

    start: function(how, mode){
        if (!this.check(arguments.callee, how, mode)) return this;
        this[mode || this.options.mode]();
        var margin = this.element.getStyle(this.margin).toInt();
        var layout = this.wrapper.getStyle(this.layout).toInt();
        var caseIn = [[margin, layout], [0, this.offset]];
        var caseOut = [[margin, layout], [-this.offset, 0]];
        var start;
        switch (how){
            case 'in': start = caseIn; break;
            case 'out': start = caseOut; break;
            case 'toggle': start = (layout == 0) ? caseIn : caseOut;
        }
        return this.parent(start[0], start[1]);
    },

    slideIn: function(mode){
        return this.start('in', mode);
    },

    slideOut: function(mode){
        return this.start('out', mode);
    },

    hide: function(mode){
        this[mode || this.options.mode]();
        this.open = false;
        return this.set([-this.offset, 0]);
    },

    show: function(mode){
        this[mode || this.options.mode]();
        this.open = true;
        return this.set([0, this.offset]);
    },

    toggle: function(mode){
        return this.start('toggle', mode);
    }

});

Element.Properties.slide = {

    set: function(options){
        var slide = this.retrieve('slide');
        if (slide) slide.cancel();
        return this.eliminate('slide').store('slide:options', $extend({link: 'cancel'}, options));
    },

    get: function(options){
        if (options || !this.retrieve('slide')){
            if (options || !this.retrieve('slide:options')) this.set('slide', options);
            this.store('slide', new Fx.Slide(this, this.retrieve('slide:options')));
        }
        return this.retrieve('slide');
    }

};

Element.implement({

    slide: function(how, mode){
        how = how || 'toggle';
        var slide = this.get('slide'), toggle;
        switch (how){
            case 'hide': slide.hide(mode); break;
            case 'show': slide.show(mode); break;
            case 'toggle':
                var flag = this.retrieve('slide:flag', slide.open);
                slide[flag ? 'slideOut' : 'slideIn'](mode);
                this.store('slide:flag', !flag);
                toggle = true;
            break;
            default: slide.start(how, mode);
        }
        if (!toggle) this.eliminate('slide:flag');
        return this;
    }

});//end of Fx,Slide

var AltTip = new Class({
    initialize: function(list) {
        list.each(function(item) {
            this.hoverEvent(item);
        }.bind(this), this);
    },
    
    hoverEvent: function(item) {
        item.getElement('a').addEvents({
            'mouseenter': function(e) {
                item.getElement('.tip').setStyle('display', 'block');
            },
            'mouseleave': function(e) {
                item.getElement('.tip').setStyle('display', 'none');
            }
        });
    }
});

var MessageAlert = new Class({
    Implements: [Options],
    options: {timeSpan: 60, url: '/user/notice_msg/'},
    initialize: function(url, options) {
        this.setOptions(options);
        this.url = url ? url : this.options.url;
        this.request();
    },
    
    request: function() {
        var span = this.getTimeSpan() - this.options.timeSpan*1000;
        if(span < 0){
            this.bindStatistic.delay(Math.abs(span), this);
            this.setAlert(JSON.decode(Cookie.read('statistic')));            
        }else{
            this.bindStatistic();
        }
        if(self.location.href.contains('/message/')){
            window.addEvent('unload', function(e) {
                this.setExpired();
            }.bind(this));
        }
    },
    
    bindStatistic: function() {
        this.getStatistic();
        this.getStatistic.periodical(this.options.timeSpan*1000, this);
    },
    
    setTimeSpan: function(statistic) {
        Cookie.write('timespan', $time(), {path: '/'});
        //console.log(Cookie.read('timespan'));
        if(statistic){
            Cookie.write('statistic', JSON.encode(statistic), {path: '/'});
        }
    },
    
    getTimeSpan: function() {
        var preTime = Cookie.read('timespan') ? Cookie.read('timespan').toInt() : false;
        if(preTime){
            return $time() - preTime;
        }else{
            this.setTimeSpan();
            this.getTimeSpan();
        }
    },
    
    setExpired: function() {
        Cookie.write('timespan', Cookie.read('timespan') - this.options.timeSpan*1000, { path: '/' });
    },
    
    getStatistic: function() {
        new Request.JSON({
            url: this.url,
            method: 'get',
            secure: false,
            onSuccess: function(statistic) {
                //reset timespan
                this.setTimeSpan(statistic);
                this.setAlert(statistic);
            }.bind(this)
        }).send();
    },
    setAlert: function(statistic) {
        var alertEl = $('global_bar').getElement('.alert');
        if(statistic.notice > 0){
            alertEl.setStyle('display', 'block');
            alertEl.getElementById('notice_alert').set('html', '通知<b>' + statistic.notice + '</b>');					
        }else{
            alertEl.getElementById('notice_alert').set('html', '');
        }
        if(statistic.message > 0){
            alertEl.setStyle('display', 'block');
            alertEl.getElementById('message_alert').set('html', '消息<b>' + statistic.message + '</b>');
        }else{
            alertEl.getElementById('message_alert').set('html', '');
        }
        if(statistic.request > 0){
            alertEl.setStyle('display', 'block');
            alertEl.getElementById('request_alert').set('html', '好友请求<b>' + statistic.request + '</b>');
        }else{
            alertEl.getElementById('request_alert').set('html', '');
        }
    }
});

//用户提醒层
var RemindTip = new Class({
    Implements: [Options, Events],
    options: {
        tip: 'remind_tip_wrap',
        rate: 1000*60*30,
        url: '/remind_tip/',
        data: false,
        onClosed: $empty()
    },
    
    initialize: function(options) {
        this.setOptions(options);
        this.remind_json = new Hash();
        this.pre_span = Cookie.read('remind_span') ? Cookie.read('remind_span').toInt() : false;
        if(!this.pre_span || $time() > this.pre_span + this.options.rate){
            this.remindData();
        }else{
            this.injectTip();
        }
    },
    
    injectTip: function() {
        if($(this.options.tip)){
            var remindId = this.getOneRemind();
            if(remindId){
                //console.info('get one remind:' + remindId);
                new Request({
                    url: this.options.url + remindId + '/',
                    method: 'get',
                    onSuccess: function(text) {
                        if(text != 'false'){
                            text = this.options.data ? new Template(text).parse(this.options.data) : text;
                            $(this.options.tip).set('html', text);
                            this.slide = new Fx.Slide(this.options.tip).hide();                            
                            (function() { this.slide.slideIn(); }.bind(this)).delay(1000);
                            $(this.options.tip).getElement('span.delete').addEvent('click', function(e) {
                                e.stop();
                                this.closeTipEvent();
                            }.bind(this));
                        }	
                    }.bind(this)
                }).send();
            }
        }
    },
    
    closeTipEvent: function() {
        var remindTip = $(this.options.tip).getElement('.remind_tip');
        var closeId = remindTip.get('id').slice(3);
        var remind_hide = Cookie.read('remind_hide') ? Cookie.read('remind_hide').split(',') : [];
        //console.log('hide:' + remind_hide);
        //Cookie.write('remind_hide', '', {path: '/', 'duration': 7});
        Cookie.write('remind_hide', remind_hide.include(closeId).join(','), {path: '/', 'duration': 7});
        //close tip
        this.fadeOut($(this.options.tip).getParent());
        this.fireEvent('onClosed', closeId, 50);
    },
    
    fadeOut: function(el) {
        $(el).fade(0);
        (function() { el.destroy(); }).delay(500);
    },
    
    remindData: function() {
        new Request.JSON({
            url: this.options.url,
            method: 'get',
            secure: false,
            onSuccess: function(json) {
                if($type(json) != 'object')return;
                Cookie.write('remind_span', $time(), {path: '/'});
                Cookie.write('remind_json', JSON.encode(json), {path: '/'});
                this.injectTip();
            }.bind(this)
        }).send();
    },
    
    //随机返回一个提醒
    getOneRemind: function() {
        this.remind_json = new Hash(JSON.decode(Cookie.read('remind_json')));
        var remindList = this.remind_json.filter(function(v, k){
            return v == this.getType() && this.isShowRemind(k);
        }.bind(this), this);
        var keys = remindList.getKeys();
        //console.info(keys);
        if(keys.length > 0){
            return keys[$random(0, keys.length-1)];
        }else return false;        
    },
    /*
        TODO 优化查询
    */
    isShowRemind: function(key) {
        if(!Cookie.read('remind_hide'))return true;
        return !Cookie.read('remind_hide').split(',').contains(key);
    },
    
    getType: function() {
        var type = self.location.pathname.split('/')[1];
        return type ? type : 'home';
    }
});

var UpdateInfo = new Class({
    Implements: [Options, Events],
    options: {
        timespan: 1000*60*60*2,
        url: '/update_info/',
        onUpdated: $empty()
    },
    
    initialize: function(options) {
        this.setOptions(options);
        this.request();		
    },
    
    getTimestamp: function() {
        var timestamp = Cookie.read('update_info_tp');
        return timestamp ? timestamp.toInt() : false;
    },
    
    setTimestamp: function() {
        var timestamp = $time();
        Cookie.write('update_info_tp', timestamp, { path: '/', 'duration': 0.5 });
        return timestamp;
    },
    
    request: function() {
        var timestamp = this.getTimestamp();
        if(!timestamp || timestamp + this.options.timespan < $time()){
            new Request.JSON({
                url: this.options.url,
                method: 'get',
                secure: false,
                data: {'stamp': $time()},
                onSuccess: function(json) {
                    if(json === true){
                        //console.log('updated information!...');
                        this.setTimestamp();
                        this.fireEvent('onUpdated', json, 50);
                    }
                }.bind(this)
            }).send();
        }
    }
});

//ajax error types
var AJAX_ERROR = {
    0: '对不起您还没有登录！<a href="/signin/">现在登录？</a>',//code 00
    1: '您没有提交数据到服务器!',// code 01
    2: '操作或保存数据出错!',// code 02
    3: '请求的数据不存在!',// code 03
    4: '提交数据中有误!',// code 04
    5: '对不起，您没有相应操作权限!',// code 05
    6: '数据不符合要求'// code 06
};

window.addEvent('domready', function() {
    //sub menu action
    $('top_nav').getElements('.has_sub').each(function(li) {
        li.addEvents({
            'mouseenter': function(e) {
                this.getElement('.main_title').addClass('active');
                menu = this.getElement('.sub_items');
                if(menu){
                    menu.setStyle('display', 'block');
                }
            },
            'mouseleave': function(e) {
                this.getElement('.main_title').removeClass('active');
                menu = this.getElement('.sub_items');
                if(menu){
                    //(function() {menu.setStyle('display', 'none')}).delay(500);
                    menu.setStyle('display', 'none');
                }
            }
        });
    });
    
    //action for round avatar (fix ie)
    if(Browser.Engine.trident){
        $(document.body).getElements('span.round_image').each(function(span) {
            span.getParent().addEvent('click', function(e) {
                e.stop();
                self.location.href = this.get('href');
            });
        });
    }    

    if($('global_bar')){
        //tip remind
        try{
            if(!REMIND_TIP_DATA){
                new RemindTip();
            }
        }catch(e){
            new RemindTip();
        }
        
        //tip text
        new AltTip($('global_bar').getElements('.shortcut li'));
        new AltTip($$('.holder_right .split_r'));
        //start navigation
        var startEl = $('global_bar').getElement('.start a');
        var appEl = $('global_bar').getElement('.app_list');
        startEl.addEvent('click', function(e) {
            e.stop();
            if(appEl.getStyle('display') == 'block'){
                appEl.setStyle('display', 'none');
                startEl.removeClass('active');
            }else{
                appEl.setStyle('display', 'block');
                startEl.addClass('active');
            }
        });
        //start navigation click event
        $(document.body).addEvent('click', function(e) {
            if(appEl.getStyle('display') == 'block'){
                appEl.setStyle('display', 'none');
                startEl.removeClass('active');
            }
        });
        
        //user update information
        new UpdateInfo();
        
        //new message and notice alert
        var ma = new MessageAlert();
        
        //to the top and to the end event
        var scroll = new Fx.Scroll($(document.body));
        $('global_bar').getElement('.to_end').addEvent('click', function(e) {
            e.stop();
            scroll.toBottom();
        });
        $('global_bar').getElement('.to_home').addEvent('click', function(e) {
            e.stop();
            scroll.toTop();
        });
    }
    
    //search event
    if($('search_go')){
        var keyEl = $('keyword');
        keyEl.addEvents({
            'click': function(e) {
                if(keyEl.get('value') == '找秀友...')keyEl.set('value', '');
                keyEl.setStyle('color', '#333');
            },
            'blur': function(e) {
                if(!keyEl.get('value')){
                    keyEl.set('value', '找秀友...');
                    keyEl.setStyle('color', '#ccc');
                }
            }
        });
        
        $('search_go').addEvent('click', function(e) {
            e.stop();
            $('search_form').submit();
        });
    }
    //feed_back
    /*if($('feed_back')){
        var width = ($(document.body).getSize().x - 960)/2 - 2;
        $('feed_back').setStyle('width', width);
    }*/
});




















