func (mul *Multicast) SendJoinRequest(dest, group, invite_code string) {
	addr := announce_client.GetInfo(dest)
	mul.Info.AddrMap[dest] = addr.IP.String() + ":9200"
	str := group + ",,," + invite_code
	fmt.Println(str)
	mul.SendUniMessage("join_request", str, dest, 5000)
}
func (mul *Multicast) rcvFromFront() {
	for {
		m := <-MessageQueue
		b := m.Body
		group := b.CalendarName
		if m.Mtype == "request_CS" {
			mul.LockRequest(group)
		} else if m.Mtype == "release_CS" {
			mul.LockRelease(group)
		} else if m.Mtype == "operation" {
			str := "Btype--" + b.Btype + ",,," + "Name--" + b.CalendarName + ",,," + "Text--" + b.Text
			mul.UpdateSend(group, str)
		} else if m.Mtype == "join_request_to_back" {
			a := strings.Split(b.Text, ",,,")
			dest := a[0]
			invite_code := a[1]
			addr := announce_client.GetInfo(dest)
			mul.Info.AddrMap[dest] = addr.IP.String() + ":9200"
			mul.SendJoinRequest(dest, group, invite_code)
		} else if m.Mtype == "vote_request" {
			mem := b.Text //who wants to join
			mul.VoteRequest(mem, group)
		} else if m.Mtype == "vote_reply" {
			dest := b.Btype
			decision := b.Text
			mul.VoteReply(dest, decision)
		} else if m.Mtype == "add_group" {
			mul.AddGroup(group)
		} else {

		}
	}
}
//initialize all variables
func (c *CalendarInfo) Init() {
	c.Hostname = cryptowrapper.GetLocalFingerPrint()
	fmt.Println("fingerprint:" + c.Hostname)

	//c.Hostname = name
	c.GroupMember = make(map[string]map[string]int)
	c.RcvQueue = make(chan customtypes.TsMessage, 1024)
	c.AddrMap = make(map[string]string)
	//    c.GroupMember["group1"] = make(map[string]int)
	//    c.GroupMember["group2"] = make(map[string]int)
	// c.GroupMember["group1"]["a"]=0
	// c.GroupMember["group1"]["b"]=1
	// c.GroupMember["group1"]["c"]=2
	// c.GroupMember["group2"]["b"]=0
	// c.GroupMember["group2"]["c"]=1
	c.ReadFromFile("config.txt")
	announce_client.AnnounceMyPresence()
	addr := announce_client.GetInfo(c.Hostname)
	c.AddrMap[c.Hostname] = addr.IP.String() + ":9200"
	ipMap := make(map[string]*net.TCPAddr)
	for _, ms := range c.GroupMember {
		for m, _ := range ms {
			_, ok := ipMap[m]
			if !ok {
				ipMap[m] = nil
			}
		}
	}
	announce_client.GetInfoStruct(ipMap) //map[string]string
	for mem, ip := range ipMap {
		c.AddrMap[mem] = ip.IP.String() + ":9200"
	}
	// c.AddrMap["a"]="127.0.0.1:1234"
	// c.AddrMap["b"]="127.0.0.1:1235"
	// c.AddrMap["c"]="127.0.0.1:1236"
}
func (mul *Multicast) VoteRcv() {
	for {
		rcv := <-mul.VoteQueue
		fmt.Println(rcv.Group + " " + rcv.Src + " " + rcv.Kind + " " + rcv.Content)
		if rcv.Kind == "vote_decision" {
			fmt.Println("vote_decison: " + rcv.Src + " " + rcv.Kind + " " + rcv.Content)
			//voteGroup+" "+voteMem+" "+mul.Info.AddrMap[voteMem]
			arr := strings.Split(rcv.Content, " ")
			group := arr[0]
			mem := arr[1]
			ip := arr[2]
			mul.Info.AddMember(group, mem, ip)
			fmt.Println(mem + " joins " + group)
			mul.Info.WriteToFile("config.txt")
			//notify front end
			text := "Approved: " + mem + " joins " + group
			b := calendar.Frontmessage{
				Btype:        "",
				CalendarName: group,
				Text:         text,
			}
			mf := &calendar.Message{
				Mtype: "vote_decision",
				Body:  &b,
			}
			//			mul.ToFront <- mf
			ToFront(mf)

		} else if rcv.Kind == "vote_request" {
			arr := strings.Split(rcv.Content, " ")
			mem := arr[0]
			group := arr[1]
			fmt.Println("receive vote request: " + mem + " joins " + group)
			// reader := bufio.NewReader(os.Stdin)
			//  		commands, _ := reader.ReadString('\n');
			//  		decision:=strings.Trim(commands, "\n")
			fmt.Println(rcv.Src + " yes")
			//		mul.VoteReply(rcv.Src, "yes")
			// 			//notify front end
			text := mem + " wants to join " + group
			b := calendar.Frontmessage{
				Btype:        rcv.Src,
				CalendarName: group,
				Text:         text,
			}
			mf := &calendar.Message{
				Mtype: "vote_request_to_front",
				Body:  &b,
			}
			//			mul.ToFront <- mf
			ToFront(mf)
		} else if rcv.Kind == "vote_reply" {
			countVote++
			if rcv.Content == "yes" {
				countYes++
			}
			if countVote == groupSize {
				var decision string
				if countYes >= (groupSize-1)/2 {
					decision = "yes"
					mul.SendMulticast("vote_decision", voteGroup+" "+voteMem+" "+mul.Info.AddrMap[voteMem], voteGroup, 5000)
					size := len(mul.Info.GroupMember[voteGroup])
					mul.Info.GroupMember[voteGroup][voteMem] = size
					fmt.Println("----------")
					fmt.Println(mul.Info.GroupMember[voteGroup])
					mul.SendInfo(voteGroup, voteMem)
					// 					//notify
					text := "Approved: " + voteMem + " joins " + voteGroup
					b := calendar.Frontmessage{
						Btype:        "",
						CalendarName: voteGroup,
						Text:         text,
					}
					mf := &calendar.Message{
						Mtype: "vote_decision",
						Body:  &b,
					}
					//					mul.ToFront <- mf
					ToFront(mf)
				} else {
					decision = "no"
				}
				fmt.Println(decision)
				mul.SendUniMessage("join_reply", voteGroup+" "+decision, voteMem, 5000)
			}
		} else if rcv.Kind == "join_reply" {
			//receive info about the group
			//notify front end
			arr := strings.Split(rcv.Content, " ")
			mem := mul.Info.Hostname
			group := arr[0]
			decision := arr[1]
			var text string
			if decision == "yes" {
				text = "Approved: " + mem + " joins " + group
			} else {
				text = "Denied: " + mem + " joins " + group
			}
			fmt.Println(text)
			b := calendar.Frontmessage{
				Btype:        "",
				CalendarName: group,
				Text:         text,
			}
			mf := &calendar.Message{
				Mtype: "join_reply",
				Body:  &b,
			}
			//			mul.ToFront <- mf
			ToFront(mf)
		} else if rcv.Kind == "join_request" {
			addr := announce_client.GetInfo(rcv.Src)
			mul.Info.AddrMap[rcv.Src] = addr.IP.String() + ":9200"

			arr := strings.Split(rcv.Content, ",,,")
			group := arr[0]
			invite_code := arr[1]
			text := rcv.Src + " wants to join " + group
			fmt.Println(text + "invite_code:" + invite_code)
			b := calendar.Frontmessage{
				Btype:        "",
				CalendarName: group,
				Text:         text,
			}
			mf := &calendar.Message{
				Mtype: "join_request_to_front",
				Body:  &b,
			}
			//			mul.ToFront <- mf
			ToFront(mf)
			if len(mul.Info.GroupMember[group]) == 1 {
				decision := "yes"
				size := len(mul.Info.GroupMember[group])
				mul.Info.GroupMember[group][rcv.Src] = size
				member := rcv.Src
				fmt.Println("send decision:" + group + " " + member + " " + mul.Info.AddrMap[member])
				fmt.Println(mul.Info.Hostname)
				mul.SendUniMessage("vote_decision", group+" "+member+" "+mul.Info.AddrMap[member], mul.Info.Hostname, 5000)
				fmt.Println(member + " " + decision)
				mul.SendUniMessage("join_reply", group+" "+decision, member, 5000)
				mul.SendInfo(group, member)
			}
		} else {
			//error
		}
	}
}