var WallApp;
(function(){

    function undef(param){ return param; }
    
    WallApp = function( widget )
    {
        this.widget = widget;
        this.views = {};
        this.data = [];
        this.items = [];
    }

    WallApp.prototype = {
        resourcePath : "http://img-css.friends.yandex.net/i/widgets/", 
        // startupping
        getItems : function( jsonItems )
        {
            this.items = y5.JSON.decode(jsonItems);
            if (this.items.length == 0) return this.startup();
            var items = this.items;
            var app = this;
            with (new Social.DataRequest(app.widget.getAuth()))
            {
                for(var i=0; i<items.length; i++)
                    add( Social.AppData.freeForAll(items[i]).Get());
                send( function(results,status){
                    for(var i=items.length-1; i>=0; i--)
                        if (results[items[i]].prototype != Social.DataRequest.Exception)
                            app.storeItem(results[items[i]].content);
                    app.startup();
                });
            }
        },
        startup : function()
        {
            this.bindView("main",WallApp.MainView);
            if (!Social.Person.VIEWER.isGuest()) 
                this.bindView("form",WallApp.FormView);
        },
        // model features
        storeItem : function(jsonData, rawData)
        {
            if (rawData != undef())
                this.data[ this.data.length ] = rawData;
            else
            {
                var data = y5.JSON.decode(jsonData);
                data.dt = new Date( data.dt.substring(0,4), data.dt.substring(5,7)-1, data.dt.substring(8,10),
                                    data.dt.substring(11,13), data.dt.substring(14,16));
                this.data[ this.data.length ] = data;
            }
        },
        addItem : function(itemData)
        {
            var no;
            if (this.items.length == 0) no=0;
            else no = parseInt(this.items[ this.items.length-1 ].replace("item",""),10);
            itemData.no = "item" + (no+1);
            this.items[this.items.length] = itemData.no;
            with (new Social.DataRequest(this.widget.getAuth()))
            {
                add( Social.AppData.freeForAll(itemData.no).Set(y5.JSON.encode(itemData)));
                add( Social.AppData.freeForAll("items").Set(y5.JSON.encode(this.items)));
                if (this.widget.getViewer() != this.widget.getOwner())
                    add( Notify.Action( "OWNER" ,itemData.from.title+" оставил записку на вашей <a href='"+Social.Person.OWNER.getUrl()+"'>стене</a>", location.href, 
                    { 
                        subject : itemData.from.title+" оставил записку на вашей стене",
                        action : "Просмотреть стену",
                        body : [
                             "<p><a href='"+itemData.from.href+"'>"+itemData.from.title+"</a> оставил записку на вашей стене.</p>",
                             "<p>Стена &mdash; это раздел вашей страницы на Я.ру, где другие пользователи могут оставлять вам записки (записки на стене видны всем).</p>",
                             "<p>Кликните на ссылку, чтобы увидеть, что изменилось на вашей стене.</p>"
                            ].join("")
                    }) );
                send( function(results,status){} );
            }
            itemData.clientSide = true;
            this.storeItem("rawData", itemData);
            this.views.main.addItem(itemData);
        },
        removeItem : function(itemNo)
        {
            var items = [];
            for(var i=0; i<this.items.length; i++)
                if (this.items[i] != itemNo)
                    items[items.length]=this.items[i];
            this.items = items; 
            with (new Social.DataRequest(this.widget.getAuth()))
            {
                add( Social.AppData.freeForAll("items").Set(y5.JSON.encode(this.items)));
                send( function(results,status){} );
            }
        },
        shortify : function(what)
        {
            if (what == undef()) what = "";
            what = what.replace(/\s+/g, ' ').replace(/^\s/,'');
            var postfix = "";
            if (what.length > 80) 
            {
                postfix = "&hellip;";
                what = what.substr(0,80).replace(/(.+)\s\S*$/g, "$1");
            }
            return what.replace(/&/g,"&amp;").replace(/</g, "&lt;")+postfix;
        },
        urlRe : /((http|ftp|https):\/\/[+~'A-Za-z0-9_!=&?\.\-\/%]+(,[+~'A-Za-z0-9_!=&?\.\-\/%]+)*)/ig,
        breakWords : function(what)
        {
            return what.replace(/(\S{30})/, "$1\01");
        },
        format : function(what)
        {
            if (what == undef()) what = "";
            what = what.replace(this.urlRe, "\01$1\01");
            what = what.split("\01");
            for (var i=0; i<what.length; i+=2)
                what[i] = this.breakWords(what[i]);
            what = what.join("");
            what = what.replace(/&/g, "&amp;").replace(/</g, "&lt;");
            what = what.replace(this.urlRe, '<a href="$1">$1</a>');
            what = what.replace(/&lt;ya\s+user\s*=\s*('|")?([a-z\-0-9])([a-z\-0-9]+)('|")?\s*\/?>/ig,
                        '<a class="b-yauser" href="http://$2$3.ya.ru"><b>$2</b>$3</a>');
            what = what.replace(/\01/g, "<wbr />");
            return what.replace(/\n/g, "<br />");
        },
        // view-controlling features
        _bind : function(view,key,eventName)
        {
            y5.Events.observe(eventName, function(params){ view.events[key](view.app,params) }, y5, true);
        },
        bindView : function( id, view, htmlId )
        {
            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 = htmlId+"_"+id;
            v.event={};
            if (v.events)
                for (var i in v.events)
                {
                    var eventName="WallApp.("+this.widget.id+")"+id+"."+i;
                    var eventHandler = v.events[i];
                    v.event[i] = "WallApp:" + eventName;
                    this._bind(v,i,v.event[i]);
                }
            if (v.render) v.render();
        },
        $ : function(id) { return this.widget.$(id) }
    }

    WallApp.FormView = function() {}
    WallApp.MainView = function() {}

    WallApp.FormView.prototype = {
        events : {
            SEND : function(app) {
                var content = ""+app.$("ta").value;
                content = content.replace(/^\s+/,"").replace(/\s+$/,"");
                app.$("ta").value = "";
                app.$("ta").focus();
                if (content != "")
                    app.addItem({
                        from: Social.Person.VIEWER.compactify(),
                        dt: new Date(),
                        content : content
                    });
            }
        },
        render : function()
        {
            this.$("form").innerHTML= [
            '<p>Написать</p>',
            '<fieldset><textarea id="'+this.$$("ta")+'" cols="40" rows="5"></textarea></fieldset>',
            '<b class="input"><input id="'+this.$$("submit")+'" onclick="y5.Events.notify(\''+this.event.SEND+'\', y5); return false;" type="submit" value="Отправить" /></b>'
            ].join("");
            var ev = this.event;
            y5.ShortCut.down( [{key: y5.ShortCut.ENTER, ctrl:true}],
                        function(e) {
                            e.stopPropagation(); 
                            y5.Events.notify(ev.SEND, y5); 
                        },
                        this.$("ta"), {checkTarget: false} );
        }
    }

    WallApp.MainView.prototype = {
        events : {
            COLLAPSE : function(app, params)
            {
                if (app.$(params.id).className == "")
                    app.$(params.id).className = "close";
                else
                    app.$(params.id).className = "";
            },
            REMOVE : function(app, params)
            {
                app.$("dt"+params.pos).style.display="none";
                app.$("dd"+params.pos).style.display="none";
                app.removeItem(params.no);
            }
        },
        addItem : function( item )
        {
            var dt = document.createElement("dt");
            var dd = document.createElement("dd");
            dt.id = this.$$("dt"+this.nextIdNo);
            dd.id = this.$$("dd"+this.nextIdNo);
            dt.innerHTML = this._dt(this.nextIdNo,item);
            dd.innerHTML = this._dd(this.nextIdNo,item);
            if (this.app.data.length <= 1)
            {
                this.$("list").appendChild(dt);
                this.$("list").appendChild(dd);
            }
            else
            {
                this.$("list").insertBefore(dd,this.$(this.firstId));
                this.$("list").insertBefore(dt,dd);
            }
            this.firstId="dt"+this.nextIdNo;
            this.nextIdNo++;
            this.showList();
        },
        _dt : function(pos,item)
        {
            show_delete = (this.app.widget.getOwner() == this.app.widget.getViewer()) || (item.from.id == this.app.widget.getViewer());
            return [
                Social.Visuals.prettyDate( item.dt ),
                show_delete?('<a href="javascript:;" onclick="this.blur(); y5.Events.notify(\''+this.event.REMOVE+'\', y5, true, {pos:\''+pos+'\',no:\''+item.no+'\'}); return false" class="delete"><img src="'+WallApp.prototype.resourcePath+'delete2.gif" alt="" title="Удалить" /></a>'):""
                ].join("");
        },
        _dd : function(pos,item)
        {
            var message = this.app.format(item.content);
            var msg = this.app.shortify(item.content);
            return [
              '<i class="collapse" onclick="this.blur(); y5.Events.notify(\''+this.event.COLLAPSE+'\', y5, true, {id:\'dd'+pos+'\'}); return false"></i>',
              '<a href="'+item.from.href+'" class="b-yauser">',
              '<i class="b-userpic small"><b><i><img src="'+item.from.userpic+'" alt="" /></i></b></i>',
              Social.Visuals.prettyUsername(item.from.title),
              '</a>',
              ' <span class="short">',
              msg,
              '</span>',
              '<blockquote>',
              message,
              '</blockquote>'].join("");
        },
        render : function()
        {
            if (this.app.data.length == 0)
                this.showEmpty();
            else
            {
                var items = [];
                for (var i=0; i< this.app.data.length; i++)
                {
                    items[i]=[
                    '<dt id="'+this.$$("dt"+i)+'">',
                    this._dt(i,this.app.data[i]),
                    '</dt>',
                    '<dd id="'+this.$$("dd"+i)+'">',
                    this._dd(i,this.app.data[i]),
                    '</dd>'
                    ].join("");
                }
                this.firstId = "dt0";
                this.nextIdNo = this.app.data.length;
                this.$("list").innerHTML = items.join("");
                this.showList();
            }
            this.$("loading").style.display="none";
        },
        showList : function()
        {
            this.$("empty").style.display="none";
            this.$("list").style.display="block";
            this.$("overflow").className = "overflow";
        },
        showEmpty : function()
        {
            this.$("empty").style.display="block";
            this.$("list").style.display="none";
            this.$("overflow").className = "overflow no-message";
        }
    }

})();
