// my curriculum vitae document
var cv;

var vaultOpen = false;

function openVault(filename)
{
    var image = gfGet('hidden_image');
    image.src = filename;
    // FireFox quirks
    if (isGecko())
    {
        gfGet('frame1').style.overflow = "hidden";
        gfGet('frame2').style.overflow = "hidden";
    }
    gfScrollHorizontalParabolically(gfGet('frame1_container'), 0, -371, 2);
    gfScrollHorizontalParabolically(gfGet('frame2_container'), 371, 742, 2);
    
    vaultOpen = true;
}
function closeVault()
{
    gfScrollHorizontalParabolically(gfGet('frame1_container'), -371, 0, 2);
    gfScrollHorizontalParabolically(gfGet('frame2_container'), 742, 371, 2,
        function(){
                if (isGecko())
                {
                    gfGet('frame1').style.overflow = "auto";
                    gfGet('frame2').style.overflow = "auto";
                }
            });
    
    vaultOpen = false;
}
function init()
{
    // show debug messages
    gfLogLevel = gfLogDebug;
    
    // "deactivate" all links
    for (var i=0; i < document.links.length; i++)
        if (document.links[i].className != "external") 
        {
            gfSetColor(document.links[i], "gray");
            document.links[i].style.cursor = "wait";
            document.links[i].onclick = setButterflyGoal;
        }

    showMe();
    importXML( 'cv_PatrickVanBergen.xml', 'loadCV_done' );
}
function loadCV_done(doc)
{
    cv = doc;
    
    if (cv.lastModified)
        gfAddChildText(gfGet('lastModified'), " was last modified on: " + cv.lastModified);

    // allow main functionality: enable links
    for (var i=0; i < document.links.length; i++)
    {
        if (document.links[i].className != "external") gfSetColor(document.links[i], "#E68868");
        document.links[i].style.cursor = "pointer";
    }
    
    // show butterfly?
    butterflyShow = (gfGetCookie('butterflyShow') != "hide");
    gfGet('butterflyCheckbox').checked = butterflyShow;
    butterflyDecide();
}
function clearContent(frameName)
{
    var container = gfGet(frameName);

    // start fade out
    gfFade(container, 1, 0, 0.3, 
        function(){ gfRemoveChildren(container) });
}
function setContent(frameName, content)
{
    var container = gfGet(frameName);
    
    if (vaultOpen) closeVault();
    
    // start fade out
    gfFade(container, 1, 0, 0.3,
        function(){
            gfRemoveChildren(container);
            gfAddChild(container, content);
            content.style.padding = "5px";
            for (var i=0; i < document.links.length; i++)
                document.links[i].onclick = setButterflyGoal;
            gfFade(container, 0, 1, 0.3);
        });
}
function getEmployer(employerName)
{
    var employers = cv.getElementsByTagName('employer');
    for(var i=0; i <employers.length; i++)
    {
        var employer = employers[i];
        if (gfGetFirstChildElementText(employer, "name") == employerName) return employer;
    }
    return false;
}
function getProject(projectTitle)
{
    // search project
    var projects = cv.getElementsByTagName("project");
    for (var i=0; i<projects.length; i++)
    {
        var project = projects[i];
        if (gfGetFirstChildElementText(project, "title") == projectTitle) return project;
    }
    return false;
}
function getSchool(schoolName)
{
    // search school
    var schools = cv.getElementsByTagName("school");
    for (var i=0; i<schools.length; i++)
    {
        var school = schools[i];
        if (gfGetFirstChildElementText(school, "name") == schoolName) return school;
    }
    return false;
}
function flipSpecializationTable(table, link)
{
    gfFlipDisplay(table);
    gfFlipText(link.firstChild, 'Show Projects', 'Hide Projects');
}
function addSpecializationTable(div, projects, specName, specValue)
{
    var id = gfGenerateId();
    var textId = gfGenerateId();
    var a = gfCreateAndAdd(div, "a", {href:"javascript:flipSpecializationTable(gfGet('"+id+"'), gfGet('"+textId+"'))"});
    gfAddChildText(a, "Show Projects");
    a.id = textId;

    var table = gfCreateAndAdd(div, "table", {id:id});
    table.className = "projects";
    table.style.display = "none";
    var tbody = gfCreateAndAdd(table, "tbody");
    
    for (var i=0; i<projects.length; i++)
    {
        var project = projects[i];
        var projectTitle = gfGetFirstChildElementText(project, "title");
        var technical = gfGetFirstChildElement(project, "technical");
        if (technical)
        {
            var technicalItems = gfGetChildElements(technical, specName);
            for (var item=0; item < technicalItems.length; item++)
            {
                var value = technicalItems[item].firstChild.nodeValue
                var index = value.indexOf(specValue);
                if (
                    (value == specValue) ||
                    ((index == 0) && (value.indexOf(' ') == specValue.length))
                )
                {
                    var start = gfGetFirstChildElement(project, "start");
                    var end = gfGetFirstChildElement(project, "end");

                    var row1 = gfCreateAndAdd(tbody, "tr");
                    var cell1 = gfCreateAndAdd(row1, "td");
                    var a = gfCreateAndAdd(cell1, "a", {href:'javascript:showProject("'+projectTitle+'")'});
                    gfAddChildText(a, projectTitle);
                    var row2 = gfCreateAndAdd(tbody, "tr");
                    var cell2 = gfCreateAndAdd(row2, "td");

                    var period = "";
                    if (start) 
                    {
                        period = "- ";
                        period += gfMonthIndex2Text(gfGetAttributeText(start, "month")) + " " + gfGetAttributeText(start, "year");
                        if (end) period += " / " + gfMonthIndex2Text(gfGetAttributeText(end, "month")) + " " + gfGetAttributeText(end, "year");
                        else period += " / present";
                    }
            
                    gfAddChildText(cell2, period);
                    }
            }
        }        
    }    
}
function addProjectToTable(tbody, project)
{
    var projectTitle = gfGetFirstChildElementText(project, "title");
    var start = gfGetFirstChildElement(project, "start");
    var end = gfGetFirstChildElement(project, "end");

    var row1 = gfCreateAndAdd(tbody, "tr");
    var cell1 = gfCreateAndAdd(row1, "td");
    var row2 = gfCreateAndAdd(tbody, "tr");
    var cell2 = gfCreateAndAdd(row2, "td");
    var anchor = gfCreateAndAdd(cell1, "a", {href:"javascript:showProject('"+projectTitle+"')"});
    gfAddChildText(anchor, projectTitle);

    var period = "";
    if (start) 
    {
        period = "- ";
        period += gfMonthIndex2Text(gfGetAttributeText(start, "month")) + " " + gfGetAttributeText(start, "year");
        if (end) period += " / " + gfMonthIndex2Text(gfGetAttributeText(end, "month")) + " " + gfGetAttributeText(end, "year");
        else period += " / present";
    }

    gfAddChildText(cell2, period);
}
function AddFactToTable(tbody, name, value)
{
    var row1 = gfCreateAndAdd(tbody, "tr");
    var cell1 = gfCreateAndAdd(row1, "td");
    var cell2 = gfCreateAndAdd(row1, "td");
    gfAddChildText(cell1, name);
    gfAddChildText(cell2, value);
}
function AddLinkToTable(tbody, name, link, desc, external)
{
    var row1 = gfCreateAndAdd(tbody, "tr");
    var cell1 = gfCreateAndAdd(row1, "td");
    var cell2 = gfCreateAndAdd(row1, "td");
    gfAddChildText(cell1, name);
    var anchor = gfCreateAndAdd(cell2, "a", {href:link});
    if (external) { anchor.className = "external"; anchor.target="_blank"; }
    gfAddChildText(anchor, desc);
}
function showMe()
{
    // right page
    
    var div = gfCreateElement("div");

    // photo
    gfCreateAndAdd(div, "img", {src:"images/pasfoto.jpg", hspace:0, vspace: 10});
    
    // morning or afternoon?
    var heading;
    var hour = new Date().getHours();
    if (hour < 6) heading = "Good night. ";
    else if (hour < 12) heading = "Good morning. ";
    else if (hour < 18) heading = "Good afternoon. ";
    else heading = "Good evening. ";
    
    // title
    var p = gfCreateAndAdd(div, "p");
    p.style.clear = "both";
    gfAddChildText(p, heading + "Allow me to introduce myself. My name is Patrick van Bergen. I am a 35 year old software engineer. In these pages I will tell you shortly about who I am, what I did in the past, and what I'm looking for in the future.");

    var p = gfCreateAndAdd(div, "p");
    gfAddChildText(p, "My main interests are software architecture, webdevelopment, artificial intelligence, and user interface design. I prefer innovating projects and projects with good software architectures. In the past I have worked mostly in small teams, but I would like to work in a large team as well.");

    var p = gfCreateAndAdd(div, "p");
    gfAddChildText(p, "This site also serves as a sandbox for some DHTML experiments. It separates the document, a single XML page, from the view, a Single Page Interface, that is built from JavaScript and cross-browser DOM functionality.");
    
    setContent('frame2', div);

    // left page
    
    div = gfCreateElement("div");

    var table = gfCreateAndAdd(div, "table");
    var tbody = gfCreateAndAdd(table, "tbody");
    table.className = "facts";
    var caption = gfCreateAndAdd(table, "caption");
    gfAddChildText(caption, "Table Of Facts");
    AddFactToTable(tbody, "Profession", "Software developer");
    AddLinkToTable(tbody, "Homepage", "http://www.patrickvanbergen.com/", "www.patrickvanbergen.com", true);
    AddLinkToTable(tbody, "C.V. (Word)", "./CV_PatrickVanBergen.doc", "CV_PatrickVanBergen.doc", true);
    AddLinkToTable(tbody, "E-mail", "mailto:garfix@zonnet.nl", "garfix@zonnet.nl", false);
    AddFactToTable(tbody, "Programming languages", "PHP, Java, C++, XML, HTML, JavaScript, CSS, DHTML");
	AddFactToTable(tbody, "Databases", "MySQL");
    AddFactToTable(tbody, "Hometown", "Lent (Nijmegen)");
    AddFactToTable(tbody, "Birthdate", "November 24, 1969");
    AddFactToTable(tbody, "Speaks", "Dutch, English");
    AddFactToTable(tbody, "Phone number", "<not disclosed here>");
    AddFactToTable(tbody, "Civil status", "Married to Katja van Grieken");
    AddFactToTable(tbody, "Children", "Three daughters: Sky Sarah, Lila Sophia, and Jade Selene");
    
    setContent('frame1', div);
}
function showEmployers()
{
    if (!cv) return;

    var employers = cv.getElementsByTagName('employer');
    var div = gfCreateElement("div");
    
    // title
    var h1 = gfCreateAndAdd(div, "h1");
    gfAddChildText(h1, "Employers");

    // table of employers
    var table = gfCreateAndAdd(div, "table");
    var tbody = gfCreateAndAdd(table, "tbody");

    for (var i=0; i<employers.length; i++)
    {
        var employer = employers[i];
        var employerName = gfGetFirstChildElementText(employer, "name");
        var start = gfGetFirstSiblingElement(employer, "start");
        var end = gfGetFirstSiblingElement(employer, "end");
        
        var row1 = gfCreateAndAdd(tbody, "tr");
        var row2 = gfCreateAndAdd(tbody, "tr");
        var cell1 = gfCreateAndAdd(row1, "td");
        var cell2 = gfCreateAndAdd(row2, "td");
        var anchor = gfCreateAndAdd(cell1, "a", {href:"javascript:showEmployer('"+employerName+"')"});
        
        var period = "";
        if (start) 
        {
            period = "- ";
            period += gfMonthIndex2Text(gfGetAttributeText(start, "month")) + " " + gfGetAttributeText(start, "year");
            if (end) period += " / " + gfMonthIndex2Text(gfGetAttributeText(end, "month")) + " " + gfGetAttributeText(end, "year");
            else period += " / present";
        }

        gfAddChildText(cell2, period);
        gfAddChildText(anchor, employerName);
    }
    setContent('frame2', div);
    clearContent('frame1');
}
function showEmployer(employerName)
{
    if (!cv) return;

    var div = gfCreateElement("div");
    var employer = getEmployer(employerName);
    if (!employer) return;
    
    // logo
    var src = gfGetFirstChildElementText(employer, "logo");
    if (src) gfCreateAndAdd(div, "img", {src:"images/"+src});
    
    // title
    var h1 = gfCreateAndAdd(div, "h1");
    gfAddChildText(h1, employerName);
    
    // website
    var src = gfGetFirstChildElementText(employer, "website");
    if (src) 
    {
        var a = gfCreateAndAdd(div, "a", {href:src, target:"_blank"});
        a.className = "external";
        gfAddChildText(a, "> the company's website");
        gfCreateAndAdd(div, "br");
        gfAddChildText(div, " ");
        gfCreateAndAdd(div, "br");
    }

    // projects
    var projectBase = gfGetFirstSiblingElement(employer, "projects");
    if (projectBase)
    {
        // table of projects
        var projects = gfGetChildElements(projectBase, "project");
        
        var p = gfCreateAndAdd(div, "p");
        if (projects.length == 1)
            gfAddChildText(p, "I participated in this project:");
        else 
            gfAddChildText(p, "I participated in the following projects:");
        
        var table = gfCreateAndAdd(div, "table");
        var tbody = gfCreateAndAdd(table, "tbody");
        table.className = "projects";
        
        for (var i=0; i<projects.length; i++)
        {
            addProjectToTable(tbody, projects[i]);
        }
    }
    
    // courses
    var courseBase = gfGetFirstSiblingElement(employer, "courses");
    if (courseBase)
    {
        // table of courses
        var table = gfCreateAndAdd(div, "table");
        var tbody = gfCreateAndAdd(table, "tbody");
        table.className = "specs";
        var caption = gfCreateAndAdd(table, "caption");
        gfAddChildText(caption, "Courses I took");
        
        var courses = gfGetChildElements(courseBase, "course");
        for (var i=0; i<courses.length; i++)
        {
            var course = courses[i];
            var courseName = course.firstChild.nodeValue;
      
            var row1 = gfCreateAndAdd(tbody, "tr");
            var cell1 = gfCreateAndAdd(row1, "td");
            
            gfAddChildText(cell1, courseName);
        }
    }

    // description
    var desc = gfGetFirstChildElement(employer, "description");
    if (desc)
    {
        var temp = gfCreateAndAdd(div, "div");
        temp.innerHTML = desc.firstChild.nodeValue;
    }
    
    setContent('frame1', div);
}
function addTechnicalSpec(tbody, technical, spec)
{
    var items = gfGetChildElements(technical, spec);
    if (items.length > 0)
    {
        var row = gfCreateAndAdd(tbody, "tr");
        var cell1 = gfCreateAndAdd(row, "td");
        var cell2 = gfCreateAndAdd(row, "td");
        gfAddChildText(cell1, spec);
    
        for (var i=0; i < items.length; i++)
        {
            gfAddChildText(cell2, items[i].firstChild.nodeValue);
            if (i < items.length-1) gfAddChildText(cell2, ", ");
        }
    }
}
function showProject(projectTitle)
{
    if (!cv) return;

    var div = gfCreateElement("div");
    var project = getProject(projectTitle);
    if (!project) return;
    
    // title
    var h1 = gfCreateAndAdd(div, "h1");
    gfAddChildText(h1, projectTitle);

    // website
    var src = gfGetFirstChildElementText(project, "website");
    if (src) 
    {
        var a = gfCreateAndAdd(div, "a", {href:src, target:"_blank"});
        a.className = "external";
        gfAddChildText(a, "> the project's website");
    }

    // image
    if (src) gfCreateAndAdd(div, "br");
    src = gfGetFirstChildElementText(project, "image");
    if (src) 
    {
        var a = gfCreateAndAdd(div, "a", {href:"javascript:showProjectImage('"+projectTitle+"')"});
        gfAddChildText(a, "> an image of the project");
    }

    var technical = gfGetFirstChildElement(project, "technical");
    if (technical)
    {
        // technical specs
        var table = gfCreateAndAdd(div, "table");
        table.className = "specs";
        var tbody = gfCreateAndAdd(table, "tbody");
        var caption = gfCreateAndAdd(table, "caption");
        gfAddChildText(caption, "Technical specifications");
    
        addTechnicalSpec(tbody, technical, "os");
        addTechnicalSpec(tbody, technical, "language");
        addTechnicalSpec(tbody, technical, "tool");
        addTechnicalSpec(tbody, technical, "product");
    }
    
    // description
    var h2 = gfCreateAndAdd(div, "h2");
    gfAddChildText(h2, "Project description");

    var functionality = gfGetFirstChildElement(project, "functionality");
    if (functionality)
    {
        var temp = gfCreateAndAdd(div, "p");
        temp.innerHTML = functionality.firstChild.nodeValue;
    }

    // my job
    var h2 = gfCreateAndAdd(div, "h2");
    gfAddChildText(h2, "My activities");

    var my_job = gfGetFirstChildElement(project, "my_job");
    if (my_job)
    {
        var temp = gfCreateAndAdd(div, "div");
        temp.innerHTML = my_job.firstChild.nodeValue;
    }

    setContent('frame2', div);
}
function showProjectImage(projectTitle)
{
    var project = getProject(projectTitle);
    
    var imageDescription = gfGetFirstChildElementText(project, "image_description");
    gfGet('hidden_image_description').firstChild.nodeValue = imageDescription;
    var src = gfGetFirstChildElementText(project, "image");
    openVault("images/"+src);
}
function showSpecializations()
{
    if (!cv) return;

    var div = gfCreateElement("div");

    // title
    var h1 = gfCreateAndAdd(div, "h1");
    gfAddChildText(h1, "Specialisations");
    var p = gfCreateAndAdd(div, "p");
    var p = gfAddChildText(p, "Although I do not have a single specialization yet, there are some recurring themes in my work. I will name them here, along with the projects in which they were used.");

    var projects = cv.getElementsByTagName('project');

    // gui
    var h2 = gfCreateAndAdd(div, "h2");
    gfAddChildText(h2, "Graphical User Interfaces");
    addSpecializationTable(div, projects, "subject", "GUI");

    // ai
    var h2 = gfCreateAndAdd(div, "h2");
    gfAddChildText(h2, "Artificial Intelligence");
    addSpecializationTable(div, projects, "subject", "AI");

    // web development
    var h2 = gfCreateAndAdd(div, "h2");
    gfAddChildText(h2, "Web development");
    addSpecializationTable(div, projects, "subject", "Web");
    
    // java
    var h2 = gfCreateAndAdd(div, "h2");
    gfAddChildText(h2, "Java");
    addSpecializationTable(div, projects, "language", "Java");

    setContent('frame1', div);
    clearContent('frame2');
}
function showPrivateProjects()
{
    if (!cv) return;

    var div = gfCreateElement("div");
    
    // title
    var h1 = gfCreateAndAdd(div, "h1");
    gfAddChildText(h1, "Private projects");
    
    // table of projects
    var projects = cv.getElementsByTagName("project");
    
    var table = gfCreateAndAdd(div, "table");
    var tbody = gfCreateAndAdd(table, "tbody");
    table.className = "projects";
    
    for (var i=0; i<projects.length; i++)
    {
        var project = projects[i];
        if (project.parentNode.parentNode.getAttribute("type") == "private")
        {
            addProjectToTable(tbody, project);
        }
    }
    
    setContent('frame1', div);
    clearContent('frame2');
}
function showEducation()
{
    if (!cv) return;

    var schools = cv.getElementsByTagName('school');
    var div = gfCreateElement("div");
    
    // title
    var h1 = gfCreateAndAdd(div, "h1");
    gfAddChildText(h1, "Education");

    // table of schools
    var table = gfCreateAndAdd(div, "table");
    var tbody = gfCreateAndAdd(table, "tbody");

    for (var i=0; i<schools.length; i++)
    {
        var school = schools[i];
        var schoolName = gfGetFirstChildElementText(school, "name");
        var start = gfGetFirstSiblingElement(school, "start");
        var end = gfGetFirstSiblingElement(school, "end");
  
        var row1 = gfCreateAndAdd(tbody, "tr");
        var row2 = gfCreateAndAdd(tbody, "tr");
        var cell1 = gfCreateAndAdd(row1, "td");
        var cell2 = gfCreateAndAdd(row2, "td");

          var src = gfGetFirstChildElementText(school, "website");
        if (src) 
        {
            var anchor = gfCreateAndAdd(cell1, "a", {href:'javascript:showSchool("'+schoolName+'")'});
            gfAddChildText(anchor, schoolName);
        }
        else
            gfAddChildText(cell1, schoolName);
        
        var period = "";
        if (start) 
        {
            period = "- ";
            period += gfMonthIndex2Text(gfGetAttributeText(start, "month")) + " " + gfGetAttributeText(start, "year");
            if (end) period += " / " + gfMonthIndex2Text(gfGetAttributeText(end, "month")) + " " + gfGetAttributeText(end, "year");
            else period += " / present";
        }

        gfAddChildText(cell2, period);
    }
    setContent('frame2', div);
    clearContent('frame1');
}
function showSchool(schoolName)
{
    if (!cv) return;

    var div = gfCreateElement("div");
    var school = getSchool(schoolName);
    if (!school) return;
    
    // logo
    var src = gfGetFirstChildElementText(school, "logo");
    if (src) gfCreateAndAdd(div, "img", {src:"images/"+src});

    // title
    var h1 = gfCreateAndAdd(div, "h1");
    gfAddChildText(h1, schoolName);

    // website
    var src = gfGetFirstChildElementText(school, "website");
    if (src) 
    {
        var a = gfCreateAndAdd(div, "a", {href:src, target:"_blank"});
        a.className = "external";
        gfAddChildText(a, "> the school's website");
    }

    // diploma
    var diploma = gfGetFirstSiblingElementText(school, "diploma");
    if (diploma) 
    {
        var d = gfCreateAndAdd(div, "div");
        d.className = "medal";
        gfCreateAndAdd(d, "img", {src:"images/diploma.jpg"});
        gfCreateAndAdd(d, "br");
        gfAddChildText(d, "Diploma: " + diploma);
    }
    else
    {
        var h2 = gfCreateAndAdd(div, "h2");
        gfAddChildText(h2, "No diploma");
    }

    // courses
    var courseBase = gfGetFirstSiblingElement(school, "courses");
    if (courseBase)
    {
        // table of courses
        var table = gfCreateAndAdd(div, "table");
        var tbody = gfCreateAndAdd(table, "tbody");
        table.className = "specs";
        var caption = gfCreateAndAdd(table, "caption");
        gfAddChildText(caption, "Courses I took");
        
        var courses = gfGetChildElements(courseBase, "course");
        for (var i=0; i<courses.length; i++)
        {
            var course = courses[i];
            var courseName = course.firstChild.nodeValue;
      
            var row1 = gfCreateAndAdd(tbody, "tr");
            var cell1 = gfCreateAndAdd(row1, "td");
            
            gfAddChildText(cell1, courseName);
        }
    }
    setContent('frame1', div);
}

// Animation ************************************************************************

function animateTitle(element)
{
    gfChangeParabolically(0, 2*360, 6, 
        function(pos){ gfRotateX(element, pos); });
}

// Butterfly animation ************************************************************************

var startPos = { x: 400, y: -50, angle: 0};
var endPos = { x: 400, y: -50, angle: 0};
var clickPos = { x: 400, y: -50, angle: 0};
var maxFlyLength = 50;
var imageDelay = 0;
var butterflyImageIndex = 0;
var butterflyState = "still";
var butterflyShow = true;

function setNextWingState()
{
    butterflyImageIndex++;
    if (butterflyImageIndex == 2) butterflyImageIndex = 0;

    gfSetVisible(gfGet('butterflyImage1'), butterflyImageIndex == 0);
    gfSetVisible(gfGet('butterflyImage2'), butterflyImageIndex == 1);
}
function fly(pos)
{
    var x = startPos.x + (pos/100)*(endPos.x - startPos.x);
    var y = startPos.y + (pos/100)*(endPos.y - startPos.y);
    var angle = startPos.angle + (pos/100)*(endPos.angle - startPos.angle);
    gfSetBorderPos(gfGet('butterfly'), x, y);
    gfRotateZ(gfGet('butterflyRotator'), 90+angle);

    imageDelay++;
    if (imageDelay == 2)
    {
        imageDelay = 0;
        setNextWingState();
    }
}
function butterflyDecide()
{
    var angle;

    startPos.x = endPos.x;
    startPos.y = endPos.y;
    startPos.angle = endPos.angle;
    
    var dx = clickPos.x - startPos.x;
    var dy = clickPos.y - startPos.y;
    var length = Math.sqrt(dx*dx + dy*dy);
    
    if (butterflyState == "still")
    {
        if (butterflyShow)
        {
            if (length >= 20)
            {
                butterflyState = "flying";
            }
            else if (Math.random() < 0.05)
            {
                setNextWingState();
                gfSchedule(setNextWingState, gfGetRandom(0.2, 0.4));
            }
            else if (Math.random() < 0.01)
            {
                butterflyState = "flying";
                clickPos.y = -50;
                clickPos.x = gfGetRandom(100, 1200);
            }
        }
        gfSchedule(butterflyDecide, 0.5);
    }
    else if (butterflyState == "flying") 
    {
        
        if (length < 20)
        {
            butterflyState = "still";
            gfSchedule(butterflyDecide, 0.5);
        }
        else
        {
            if (length < maxFlyLength)
            {
                endPos.x = startPos.x + dx;
                endPos.y = startPos.y + dy;
            }
            else
            {
                dx = dx * (maxFlyLength / length);
                dy = dy * (maxFlyLength / length);
                endPos.x = startPos.x + dx;
                endPos.y = startPos.y + dy;
                
                endPos.angle = gfGetAngleFromDeltaXY(endPos.x - startPos.x, endPos.y - startPos.y);
                
                var ray = gfGetRandom(maxFlyLength/2, maxFlyLength);
                if (Math.random() < 0.5) angle = 90; else angle = -90;
                endPos.x += ray * Math.cos(deg2radians * (endPos.angle + angle));
                endPos.y += ray * Math.sin(deg2radians * (endPos.angle + angle));
            }
            endPos.angle = gfGetAngleFromDeltaXY(endPos.x - startPos.x, endPos.y - startPos.y);
            if (endPos.angle - startPos.angle > 180) endPos.angle -= 360;
            if (endPos.angle - startPos.angle < -180) endPos.angle += 360;
        
            gfChangeLinearly(0, 100, 0.3, fly, butterflyDecide);
        }
    }
}
function setButterflyGoal()
{
    clickPos.x = gfGetInlineLeft(this);
    clickPos.y = gfGetInlineTop(this);
}
function showButterfly(show)
{
    butterflyShow = show;
    
    gfSetCookie("butterflyShow", (butterflyShow ? "show" : "hide"));
    
    // fly away!
    if (!butterflyShow)
    {
        clickPos.x = 400;
        clickPos.y = -50;
        butterflyState = "flying";
    }
}
