/*++++++++++++++!!!!!!!!!!!!!!!!!!!!++++++++++++++++++++++++
     *                      Please call this when grabbing!
     ++++++++++++++++!!!!!!!!!!!!!!!!!!!!++++++++++++++++++*/
    public bool grab(Transform hand, Transform target)
    {
        //when grab something, move the !START_NODE of a rope with hand
        FakeRope fk_rp = target.GetComponent <FakeRope>();

        if (!target.GetComponent <FakeRope>().not_connect_others())
        {
            Debug.LogWarning("Dettaching my rope!");
            //I am connecting to someone else
            fk_rp.dettach();
        }

        if (target == end_rope.transform)
        {
            grabbing_end = true;
        }

        Transform start_node = target.FindChild("start");

        start_node.SetParent(hand);
        start_node.localPosition = Vector3.zero;
        return(true);
    }
    public bool attach_ropes(Transform hand, Transform src, Transform dest = null)
    {
        grabbing_end = false;
        if (hand.FindChild("start") == null && src.FindChild("start") == null)
        {
            Debug.LogError("The operating node is missing.");
        }
        hand.FindChild("start").SetParent(src);
        if (src.GetComponent <FakeRope>() == null)
        {
            Debug.Log("Nothing to be operated.");
            return(false);
        }


        if (dest == null)
        {
            connection_count = still_connect();
            if (connection_count == -1)
            {
                StartCoroutine("on_disconnected");
            }
            return(true);
        }
        FakeRope src_fr = src.GetComponent <FakeRope>();

        if (dest == start_rope.transform && src_fr == end_rope)
        {
            //invalid operation
            connection_count = still_connect();
            if (connection_count == -1)
            {
                StartCoroutine("on_disconnected");
            }
            return(false);
        }
        //if there is no error, could get rid of this
        if (dest.GetComponent <FakeRope>() == src_fr.first_child())
        {
            //invalid operation
            connection_count = still_connect();
            if (connection_count == -1)
            {
                StartCoroutine("on_disconnected");
            }
            return(false);
        }
        src_fr.attach(dest);

        if (dest == start_rope.transform)
        {
            if (!circle_formed())
            {
                FakeRope tmp = src_fr;
                while (tmp.first_child() != null)
                {
                    tmp = tmp.first_child();
                }
                start_rope          = tmp;
                line_start          = tmp.end;
                line_start.position = origin_pos_start;
                Debug.LogWarning("Attaching to the startnode.");
            }
            //change here: start node should be the child of scr_fr until there is none
        }

        if (src_fr == end_rope)
        {
            if (dest.GetComponent <FakeRope>() != null)
            {
                FakeRope tmp = dest.GetComponent <FakeRope>();
                //It is here that crushed!
                if (!circle_formed())
                {
                    while (tmp.next_rope() != null)
                    {
                        tmp = tmp.next_rope();
                    }
                    end_rope = tmp.GetComponent <FakeRope>();
                    line_end = end_rope.start;
                }
            }
        }
        //detect connections
        //detect circles from start, if so, reject connection
        if (circle_formed())
        {
            src_fr.dettach();
        }
        //fixing crush
        if (Mathf.Abs(GameObject.Find("hand_left").GetComponent <RotateHand>().get_offset_angle()) < 1e-5)
        {
            line_start.position = origin_pos_start;
        }
        connection_count = still_connect();
        if (connection_count == -1)
        {
            StartCoroutine("on_disconnected");
        }
        return(true);
    }