/*-------------------------------------------------
 * Auto Complete Contacts, alias piku
 * Copyright (c) 2007 A.D. & Diigo System.
 *------------------------------------------------*/
var ACContact = Class.create({
    initialize: function(options) {
        if(options.maxRec){
            this.maxRec = options.maxRec;
            this.maxRecTipTemp = "MAX Recipients "+this.maxRec;
        }
        this.scanType = options.scanType || 'all';
        this.maxHeight = options.maxHeight || 200;
        this.width = options.width || 414;
        this.recItemsId = [];
        this.tipTemp = "Start typing a friend's name or email address.";
        this.recBox = options.rec;
        this.recBox.setStyle({
            font:"12px verdana",
            padding:"0 0 2px 2px",
            width:this.width+"px"
        });

        if(!this.recInput) {
            this.recInput = new Element("input", {
                className:"recInput",
                maxlength:255
            });
            this.recBox.appendChild(this.recInput);
            this.recInputSizer = new Element("div", {
                className:"recInputSizer"
            });
            this.recBox.appendChild(this.recInputSizer);
            var cl = new Element("div");
            cl.setStyle({
                clear:"both"
            });
            this.recBox.appendChild(cl);
        }
        if(!ACContact.contacts){
            ACContact.contacts = options.contacts;
        }
        if(!ACContact.contactLists) {
            ACContact.contactListsID = [];
            for(var i=0; i<ACContact.contacts.length; i++) {
                if(ACContact.contacts[i].type=="list"){
                    ACContact.contactListsID.push(i)
                }
            }
        }
        if(!this.tip) {
            this.tip = new Element("div").hide();
            this.tip.setStyle({
                width:this.width-2+"px"
            });
            this.recBox.up().appendChild(this.tip);
        }
        if(!this.contactList) {
            this.contactList = new Element("div", {
                className:"accList"
            }).hide();
            this.contactList.setStyle({
                width:this.width-2+"px"
            });
            this.contactListInner = new Element("div").setStyle({
                position:"relative",
                overflow:"auto",
                padding:"2px"
            });
            this.contactList.appendChild(this.contactListInner);
            this.recBox.up().appendChild(this.contactList);
        }
        this.recBox.onclick = function() {
            this.recInput.setStyle({
                visibility:"visible"
            });
            this.recInput.focus();
        }.bind(this);

        this.recBox.reset = function() {
            this.recInput.onblur();
            this.recBox.select(".recItem").each(function(t){
                t.remove();
            });
            this.recItemsId.clear();
        }.bind(this);

        this.recInput.onfocus = function() {
            this.showTip();
            this.recInput.reset();
            this.currentItem = -1;
        }.bind(this);

        this.recInput.reset = function() {
            this.recInput.value = "";
            var width = ACContact.getTextSize(this.recInput.value, this.recInputSizer);
            this.recInput.setStyle({
                width: width + 30 + "px",
                visibility:"visible"
            });
        }.bind(this);

        this.recInput.onblur = function() {
            this.wrapItem();
            this.hideTip();
            this.recInput.setStyle({
                visibility:"hidden"
            });
            setTimeout(function(){
                this.hideContacts();
            }.bind(this), 300);
        }.bind(this);

        this.recInput.onkeydown = function(e) {
            var keycode;
            if(window.event) {
                keycode = window.event.keyCode;
            }
            else if(e){
                keycode = e.which;
            }
            switch(keycode) {
                case 9:
                case 40:{
                    this.hoverItem(this.currentItem+1);return false;
                }break;
                case 38:{
                    this.hoverItem(this.currentItem-1);return false;
                }break;
                case 8:{
                    if(this.recInput.value=="" && this.recInput.previous()) {
                        var cIndex = this.recInput.previous().getAttribute("cIndex");
                        $("recItemRemove_"+cIndex).onclick();
                    }
                }break;
                case 13:{
                    this.wrapItem();this.recInput.reset();this.hideContacts();this.showTip();return false;
                }break;
                // space
                case 32:{
                    if (!this.recInput.value.blank()) {
                        this.wrapItem();
                        this.recInput.reset();
                        this.hideContacts();
                        this.showTip();
                        return false;
                    }
                }break;
            }
            var width = ACContact.getTextSize(this.recInput.value, this.recInputSizer);
            if(width > this.recBox.getWidth()-50){
                width=this.recBox.getWidth()-50;
            }
            this.recInput.setStyle({
                width: width + 30 + "px"
            });
        }.bind(this);

        this.recInput.onkeyup = function(e) {
            var keycode;
            if(window.event) {
                keycode = window.event.keyCode;
            }
            else if(e){
                keycode = e.which;
            }
            if((keycode<=105 && keycode>=48) || keycode==8){
                this.scanContacts();
            }
        }.bind(this);
		
		this.tip_in_box = new Element("span");
		this.tip_in_box.setStyle({
			position:"absolute",
			marginTop:"2px",
			marginLeft:"5px",
			color:"#999"
		});
		this.tip_in_box.update(this.tipTemp);
		this.tip_in_box.onclick = this.recBox.onclick;
		Insertion.Before(this.recBox,this.tip_in_box);
		if(options.showTipInBox == false){
			this.hideTipInBox();	
		}	
    },
    showNotice: function() {
        this.tip.className = "accNotice";
        this.tip.update(this.maxRecTipTemp);
        this.tip.setStyle({
            width:this.recBox.getWidth()-2+"px"
        });
        this.tip.show();
    },
    showTip: function() {
		this.hideTipInBox();
//        this.tip.className = "accTip";
//        this.tip.update(this.tipTemp);
//        this.tip.setStyle({
//            width:this.recBox.getWidth()-2+"px"
//        });
//        this.tip.show();
    },
    hideTip: function() {
        this.tip.hide();
		if(this.recItemsId.length == 0){
			this.showTipInBox();
		}		
    },
	hideTipInBox: function(){
		this.tip_in_box.hide();
	},
	showTipInBox: function(){
		this.tip_in_box.show();
	},
    scanContacts: function() {
        this.match = [];
        var keyword = this.recInput.value.replace(/\s+/, "&");
        if(keyword.blank()){
            this.hideContacts();return false;
        }
        var p = new RegExp("&"+keyword,"i");
        for(var i=0; i<ACContact.contacts.length; i++) {
            var summary = ""
            var c = ACContact.contacts[i];
            if(this.scanType!='all' && this.scanType!=c.type){
                continue;
            }
            switch(c.type){
                case "list":{
                    summary = "&"+c.extra.title.replace(/\s+/, "&") + "&" + c.extra.note;
                }break;
                case "friend":{
                    summary = "&"+c.extra.real_name.replace(/\s+/, "&") + "&" + c.id;
                }break;
                case "user":{
                    summary = "&"+c.id.replace(/\s+/, "&") + "&" + c.extra.email;
                }break;
                case "email":{
                    summary = "&"+c.id;
                }break;
            }
            if(p.test(summary)) {
                this.match.push(i)
            }
        }
        if(this.match.length>0){
            this.showContacts();
        }else {
            this.hideContacts();
        }
    },
    showContacts: function() {
        var keyword = this.recInput.value;
        this.contactListInner.update("");
        this.contactListInner.setStyle({
            height:"auto",
            width:this.recBox.getWidth()-6+"px"
        });
        var tempContainer = new Element("div");
        for(var i=0; i<this.match.length; i++) {
            var cIndex = this.match[i];
            var c = ACContact.contacts[cIndex];
            var item = new Element("div", {
                id:"cI_"+i,
                className:"cItem"
            });
            switch(c.type){
                case "list":{
                    item.update("<b><i>list</i>"+this.h(c.extra.title)+"</b>"+c.extra.note);
                }break;
                case "friend":{
                    str = "<b>"+this.h(c.extra.real_name)+"</b><span class='extraDesc'>(";
                    if(c.id){
                        str += this.h(c.id)+' on Diigo';
                    }
                    if(c.extra.location){
                        str += ", "+c.extra.location;
                    }
                    if(c.extra.sex){
                        str +=" "+c.extra.sex;
                    }
                    str += ")</span>"
                    item.update(str);
                }break;
                case "user":{
                    item.update("<b>"+this.h(c.extra.email)+"</b>");
                }break;
                case "email":{
                    item.update("<b>"+this.h(c.id)+"</b>");
                }break;
            }
            item.setAttribute("cIndex", cIndex);
            item.onmouseover = function(i) {
                this.hoverItem(i);
            }.bind(this, i);
            item.onmouseout = function(i) {
                this.outItem(i)
            }.bind(this, i);
            item.onclick = function() {
                this.wrapItem();
            }.bind(this);
            tempContainer.appendChild(item);
        }
        this.contactListInner.appendChild(tempContainer);
        this.contactList.show();
        if(this.contactListInner.getHeight() > this.maxHeight) {
            this.contactListInner.setStyle({
                height:this.maxHeight+"px"
            });
        }
        this.hoverItem(0);
    },
    hideContacts: function() {
        this.contactList.hide();
        this.currentItem = -1;
    },
    h: function(text) {
        if(text.blank()){
            return "";
        }
        var keyword = this.recInput.value;
        return text.replace(eval("/"+keyword+"/i"), "<span class='keywordStrong'>"+keyword+"</span>");
    },
    hoverItem: function(i) {
        if(this.currentItem>=0){
            this.outItem(this.currentItem)
        }
        if(i>this.match.length-1){
            this.currentItem = this.match.length-1;
        }else if(i<-1){
            this.currentItem = -1
        }else {
            this.currentItem = i;
        }
        var item = $("cI_"+this.currentItem);
        if(item){
            item.className += " hover";
            if(this.currentItem==0){
                this.contactListInner.scrollTop=0;return false;
            }
            if(this.currentItem==this.match.length-1){
                this.contactListInner.scrollTop=2000;return false;
            }
            var d = this.contactListInner.getDimensions();
            var viewTop = this.contactListInner.scrollTop;
            var viewBottom = viewTop+d.height;
            var top = item.positionedOffset()[1];
            var bottom = top+item.getHeight();
            if(top < viewTop){
                this.contactListInner.scrollTop -=  (viewTop-top);
            }else if(bottom>viewBottom){
                this.contactListInner.scrollTop +=  (bottom-viewBottom);
            }else {}
        }
    },
    outItem: function(i) {
        if(this.currentItem>=0){
            var cItem = $("cI_"+this.currentItem);
            if(cItem){
                cItem.className = cItem.className.replace(/\s?hover/gi, "");
            }
        }
        this.currentItem = -1;
        var item = $("cI_"+i);
        if(item){
            item.className = item.className.replace(/\s?hover/gi, "");
        }
    },
    wrapItem: function(cIndex) {
        if(typeof(cIndex)=="undefined") {
            var keyword = this.recInput.value;
            if(keyword.blank()){
                this.currentItem=-1;return false;
            }
            if(this.currentItem==-1) {
                emailR =  /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
                if(emailR.test(keyword)) {
                    ACContact.contacts.push({
                        'type':'email',
                        'id':keyword
                    });
                    cIndex = ACContact.contacts.length-1;
                }else {
                    ACContact.contacts.push({
                        'type':'username',
                        'id':keyword
                    });
                    cIndex = ACContact.contacts.length-1;
                }
            }else {
                cIndex = $("cI_"+this.currentItem).getAttribute("cIndex");
            }
        }
        var c = ACContact.contacts[cIndex];
        if(this.recItemsId.indexOf(cIndex)!=-1){
            this.hideContacts();
            this.recBox.onclick();
            return false;
        }
        if(this.maxRec && this.recItemsId.length>this.maxRec){
            this.hideContacts();
            this.showNotice();
            return false;
        }
        var itemContent = "";
        switch(c.type){
            case "list":{
                itemContent = "<i>list</i>"+c.extra.title;
            }break;
            case "friend":{
                itemContent = c.extra.real_name;
            }break;
            case "user":{
                itemContent = c.extra.email;
            }break;
            case "email":{
                itemContent = c.id;
            }break;
            case "username":{
                itemContent = c.id;
            }break;
        }
        var recItem = new Element("span", {
            className: "recItem",
            id:"recItem_"+cIndex
        }).update(itemContent);
        var recItemRemove = new Element("a", {
            className:"recItemRemove",
            id:"recItemRemove_"+cIndex,
            href:"javascript:void(0);"
        }).update("x");
        recItem.appendChild(recItemRemove);
        recItem.setAttribute("cIndex", cIndex);
        var temp = new Element("div");
        temp.appendChild(recItem);
        new Insertion.Before(this.recInput, temp.innerHTML);
        $("recItemRemove_"+cIndex).onclick = function(cIndex) {
            this.removeRecItem.bind(this)(cIndex);
        }.bind(this, cIndex);
        this.recBox.onclick();
        this.recItemsId.push(cIndex);
    },
    removeRecItem: function(cIndex) {
        var recItem = $("recItem_"+cIndex);
        recItem.remove();
        this.recItemsId = this.recItemsId.without(cIndex);
        this.recBox.onclick();
    },
    getRecItems: function() {
        if(!this.recItemsId || this.recItemsId.length==0){
            return null;
        }else {
            var recFriends = [];
            var recEmails = [];
            var recLists = [];
            var recUsernames = [];
            for(var i=0; i<this.recItemsId.length; i++) {
                var c = ACContact.contacts[this.recItemsId[i]];
                switch(c.type){
                    case "friend":{
                        recFriends.push(c.id)
                    }break;
                    case "list":{
                        recLists.push(c.id)
                    }break;
                    case "user":{
                        recEmails.push(c.extra.email)
                    }break;
                    case "email":{
                        recEmails.push(c.id)
                    }break;
                    case "username":{
                        recUsernames.push(c.id)
                    }break;
                }
            }
            return {
                'friends':recFriends,
                'emails':recEmails,
                'lists':recLists,
                'usernames':recUsernames
            };
        }
    },
    setDefault: function(cIndex) {
        this.wrapItem(cIndex);
    },
    getRecOriItems: function() {
        if(!this.recItemsId || this.recItemsId.length==0){
            return null;
        }else {
            var recItems = [];
            for(var i=0; i<this.recItemsId.length; i++) {
                recItems.push(ACContact.contacts[this.recItemsId[i]]);
            }
            return recItems;
        }
    }
});
ACContact.getTextSize = function(text, el){
    el.innerHTML = text.escapeHTML().replace(/ /g, '&nbsp;');
    return (el.offsetWidth > 500 ? 500 : el.offsetWidth);
}