var fs = {

init : function(max, frds) {
   this.friends = $H(frds);
   this.selected = $A();
   this.tagged = $A();
   this.max_selected = max;
   this.updateNumberOfSelected();
   this.view('all');
},

displayList : function(list, tagid) {
   var s = '';
   var that = this;
   if(tagid) {
      list.each(function(uid) {
         s += that.getFriendAsLIByTagged(uid, tagid);
      });
   } else {
      list.each(function(uid) {
         s += that.getFriendAsLI(uid);
      });
   }
   Element.update('friends', s);
},

view : function(type, id, text) {
   this.currentPage = type;
   switch (type) {
   case 'all'        : this.displayList(this.getAll()); break;
   case 'selected'   : this.displayList(this.getSelected()); break;
   case 'unselected' : this.displayList(this.getUnselected()); break;
   case 'editFriendTag' : this.displayList(this.getByEditFriendTag(id, text), id); break;
   }
},

network_filter : function(id, name) {
   this.currentPage = 'network';
   this.displayList(this.getByNetwork(id));
},

friendTag_filter : function(id, name, mgt) {
   this.currentPage = 'friendTag';
   this.displayList(this.getByFriendTag(id));
   if(mgt) {
      $('view_editFriendTag').innerHTML='<a href="#" onclick="fs.view(\'editFriendTag\', '+id+', \''+name+'\');return false;"><b>'+name+'</b>&nbsp;(edit)</a>';
   } else {
      $('view_editFriendTag').innerHTML='<a href="#" onclick="fs.friendTag_filter('+id+', \''+name+'\', 0);return false;"><b>'+name+'</b>&nbsp;</a>';
   }
   Element.removeClassName('view_unselected', 'selected');
   Element.removeClassName('view_selected', 'selected');
   Element.removeClassName('view_all', 'selected');
   Element.addClassName('view_editFriendTag', 'selected');
   Element.show('view_editFriendTag');
},

typeahead_filter : function(prefix) {
   this.displayList(this.getByTypeahead(prefix));
},

getAll : function() { 
   Element.addClassName('view_all', 'selected');
   Element.removeClassName('view_selected', 'selected');
   Element.removeClassName('view_unselected', 'selected');
   Element.hide('view_editFriendTag');
   return this.friends.keys();
},

getSelected : function() {
   Element.addClassName('view_selected', 'selected');
   Element.removeClassName('view_all', 'selected');
   Element.removeClassName('view_unselected', 'selected');
   Element.hide('view_editFriendTag');
   return this.selected;
},

getUnselected : function() {
   var result = $A();
   var that = this;
   this.getAll().each(function(uid){
      if (that.selected.indexOf(uid) == -1) 
         result.push(uid);
   });
   Element.addClassName('view_unselected', 'selected');
   Element.removeClassName('view_selected', 'selected');
   Element.removeClassName('view_all', 'selected');
   Element.hide('view_editFriendTag');
   return result;
},

getByNetwork : function(id) {
   if (id == -1) return this.getAll();
   var result = $A();
   var that = this;
   this.getAll().each(function(uid){
      var matched = false;
      for (var i=0; i<that.friends.get(uid).network.length; ++i) {
         if (that.friends.get(uid).network[i].id == id) {
            matched = true;
            break;
         }
      }
      if (matched) result.push(uid);
   });
   return result;
},

getByFriendTag : function(id) {
   var result = $A();
   var that = this;
   this.getAll().each(function(uid){
      if(that.friends.get(uid).tagging && that.friends.get(uid).tagging[id]) {
         result.push(uid);
      }
   });
   return result;
},

getByEditFriendTag : function(id, tagname) {
   var result = $A();
   var that = this;
   if(tagname) {
      Element.removeClassName('view_unselected', 'selected');
      Element.removeClassName('view_selected', 'selected');
      Element.removeClassName('view_all', 'selected');
      Element.addClassName('view_editFriendTag', 'selected');
   }
   this.friends.keys().each(function(uid){
      result.push(uid);
   });
   if(tagname) $('view_editFriendTag').innerHTML='<a href="#" onclick="fs.friendTag_filter('+id+', \''+tagname+'\', 1);return false;">Save&nbsp;<b>'+tagname+'</b></a>';
   return result;
},

getByTypeahead : function(prefix) {
   var prefix = prefix.trim();
   if (prefix.length < 2) return this.getAll();
   var result = $A();
   var exp = new RegExp(prefix, 'i');
   var that = this;
   this.friends.keys().each(function(uid){
      if (that.friends.get(uid).username.match(exp)) result.push(uid);
   });
   return result;
},

updateNumberOfSelected : function() {
   var left = this.max_selected - this.selected.length;
   if (left < 5) {
      Element.update('max_limit_notice', '剩下'+left+'個');
      Element.show('max_limit_notice');
   } else {
      Element.hide('max_limit_notice');
   }
   Element.update('view_selected_count', this.selected.length);
},

isSelected : function(uid) {
   return this.selected.indexOf(uid) != -1;
},

select : function(uid) {
   if (!this.friends.get(uid)) return false;
   if (this.isSelected(uid)) {
      this.selected.remove(uid);
      Element.remove('hidden_'+uid); 
      if (this.currentPage == 'selected') Element.remove('user_'+uid);
      else Element.removeClassName('user_'+uid, 'selected');
   } else {
      if (this.max_selected - this.selected.length <= 0) return false;
      this.selected.push(uid);
      new Insertion.After('fb_multi_friend_selector', this.getFriendAsHidden(uid)); 
      if (this.currentPage == 'unselected') Element.remove('user_'+uid);
      else Element.addClassName('user_'+uid, 'selected');
   }
   this.updateNumberOfSelected();
   return true;
},

getFriendAsHidden : function(uid) {
   return '<input type="hidden" name="ids[]" value="'+uid+'" id="hidden_'+uid+'" fb_protected="true"/>';
},

getFriendAsLI : function(uid) {
   var s = '<li id="user_'+uid+'"';
   if (this.isSelected(uid)) s += ' class="selected"';
   s += '><a href="#" onclick="fs.select('+uid+');return false;">';
   s += this.friends.get(uid).pic;
   s += '<span class="username">'+this.friends.get(uid).username+'</span>';
   if (this.friends.get(uid).network.length) 
      s += '<span class="network">@'+this.friends.get(uid).network[0].name+'</span>';
   s += '</a></li>';
   return s;
},

getFriendAsLIByTagged : function(uid, tagid) {
   var s = '<li id="user_'+uid+'"';
   if (this.friends.get(uid).tagging && this.friends.get(uid).tagging[tagid] ) s += ' class="selected"';
   s += '><a href="#" onclick="fs.setFriendTag('+uid+','+tagid+');return false;">';
   s += this.friends.get(uid).pic;
   s += '<span class="username">'+this.friends.get(uid).username+'</span>';
   if (this.friends.get(uid).network.length) 
      s += '<span class="network">@'+this.friends.get(uid).network[0].name+'</span>';
   s += '</a></li>';
   return s;
},

setFriendTag : function(uid, tagid) {
  // here can only use getClassName to judge selected items
  if ( Element.hasClassName('user_'+uid, 'selected') ) {  // selected, deselect this
     Element.removeClassName('user_'+uid, 'selected');
     this.friends.get(uid).tagging[tagid]=null;
  } else {
     Element.addClassName('user_'+uid, 'selected');
     if(!this.friends.get(uid).tagging) this.friends.get(uid).tagging=$A();
     this.friends.get(uid).tagging[tagid]=tagid;
  }
  f_mgt.tagFriend(tagid, uid);
}

};

