int ColoredPolygon::CreateDot(float x, float y) {
    if (_dots.size() >= 50) {
        return false;
    }
    int result = -1;
    OnePoint point;
    FPoint p(x, y);
    for (unsigned int i = 0; i < _dots.size() && result < 0; ++i) {
        if (Math::DotNearLine(_dots[i].pos, _dots[(i + 1) % _dots.size()].pos, p)) {
            unsigned int index = (i + 1) % _dots.size();
            point.pos = p;
            if (index < _dots.size()) {
                _dots.insert(_dots.begin() + index, point);
                result = index;
            } else {
                _dots.push_back(point);
                result = _dots.size() - 1;
            }
        }
    }
    if (result >= 0) {
        GenerateTriangles();
    }
    return result;
}
bool ColoredPolygon::RemoveDots()
{
    if (_selectedDots.size() > 0)
    {
        RemoveDot(_selectedDots);
        _selectedDots.clear();
        _dotUnderCursor.clear();
        GenerateTriangles();
        return true;
    }
    return false;
}
ColoredPolygon::ColoredPolygon(const ColoredPolygon &c)
{
    _dots = c._dots;
    CalcWidthAndHeight();
    GenerateTriangles();
    _mouseDown = false;
    _dotUnderCursor.clear();
    _selectedDots.clear();
    _debugDraw = false;
    InitCorners();
    _color = 0xFFFFFFFF;
}
void ColoredPolygon::UpdatePoints(const PointList &points)
{
    _dots.resize(points.size());
    for (uint i = 0; i < points.size(); ++i)
    {
        _dots[i].pos = points[i];
    }
    CalcWidthAndHeight();
    GenerateTriangles();
    _dotUnderCursor.clear();
    _selectedDots.clear();
    InitCorners();
}
void ModelLoader::ReadSurfaceData(FILE* apFile)
{
    vector<TmpTriplet> DataList;
    char tLineBuffer[512];
    TmpTriplet TmpData;
    
    fgets(tLineBuffer,512,apFile);
    
    TmpData.VxRef = 0;	
    TmpData.TexRef = 0;	
    TmpData.NormRef = 0;

    istringstream iss(tLineBuffer);
    vector<string> Words;

    copy(   std::istream_iterator<string>(iss),
            istream_iterator<string>(),
            back_inserter<vector<string> >(Words));
    
    for(unsigned int k = 0; k < Words.size(); ++k)
    {
        string TripletBuffer = Words[k];
        unsigned int i = 0;
        unsigned int j = 0;
        
        int SlashIndexes[2];
        
        while(i < TripletBuffer.size() && TripletBuffer[i] && j < 2)
        {
            if(TripletBuffer[i] == '/')
            {
                SlashIndexes[j++] = i;		
            }
            ++i;
        }
        
        switch(j)
        {
            case 2:
                TmpData.NormRef = atoi(&TripletBuffer[SlashIndexes[1]+1]);
            case 1:
                TmpData.TexRef = atoi(&TripletBuffer[SlashIndexes[0]+1]);
            case 0:
                TmpData.VxRef = atoi(&TripletBuffer[0]);
        }

        DataList.push_back(TmpData);
    }
    
    GenerateTriangles(DataList);
}
ColoredPolygon::ColoredPolygon(const PointList &points)
{
    _dots.resize(points.size());
    for (uint i = 0; i < points.size(); ++i)
    {
        _dots[i].pos = points[i];
    }
    CalcWidthAndHeight();
    GenerateTriangles();
    _mouseDown = false;
    _dotUnderCursor.clear();
    _selectedDots.clear();
    _debugDraw = false;
    InitCorners();
    _color = 0xFFFFFFFF;
}
bool ColoredPolygon::MouseMove(const FPoint &mousePos) {
    if (!MainWindow::Instance()->CreateDotMode() && _mouseDown)
    {
        return true;
    }

    if (!_debugDraw || !_mouseDown) {
        int r = SearchNearest(mousePos.x, mousePos.y);
        if (r == -1)
        {
            _dotUnderCursor.clear();
        }
        else
        {
            _dotUnderCursor = QVector<int>(1, r);
        }
        _mousePos = mousePos;
        return false;
    }

    FPoint start(_mousePos);
    FPoint end(mousePos);

    if (_dotUnderCursor.size() == 0) {
//		_pos.x += (end.x - start.x);
//		_pos.y += (end.y - start.y);
    } else {
        for (unsigned int i = 0; i < _dotUnderCursor.size(); ++i)
        {
            _dots[_dotUnderCursor[i]].pos.x += (end.x - start.x);
            _dots[_dotUnderCursor[i]].pos.y += (end.y - start.y);
        }
        CalcWidthAndHeight();
        GenerateTriangles();
    }
    _mousePos = mousePos;
    return true;
}
void ColoredPolygon::MouseUp(const FPoint &mouse) {
    _mouseDown = false;
    _dotUnderCursor.clear();
    GenerateTriangles();
}
ColoredPolygon::ColoredPolygon(rapidxml::xml_node<> *xe)
{
    _boneName = xe->first_attribute("bone")->value();

    rapidxml::xml_attribute<> *size = xe->first_attribute("size");
    if (size)
    {
        _dots.resize(atoi(size->value()));
        std::string array = xe->first_attribute("dots")->value();
        std::string::size_type start = 0;
        std::string::size_type sigma = array.find(";");
        for (unsigned int j = 0; j < _dots.size(); ++j)
        {
            sscanf(array.substr(start, sigma - start).c_str(), "%g %g", &_dots[j].pos.x, &_dots[j].pos.y);
            start = sigma + 1;
            sigma = array.find(";", start);
        }
    }
    else
    {
        rapidxml::xml_node<> *mesh = xe->first_node("mesh");
        if (mesh)
        {
            int vert = atoi(mesh->first_attribute("vert")->value());
            int ind = atoi(mesh->first_attribute("ind")->value());
            _triangles.GetVB().Resize(vert, ind);
            _dots.resize(vert);
            //_dots.resize(atoi(mesh->first_attribute("vert")->value()));
            unsigned int count = 0;
            for (rapidxml::xml_node<> *i = mesh->first_node(); i; i = i->next_sibling())
            {
                sscanf(i->first_attribute("geom")->value(), "%g;%g;%g;%g"
                       , &_triangles.GetVB().VertXY(count).x
                       , &_triangles.GetVB().VertXY(count).y
                       , &_triangles.GetVB().VertUV(count).x
                       , &_triangles.GetVB().VertUV(count).y
                      );
                _dots[count].pos = _triangles.GetVB().VertXY(count);
                std::string s(i->first_attribute("mass")->value());
                std::string::size_type start = 0;
                std::string::size_type end = s.find(" ", start);
                _dots[count].p[0].boneName = s.substr(start, end - start);
                start = end + 1;
                end = s.find(";", start);
                _dots[count].p[0].mass = atof(s.substr(start, end - start).c_str());
                start = end + 1;
                end = s.find(" ", start);
                _dots[count].p[1].boneName = s.substr(start, end - start);
                start = end + 1;
                _dots[count].p[1].mass = atof(s.substr(start).c_str());
                count++;
            }
        }
    }

    CalcWidthAndHeight();
    GenerateTriangles();
    _mouseDown = false;
    _dotUnderCursor.clear();
    _selectedDots.clear();
    _debugDraw = false;
    InitCorners();
    _color = 0xFFFFFFFF;
}