ArrowModel::ArrowModel(ApplicationWindow* parentWnd,
                       Glib::RefPtr<PortModel> src, Glib::RefPtr<PortModel> dest,
                       Connection* con, ApplicationModel* appModel, bool nullArw): PolylineModel(0,0,0,0), connection(NULL, NULL) 
{
    parentWindow = parentWnd;
    source = src;
    destination = dest;
    selected = false;
    bExist = false;
    bNullArrow = nullArw;
    applicationModel = appModel; 
    bNested = (applicationModel != NULL);
    if(appModel)
        application = appModel->getApplication();
    else        
        application = parentWindow->manager.getKnowledgeBase()->getApplication();

    if(con)
    {
        strLabel = con->carrier();
        connection = *con;
    }
        
    this->property_close_path().set_value(false);
    this->property_line_width().set_value(ARROW_LINEWIDTH);
    this->property_arrow_width().set_value(5.0);
    if(!bNullArrow)
        this->property_end_arrow().set_value(true);
    if(bNested)
    {
        defaultColor = "#555555";
        //GooCanvasLineDash *dash = goo_canvas_line_dash_new (ARROW_LINEWIDTH, 3.0, 3.0);
        //g_object_set(this->gobj(), "line-dash", dash, NULL);
    }
    else
        defaultColor = "black";

    source->addSourceArrow(this);
    destination->addDestinationArrow(this);
    if(!bNullArrow)
    {
        string strCarrier = strLabel;
        string dummyLabel;
        //Adding connection 
        if(application)
        {
            string strFrom, strTo;
            Glib::RefPtr<InternalPortModel> intPort;
            Glib::RefPtr<ExternalPortModel> extPort;
            Glib::RefPtr<PortArbitratorModel> arbPort;
            Module* module;
            InputData* input = NULL;
            OutputData* output = NULL;
            bool bExternFrom = false;
            bool bExternTo = false;

            // port arbitrator at the destination
            arbPort = Glib::RefPtr<PortArbitratorModel>::cast_dynamic(destination);

            // source 
            intPort = Glib::RefPtr<InternalPortModel>::cast_dynamic(source);
            if(intPort)
            {
                output = intPort->getOutput();
                module = (Module*) output->owner();
                strFrom = string(module->getPrefix()) + string(intPort->getOutput()->getPort()); 
                dummyLabel = string(intPort->getOutput()->getPort());
                if(!strCarrier.size())
                {
                    strCarrier = intPort->getOutput()->getCarrier();
                    if(arbPort)
                        strCarrier += "+recv.priority";
                }                    
            }
            else
            {
                extPort = Glib::RefPtr<ExternalPortModel>::cast_dynamic(source);
                strFrom = extPort->getPort();
                dummyLabel = string(extPort->getPort());
                if(!strCarrier.size() && arbPort)
                    strCarrier = "udp+recv.priority";
                bExternFrom = true;
            }
          
            // destination
            intPort = Glib::RefPtr<InternalPortModel>::cast_dynamic(destination);
            if(intPort)
            {
                input = intPort->getInput();
                module = (Module*) input->owner();
                strTo = string(module->getPrefix()) + string(intPort->getInput()->getPort()); 
                dummyLabel += string(" -> ") + string(intPort->getInput()->getPort()) + string(" "); 
                if(!strCarrier.size())   
                {
                    strCarrier = intPort->getInput()->getCarrier();
                    if(arbPort)
                        strCarrier += "+recv.priority";
                }                    
            }
            else if(arbPort)
            {
                intPort = Glib::RefPtr<InternalPortModel>::cast_dynamic(arbPort->getPortModel());
                extPort = Glib::RefPtr<ExternalPortModel>::cast_dynamic(arbPort->getPortModel());
                if(intPort)
                {
                    input = intPort->getInput();
                    module = (Module*) input->owner();
                    strTo = string(module->getPrefix()) + string(intPort->getInput()->getPort()); 
                    dummyLabel += string(" -> ") + string(intPort->getInput()->getPort()) + string(" "); 
                    if(!strCarrier.size())
                    {
                        strCarrier = intPort->getInput()->getCarrier();
                        strCarrier += "+recv.priority";
                    }                        
                }
                else
                {
                    strTo = extPort->getPort();
                    dummyLabel += string(" -> ") + string(extPort->getPort()) + string(" "); 
                    bExternTo = true;
                    if(!strCarrier.size())
                        strCarrier = "udp+recv.priority";
                }
            }
            else
            {
                extPort = Glib::RefPtr<ExternalPortModel>::cast_dynamic(destination);
                strTo = extPort->getPort();
                dummyLabel += string(" -> ") + string(extPort->getPort()) + string(" "); 
                bExternTo = true;
                if(!strCarrier.size())
                        strCarrier = "udp";
            }
            
            connection.setFrom(strFrom.c_str());
            connection.setTo(strTo.c_str());
            connection.setCarrier(strCarrier.c_str());
            connection.setFromExternal(bExternFrom);
            connection.setToExternal(bExternTo);
            connection.setCorOutputData(output);
            connection.setCorInputData(input);
            connection.setModel(this);
            connection = parentWindow->manager.getKnowledgeBase()->addConnectionToApplication(application, connection);
            tool = TooltipModel::create(parentWindow, dummyLabel.c_str());
        }

        strLabel = strCarrier;
        this->property_stroke_color().set_value(defaultColor.c_str());
        if(strLabel.size())
            label = LabelModel::create(parentWindow, this, strLabel.c_str());
        else
            label = LabelModel::create(parentWindow, this, strCarrier.c_str());

        // if it is an auxilary connections
        /*
        if((strLabel.find("virtual") != std::string::npos) || 
           (strLabel.find("auxiliary") != std::string::npos) )
        {
            GooCanvasLineDash *dash = goo_canvas_line_dash_new (ARROW_LINEWIDTH, 3.0, 3.0);
            g_object_set(this->gobj(), "line-dash", dash, NULL);      
        }
        */

        if(bNested)
        {
            applicationModel->add_child(label);
            label->property_visibility().set_value(Goocanvas::ITEM_HIDDEN);
        }
        else
            parentWindow->getRootModel()->add_child(label);
        label->raise();

        showLabel(parentWindow->m_showLabel);
    }

    
    Gdk::Point pt1 = source->getContactPoint(this);
    Gdk::Point pt2 = destination->getContactPoint(this);
    setPoint(0, pt1.get_x(), pt1.get_y()-ARROW_LINEWIDTH/2.0);
    Goocanvas::Points points = this->property_points().get_value();
    setPoint(points.get_num_points()-1, pt2.get_x(), pt2.get_y()-ARROW_LINEWIDTH/2.0);
    setLabel(strLabel.c_str());
    updatCoordiantes();
    //printf("%s : %d\n", __FILE__, __LINE__); 
}