var PokeApp;
(function(){
    
    function undef(param){ return param; }
   
    PokeApp = function( widget )
    {
        this.widget = widget;
        this.views = {};
    }
    
    PokeApp.prototype = {
        resourcePath : "http://img-css.friends.yandex.net/i/widgets/",
        // starting up
        startup : function()
        {
            if (this.widget.getViewer() == 0) return;
            if (Social.Person.VIEWER.isGuest()) return;
            var app = this;
            if (this.widget.getViewer() == this.widget.getOwner())
            {
                with (new Social.DataRequest(app.widget.getAuth(), "YaRu"))
                {
                    add( PokeList(), "pokes" );
                    send( function(results,status){
                        if (results["pokes"].prototype != Social.DataRequest.Exception)
                        {
                            app.data = results["pokes"];
                            for (var i=0; i<app.data.length;i++)
                                app.data[i] = y5.JSON.decode(app.data[i]);
                            app.bindView("notifications",PokeApp.NotificationsView);
                        }
                    });
                }
            }
            else
                app.bindView("action",PokeApp.ActionView);
            app.bindView("confirm",PokeApp.ConfirmView);
        },
        // models
        doCreatePoke : function(key, targetUser)
        {
            var app = this;
            var poke_data = {
                from: Social.Person.VIEWER.compactify(),
                dt: new Date(),
                action: app.views.confirm.key,
                isReply: app.views.confirm.isReplyPos,
                notify : {
                    action : "Открыть свою страницу",
                    subject : Action.notify(key)+" "+Social.Person.VIEWER.getDisplayName(),
                    title : Action.notify(key)+" "+Social.Person.VIEWER.getLink(),
                    body : [
                         "<p>"+Social.Person.VIEWER.getLink()+" сделал вам персональный жест.</p>",
                         "<p>Подмигивания, обнимания и другие персональные жесты, которые вам делают другие пользователи, видны только вам. Вы можете ответить на них, если захотите.</p>"
                        ].join(""),
                    href : Social.Person.OWNER.getUrl()
                }
            };
            if (targetUser) 
            {
                poke_data.target = targetUser.id;
                poke_data.notify.href = targetUser.href;
            }
            with (new Social.DataRequest(app.widget.getAuth(), "YaRu"))
            {
                add( PokeNo(), "no" );
                send( function(results,status){
                    var req = new Social.DataRequest(app.widget.getAuth(), "YaRu");
                    poke_data.no = results.no;
                    req.add( req.PokeAdd(y5.JSON.encode(poke_data)) );
                    req.send( function(results,status){
                                app.onCreatePoke();
                            });
                });
            }
        },
        onCreatePoke : function()
        {
            this.views.confirm.doSuccess();
        },
        doDeletePoke : function(poke_no, poke_pos)
        {
            this.views.notifications.showWait();
            with (new Social.DataRequest(this.widget.getAuth(), "YaRu"))
            {
                var app = this;
                add( PokeRemove(poke_no) );
                send( function(results,status){
                    app.views.notifications.hideItem(poke_pos);
                    app.views.notifications.hideWait();
                } );
            }
        },
        
        // view-controlling
        _bind : function(view,key,eventName)
        {
            y5.Events.observe(eventName, function(params){ view.events[key](view.app,params) }, y5, true);
        },
        bindView : function( id, view )
        {
            var v;
            view.prototype.$  = function(id) { return this.app.widget.$(id) };
            view.prototype.$$ = function(id) { return this.app.widget.$$(id) };
            v = new view();
            this.views[id] = v;
            v.app = this;
            v.htmlId = this.widget.id + "_"+id;
            v.event={};
            if (v.events)
                for (var i in v.events)
                {
                    var eventName="PokeApp.("+this.widget.id+")"+id+"."+i;
                    var eventHandler = v.events[i];
                    v.event[i] = "PokeApp:" + eventName;
                    this._bind(v,i,v.event[i]);
                }
            if (v.render) v.render();
        },
        $ : function(id) { return this.widget.$(id) } 
    }
    
    PokeApp.ActionView = function() {}
    PokeApp.ConfirmView = function() {}
    PokeApp.NotificationsView = function() {}


    PokeApp.NotificationsView.prototype = {
        events : {
            DELETE : function(app,params)
            {
                app.doDeletePoke(params["no"], params["pos"]);
            },
            REPLY : function(app,params)
            {
                app.views.confirm.setAction(app.data[params["pos"]].action, params["pos"], params["no"],app.data[params["pos"]].from);
                app.views.confirm.doShow();
            }
        },
        showWait : function()
        {
            this.$('notifications-list').style.visibility="hidden";
            this.$('notifications-wait').style.display="block";
        },
        hideWait : function()
        {
            this.$('notifications-list').style.visibility="visible";
            this.$('notifications-wait').style.display="none";
        },
        hideItem : function(pos)
        {
            this.$("li"+pos).style.display="none"; 
            this.size--;
            if (this.size == 0)
                this.$("notifications").style.display = "none";
        },
        render : function()
        {
            var items = [];
            for(var i=0; i<this.app.data.length; i++)
            {
                items[i] = ["<li id='"+this.$$("li"+i)+"'>",
                '<i class="b-userpic small"><b><i><img src="'+this.app.data[i].from.userpic+'" alt="" /></i></b></i>',
                '<a class="delete" onclick="this.blur(); y5.Events.notify(\''+this.event.DELETE+'\', y5, true, {pos:\''+i+'\',no:\''+this.app.data[i].no+'\'}); return false" title="Удалить" href="#delele">x</a>',
                '<a class="reply" onclick="this.blur(); y5.Events.notify(\''+this.event.REPLY+'\', y5, true, {pos:\''+i+'\',no:\''+this.app.data[i].no+'\'}); return false" title="Ответить" href="#reply">ответить</a>',
                '<a class="b-yauser" href="'+this.app.data[i].from.href+'">',
                Social.Visuals.prettyUsername(this.app.data[i].from.title),
                '</a>', 
                '<p>'+Action.status(this.app.data[i].action)+'</p>',
                "</li>"].join("");
            }
            var prg = "<img src='http://img-css.friends.yandex.net/i/widgets/candy.gif' />";
            this.$("notifications").innerHTML= 
                "<div id='"+this.$$('notifications-wait')+"' style='display:none;padding:10px 20px;text-align:center;position:absolute;'>"+
                "<div style='height:8px;"+
                "background: url(http://img-css.friends.yandex.net/i/widgets/candy.gif) repeat-x;'>"+
                "</div>Подождите, идёт удаление.</div></div>"+
                "<ul id='"+this.$$('notifications-list')+"'>"+items.join("")+"</ul>";
            this.size = this.app.data.length;
            if (this.app.data.length > 0)
                this.$("notifications").style.display = "block";
            else
                this.$("notifications").style.display = "none";
        }
    }

    PokeApp.png = function( image )
    {
        if (!window._png) return;
        window._png(image.parentElement);
        image.onload();
        image.parentElement.style.marginTop="-10px";
    }

    PokeApp.ConfirmView.prototype = {
        events : {
            OK : function(app)
            {
                app.doCreatePoke( app.views.confirm.key, app.views.confirm.replyUser );
                app.views.confirm.doProgress();
            },
            CANCEL : function(app)
            {
                app.views.confirm.doHide();
            }
        },
        setAction : function(key, isReplyPos, isReplyNo, replyUser)
        {
            var name   = Social.Person.OWNER.getDisplayName();
            var gender = Social.Person.OWNER.getField("genderInt");
            var userpic= Social.Person.OWNER.getUserpicUrl("middle");
            if (replyUser) 
            {
                name=replyUser.title; 
                gender=replyUser.gender;
                if (replyUser.userpics)
                    userpic=replyUser.userpics["middle"];
                else
                    userpic=replyUser.userpic;
            }
            this.$("confirm_pre").innerHTML = Action.pre(key,Social.Person.OWNER.getField("genderInt"));
            this.$("confirm_title").innerHTML = Action.short(key);
            this.$("confirm_post").innerHTML = name+" получит уведомление о том, что "+Action.result(key,gender)+".";
            this.$("confirm_ok").innerHTML = Action.title(key);
            this.$("confirm_icon").src = userpic;
            this.key = key;
            this.isReplyPos = isReplyPos;
            this.isReplyNo = isReplyNo;
            this.replyUser = replyUser;
        },
        doShow : function()
        {
            this.$("confirm_modal").className="b-wink-modal";
            this.$("confirm").style.display="block";
            this.$("confirm_ok").focus();
        },
        doHide : function()
        {
            this.$("confirm_modal").className="b-wink-modal";
            this.$("confirm").style.display="none";
        },
        doProgress : function()
        {
            this.$("confirm_modal").className="b-wink-modal b-wink-modal-sending";
            this.$("confirm").style.display="block";
        },
        doSuccess : function()
        {
            this.$("confirm_modal").className="b-wink-modal b-wink-modal-confirm";
            this.$("confirm").style.display="block";
            if (this.isReplyPos)
                this.app.views.notifications.events.DELETE(this.app, {no:this.isReplyNo,pos:this.isReplyPos});
            if (this.app.views.action) 
                this.app.views.action.doHide();
            var view = this;
            window.setTimeout(function(){ view.doHide() },1200);
        },
        render : function()
        {
            document.body.appendChild(this.$("confirm"));
            var view = this;
            y5.Events.observe('click', function() { view.events.CANCEL(view.app); }, this.$("confirm_cancel"), true);
            y5.Events.observe('click', function() { view.events.OK(view.app); }, this.$("confirm_ok"), true);
        }
    }
    
    PokeApp.ActionView.prototype = {
        events : {
            OR : function(app)
            {
                if (app.$("actions").className == "action")
                    app.views.action.doShow();
                else
                    app.views.action.doHide();
            },
            DO : function(app,params)
            {
                app.views.confirm.setAction(params["key"]);
                app.views.confirm.doShow();
            }
        },
        doHide : function()
        {
            this.app.$("actions").className = "action";
        },
        doShow : function()
        {
            this.app.$("actions").className = "action show";
        },
        render : function()
        {
            if (!Action.initDone) Action.init();
            var items = [];
            for(var i=0; i<Action.list.length;i++)
                items[i] = this.generateItemHtml(Action.list[i][0], i==0);
            this.$("actions").innerHTML = items.join("");
            this.$("action").style.display = "block";
        },
        generateItemHtml : function(key, isFirst)
        {
            return '<li '+(isFirst?'class="visible"':'')+'><i class="g-smiles"><img onload="PokeApp.png(this)" src="'+Action.imgSrc(key)+'" alt="" /></i> <a onclick="this.blur(); y5.Events.notify(\''+this.event.DO+'\', y5, true, {key:\''+key+'\'}); return false" href="javascript:{}">'+ Action.title(key)+'</a>'+(isFirst?this.generateOR():'')+'</li>';
        },
        generateOR : function()
        {
            return '<a class="or" href="javascript:{}" onclick="this.blur(); y5.Events.notify(\''+this.event.OR+'\', y5, true, {htmlId:\''+this.htmlId+'\'}); return false"><i>или</i></a>';
        }
    }


    var Action = {
        list : [
            ["wink", "подмигнуть", "Подмигнуть", "вы ему|ей|ему подмигнули", "Вам подмигивает", "вам <i> подмигивает", 
                "Вы собираетесь ему|ей|ему", "smile_2"],
            ["beer", "предложить выпить", "Предложить выпить", "вы хотите предложить ему|eй|ему выпить", "Вам предлагают выпить", 
                "предлагает вам <i> выпить", "Вы собираетесь ему|eй|ему", "smile_15"],
            ["kiss", "поцеловать", "Поцеловать", "вы его|eё|его поцеловали", "Вас целует", "вас <i> целует", 
                "Вы собираетесь его|eё|его", "smile_14"],
            ["tongue", "показать язык", "Показать язык", "вы показали ему|ей|ему язык", "Вам показывает язык", "<i> показывает вам язык", 
                "Вы собираетесь", "smile_8"],
            ["hug",  "обнять",     "Обнять", "вы его|eё|его обнимаете", "Ммм! Вас обнимает", "вас <i> обнимает", 
                "Вы собираетесь его|eё|его", "smile_7"],
            ["wake", "разбудить",  "Разбудить",  "вы хотите его|eё|его разбудить ", "Вас будит", "вас <i> будит", 
                "Вы собираетесь его|eё|его", "smile_5"],
            ["slime",  "подарить слизня",     "Подарить слизня", "вы дарите ему|ей|ему мозгового слизня", 
                "Чпок! Вам мозговой слизень от ", "дарит вам <i> слизня",
                "Вы собираетесь подарить ему|ей|ему мозгового слизня", "smile_12"]
        ],
        hash : {},
        genderic : function(what,gender)
        {
            if (gender == undef()) return what;
            var parts = what.split(" ");
            for(var i=0; i<parts.length; i++)
            {
                var p2 = parts[i].split("|");
                if (p2.length > 1)
                    parts[i] = p2[gender];
            }
            return parts.join(" ");
        },
        short  : function(key,gender) { return this.genderic(this.hash[key][1],gender) },
        title  : function(key,gender) { return this.genderic(this.hash[key][2],gender) },
        result : function(key,gender) { return this.genderic(this.hash[key][3],gender) },
        notify : function(key,gender) { return this.genderic(this.hash[key][4],gender) },
        status : function(key,gender) { return this.genderic(this.hash[key][5],gender) },
        pre    : function(key,gender) { return this.genderic(this.hash[key][6],gender) },
        imgSrc : function(key) { return "http://img.yandex.net/i/smiles/default/"+this.hash[key][7]+".png" },
        imgSrcSmall : function(key) { return "http://img.yandex.net/i/smiles/small/"+this.hash[key][7]+".png" },
        _smile : function(key, what) { return what.replace( "<i>", '<i class="g-smiles"><img onload="PokeApp.png(this)" src="'+this.imgSrcSmall(key)+'" alt="" /></i>' ) },
        init : function()
        {
            for(var i=0; i<this.list.length; i++)
            {
                this.hash[ this.list[i][0] ] = this.list[i];
                this.list[i][5] = this._smile( this.list[i][0], this.list[i][5] );
                this.hash[ this.list[i][0] ] = this.list[i];
            }
            this.initDone = true;
        }
    }
    Action.init();
    
    
    Social.DataRequest.YaRu = function(datarequest)
    {
        var pattern = "{x}{y}";
        var prefix  = "yaru.";
        var t;
        for (var x in Social.DataRequest.YaRu.methods)
            for( var y in Social.DataRequest.YaRu.methods[x] )
                datarequest[ pattern.replace("{x}", x).replace("{y}", y) ] = 
                    eval("t = function( params ) { return this._add('"+prefix+x+y+"', arguments, Social.DataRequest.YaRu.methods, '"+x+"', '"+y+"' ); }");
        return datarequest;
    }
    Social.DataRequest.YaRu.methods = { 
        "Poke" : {
            "Add" : ["poke_content"],
            "Remove" : ["poke_no"],
            "List" : [],
            "No" : []
            }
        }
    
})();