
// ECMAScript coding: UTF-8
/**
 * @file src/resources/create.js
 */

var yg_gameEditor = {
    currentXml: '',
    currentWidth: -1,
    currentHeight: -1,

    // Template
    currentTemplateId: -1,
    currentTemplate: null,

    // Skin
    currentSkin: -1,

    gameName: null,

    // Game container
    gameContainerReady: false,

    // Game creation tool
    creationToolReady: false,

    // Snapshot container
    snapshotContainerReady: false,

    // This index is used for making sure we're receiving the "right" ready notification from
    // flash animations.
    rdyIdx: 0,

    // Image library
    imgLib: new Object(),
    imgLibNext: 0,

    // Image upload poller
    uploadImagePoller: null,

    // User status
    anonymous: true,
    // New game = false, existing game = true
    existingGame: false,

    addImageCommon: function(image, type)
    {
        var i = 'i' + (this.imgLibNext++);

        this.imgLib[i] = {
            'img'       :   new Element('img'), // Keep a reference to it
            'type'      :   type,
            'image'     :   image,
            'loaded'    :   false
        };

        this.imgLib[i].img.onload  = this.onImageLoad.bind(this, i);
        this.imgLib[i].img.onabord = this.onImageFail.bind(this, i);
        this.imgLib[i].img.onerror = this.onImageFail.bind(this, i);

        this.imgLib[i].img.src = image;
        return i;
    },
    bothReady: function()
    {
        // Xml, if any, should be sent at this moment.

        debug('Sending:');
        debug('- XML: ['+this.currentXml+']');
        debug('- WIDTH: '+this.currentWidth);
        debug('- HEIGHT: '+this.currentHeight);

        if ((ct = this.getCT()) != null)
        {
            this.onTitleUpdate();
            ct.ctSetData(this.currentXml, this.currentWidth, this.currentHeight);
        }

        // And (re)enable the save button
        this.enableSave(true);
    },
    creationToolRemoveImage: function(imgurl)
    {
        var i;

        for (i in this.imgLib)
        {
            if (this.imgLib[i].image == imgurl && this.imgLib[i].type == 'upload')
            {
                this.imgLib[i].img.remove();
                delete this.imgLib[i];
                return true;
            }
        }

        return false;
    },
    selectImageUpload: function()
    {
        if (Object.isElement(elem = $('create_image_uploadImagePanel')))
            elem.show();
        if (Object.isElement(elem = $('create_image_pasteUrlPanel')))
            elem.hide();
    },
    selectUrlPaste: function()
    {
        if (Object.isElement(elem = $('create_image_pasteUrlPanel')))
            elem.show();
        if (Object.isElement(elem = $('create_image_uploadImagePanel')))
            elem.hide();
    },
    enableImageRemote: function()
    {
        if (Object.isElement(elem = $('create_image_pasteUrlPanel')))
        {
            elem.addOnlyClassName('status').update(
                '<form onsubmit="yg_gameEditor.onImageRemoteStart($(\'create_image_pasteUrlInput\').value); return false;">\
                URL <input type="text" id="create_image_pasteUrlInput" class="create_image_container_form" style="width: 200px;" onfocus="this.select()">\
            <input type="submit" value="Get Picture" />\
            </form>\
            (like&nbsp;<span style="color:#54BE46;text-decoration:underline;cursor:pointer;" onclick="$(\'create_image_pasteUrlInput\').value=\'http://data.pictogame.com/funnyface.jpg\';">http://data.pictogame.com/funnyface.jpg</span>&nbsp;)<br/>\
            or <a href="javascript:void(0);" onClick="yg_gameEditor.selectImageUpload();" class="create_image_container_links">upload a picture from your computer</a>.'
            );
        }
    },
    enableImageUpload: function()
    {
        if (Object.isElement(elem = $('create_image_uploadImagePanel')))
        {
            elem.addOnlyClassName('status').update('<form action="/services/creation/uploadImage.php" target="creation_image_uploadTarget" '+
                'method="post" enctype="multipart/form-data"> \
                Upload <input type="file" size="25" class="create_image_container_form" name="create_image_uploadInput" onkeydown="return false;" onchange="this.form.submit(); yg_gameEditor.onImageUploadStart();" /> <i>(You can upload a JPG, GIF or PNG file. Max size is 6MB.)</i>\
            </form>\
            or <a href="javascript:void(0);" onClick="yg_gameEditor.selectUrlPaste();" class="create_image_container_links">paste a web URL of a picture<a href="javascript:void(0);" onClick="yg_gameEditor.selectUrlPaste();" class="create_image_container_links">.'
            );
        }
    },
    backToSaveStep1: function()
    {
        /*
        //~ if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
        if (Prototype.Browser.WebKit)
        {
            $('creation_gameSaveContainer').setStyle({ display: 'block', visibility: 'hidden', height: '0px' });
            $('creation_gameCreationContainer').setStyle({ display: 'block', visibility: 'visible', height: '' });
        }
        else
        {
        */
            $('creation_gameCreationContainer').show();
            $('creation_gameSaveContainer').hide();
        /* } */

        // Enable topMenu's login form
        if (Object.isElement(elem = $('topMenuLink_login')))
            elem.setAttribute('onclick', 'yg_showLogin(); return false;');

        // Remove the snapshot container
        this.snapshotContainerDiv.update();

        //Remove content of block_saveStatusDuringAuth
        $('block_saveStatusDuringAuth').update();
    },
    goToSaveStep2: function()
    {
        this.onTitleUpdate();

        if (typeof(urchinTracker) == 'function')
            urchinTracker('/urchin/create_save_button');

        if (!Object.isString(tmp = this.getCT().ctCanSave()))
        {
            $('block_saveStatusBeforeAuth').update('Cannot save because something bad happened').addOnlyClassName('error');
            return;
        }
        else if (tmp.toLowerCase() != 'ok')
        {
            $('block_saveStatusBeforeAuth').update('Cannot save because ' + tmp).addOnlyClassName('error');
            return;
        }

        // Fill-in the xml
        this.currentXml = this.getCT().ctGetXml();
        debug('XML received from CT: ['+this.currentXml+']');

        // We're done, now swap the divs.
        /*
        if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
        if (Prototype.Browser.WebKit)
        {
            $('creation_gameCreationContainer').setStyle({ display: 'block', visibility: 'hidden', height: '0px' });
            $('creation_gameSaveContainer').setStyle({ display: 'block', visibility: 'visible', height: '' });
        }
        else
        {
        */
            $('creation_gameCreationContainer').hide();
            $('creation_gameSaveContainer').show();
        /* } */

        // Disable topMenu's login form
        if (Object.isElement(elem = $('topMenuLink_login')))
            elem.observe('onclick', 'return false;');

        // Then, create the snapshot container
        tmp = '/create/sc/sc.swf?rdyidx='+this.rdyIdx+'&template='+this.currentTemplateId;
        debug('Loading SC file ['+tmp+']');

        this.snapshotContainerDiv.update(makeFlashObject({
            id: 'create_snapshotContainer_flashObj',
            swf: '/create/sc/sc.swf',
            flashvars: 'rdyidx='+this.rdyIdx+'&template='+this.currentTemplateId,
            width: 1,
            height: 1,
            internal: true
        }));

        if (!Object.isElement($('block_signupLogin')))
            this.save();
        else if (!Object.isElement($('signin_and_save')))
        {
            $('block_signinStatus').insert({ after: '<input type="submit" id="signin_and_save" onclick="yg_gameEditor.saveAfterSignIn();" class="buttons" style="margin-left: 100px" value="log in" />' });
            $('block_signupStatus').insert({ after: '<input type="submit" id="signup_and_save" onclick="yg_gameEditor.saveAfterSignUp();" class="buttons" style="margin-left: 150px" value="sign up" />' });
            $('create_saveGame').insert({ after: '<p><a href="javascript:void(0);" onclick="yg_gameEditor.save(true);" style="margin-left: 15px; font-size: 15px">skip sign up</a></p>' });
        }

    },
    saveFromFlash: function()
    {
        //~ setTimeout('yg_gameEditor.goToSaveStep2()', 500);
        this.goToSaveStep2.delay(0.5);
    },
    enableSave: function(enable)
    {
        var buttons = $('create_button', 'create_button2');

        /*
        TODO: remove location.pathname in if statement.

        due to image information not in database, the save button is hidden by default on edit page.
        to show save button on edit page although information was missing, this tweak was added.
        */
        if ((enable && this.imgLibNext != 0) || location.pathname == '/edit.php')
            buttons.invoke('show');
        else
            buttons.invoke('hide');
    },
    getGC: function()
    {
        if (!this.gameContainerReady)
            return null;

        return this.getFlash('create_gameContainer_flashObj');
    },
    getCT: function()
    {
        if (!this.creationToolReady)
            return null;

        return this.getFlash('create_creationTool_flashObj');
    },
    getSC: function()
    {
        // 21/02/2007
        // First check if sc is loaded
        if (!this.snapshotContainerReady)
            return null;

        return this.getFlash('create_snapshotContainer_flashObj');
    },
    getFlash: function(id)
    {
        //~ if (navigator.appName.indexOf('Microsoft') != -1)
        return (Prototype.Browser.IE) ? window[id] : document[id];
    },
    imageGUIHandler: function(i, message)
    {
        switch (this.imgLib[i].type)
        {
            case 'remote':
                // Show the remote address input field again
                if (Object.isUndefined(message) || message == null)
                {
                    message = 'Loading image complete';
                    cssClass = 'status';
                }
                else
                    cssClass = 'error';

                $('create_image_pasteUrlPanel').update(message).addOnlyClassName(cssClass);
                //~ setTimeout('yg_gameEditor.enableImageRemote()', 800);
                this.enableImageRemote.delay(0.8);
                break;
            case 'upload':
                // Show the upload input field again
                this.enableImageUpload();
                break;
        }
    },
    initialize: function(gameId, s3url, flsync)
    {
        this.gameId = gameId;
        this.s3url = s3url;
        this.flsync = flsync;

        this.gameContainerDiv       = $('create_gameContainer_flash');
        this.creationToolDiv        = $('create_creationTool_flash');
        this.snapshotContainerDiv   = $('create_snapshotContainer_flash');

        this.enableImageRemote();
        this.enableImageUpload();
    },
    onImageFail: function(i)
    {
        debug('onImageFail('+i+')');
        debug(this.imgLib[i].type);

        if (Object.isUndefined(this.imgLib[i])) // was removed by creation tool, simply forget about it
            return;

        // Then, should we notify the user?
        switch (this.imgLib[i].type)
        {
            case 'remote':
            case 'upload':
                if (this.imgLib[i].image.empty())
                    error = 'Please select a picture.';
                else
                    error = 'Failed loading your image.';
                break;
        }

        // Okay, look if a GUI action must be undertaken
        this.imageGUIHandler(i, (error || null));

        // Finally, remove the image
        this.imgLib[i].img.remove();
        delete this.imgLib[i];
        this.imgLibNext--;
    },
    onImageLoad: function(i)
    {
        debug('onImageLoad('+i+')');

        if (typeof(urchinTracker) == 'function')
            urchinTracker('/urchin/create_image_ok');

        if (Object.isUndefined(this.imgLib[i])) // was removed by creation tool, simply forget about it
        {
            debug('onImageLoad(): ignoring');
            return;
        }
        // If the creation tool is ready (we don't have to wait until the game container is ready),
        // then send the image...
        if (this.creationToolReady)
        {
            debug('Sending image to the creation tool: '+this.imgLib[i].image);
            this.getCT().ctAddImage(this.imgLib[i].image, true);
        }
        else
        {
            debug('Creation tool not ready, image send deffered');
        }
        // Okay, look if a GUI action must be undertaken
        this.imageGUIHandler(i);
        this.imgLib[i].loaded = true;
        this.enableSave(true);
    },
    onImageRemoteCancel: function(i)
    {
        debug('onImageRemoteCancel('+i+')');

        if (!Object.isUndefined(this.imgLib[i]))
        {
            // remove the element before deleting the global object
            this.imgLib[i].img.remove();
            delete this.imgLib[i];
        }

        this.enableImageRemote();
    },
    onImageRemoteStart: function(url)
    {
        url = url.strip();

        debug('onImageRemoteStart('+url+') : TODO - check if url seems valid...');

        var i = this.addImageCommon(url, 'remote');

        $('create_image_pasteUrlPanel').addOnlyClassName('status').update('\
            Downloading, please wait <img src="/resources/loader.gif" alt="uploading" />\
            <input type="button" id="create_image_cancelRemote" \
            onclick="yg_gameEditor.onImageRemoteCancel(\'' + i + '\'); return false" value="Cancel" />\
        ');
    },
    onImageUploadCancel: function(i)
    {
        // Okay, cancel may happen either while uploading, or while downloading the uploaded image.
        // In the later case, an id will be provided, so that we may effectively cancel the download

        debug('onImageUploadCancel('+i+')');

        // Cancel poller if any
        if (this.uploadImagePoller !== null)
        {
            debug('*** UPLOAD POLL CANCELLED');
            this.uploadImagePoller.abort();
            clearTimeout(this.uploadPollTimer);
            //~ this.uploadImagePoller = null;
        }

        if (i !== null && !Object.isUndefined(this.imgLib[i]))
        {
            this.imgLib[i].img.remove();
            delete this.imgLib[i];
        }

        this.enableImageUpload();
    },
    onImageUploadStart: function()
    {
        $('create_image_uploadImagePanel').addOnlyClassName('status').update('\
            Uploading, please wait <img src="/resources/loader.gif" alt="uploading" />\
            <input type="button" id="create_image_cancelUpload" \
            onclick="yg_gameEditor.onImageUploadCancel(null); return false" value="Cancel" />\
        ');

        debug('*** onImageUploadStart()');

        // Okay, fire Ajax poll

        // Poll every 2,5 seconds. Set timeout to 3 seconds, and pool again if hit.
        this.uploadImagePoller = new yRemote();
        //~ setTimeout('yg_gameEditor.uploadPoll()', 3000);
        this.uploadPollTimer = this.uploadPoll.bind(yg_gameEditor).delay(1);
    },
    onUploadPollLoad: function(status, data)
    {
        debug('*** onUploadPollLoad('+status+', '+data+')');

        if (status == 200 && data !== null)
        {
            // Got definitive response (success or failure)
            if (data.success)
            {
                this.addImageCommon(this.s3url+data.image, 'upload');
                this.uploadImagePoller.abort.bind(yg_gameEditor);
                clearTimeout(this.uploadPollTimer);
            }
            else
            {
                // Okay, this means it definetely failed.
                debug('TODO: Image upload failed: '+data.message);
                $('create_image_uploadImagePanel').update(data.message).addOnlyClassName('error');
                //~ setTimeout('yg_gameEditor.enableImageUpload()', 800);
                this.enableImageUpload.bind(yg_gameEditor).delay(0.8);
            }
            return;
        }
        // Bad reply or unfinished, poll again in 2 seconds
        //~ setTimeout('yg_gameEditor.uploadPoll()', 2500);
        this.uploadPollTimer = this.uploadPoll.bind(yg_gameEditor).delay(2.5);
    },
    onUploadPollTimeout: function()
    {
        debug('*** onUploadPollTimeout()');

        // Okay, reschedule it!
        //~ this.uploadImagePoller = null;
        this.uploadImagePoller.abort.bind(yg_gameEditor);
        // in 0,5 seconds
        //~ setTimeout('yg_gameEditor.uploadPoll()', 500);
        this.uploadPollTimer = this.uploadPoll.bind(yg_gameEditor).delay(0.5);
    },
    saveAfterSignIn: function()
    {
        if ($('block_signinLogin').present() && $('block_signinPassword').present())
        {
            this.anonymous = false;
            signin(null, this.saveRegistered.bind(this));
        }
    },
    saveAfterSignUp: function()
    {
        if ($('block_signupLogin').present() && $('block_signupPassword').present())
        {
            this.anonymous = false;
            signup(null, this.saveRegistered.bind(this));
        }
    },
    save: function(anonymous)
    {
        if (typeof(urchinTracker) == 'function')
            urchinTracker('/urchin/create_login_signup_or_skip');

        this.existingGame = $('create_saveGame_edit').value

        // Check our fields (name & description) prior to trying to authenticate user
        var name = $('create_gameInfo_name');
        this.gameName = (Object.isElement(name)) ? name.getValue().strip() : '';

        // Then, login or register user
        if (!Object.isElement($('block_signupLogin')))
        {
            // There is no signup / signin form
            this.anonymous = false;
            this.saveRegistered();
            return;
        }
        else if (anonymous === true)
        {
            this.anonymous = true;
            if (confirmSkipSignUp() == true)
                this.saveRegistered();
            return;
        }

        $('block_saveStatusDuringAuth').update(
            'You must either login, register or choose to stay anonymous to save this game').addOnlyClassName('error');
    },
    saveRegistered: function()
    {
        // Create ajax request
        var args = {
            game: this.gameId,
            name: this.gameName,
            description: $('create_gameInfo_description').getValue().strip(),
            tags: $('create_gameInfo_tags').getValue().strip(),
            template: this.currentTemplateId,
            width: this.currentWidth,
            height: this.currentHeight,
            skin: this.currentSkin,
            xml: this.currentXml,
            anonymous: this.anonymous,
            edit: $('create_saveGame_edit').getValue()
        };

        // Send the request
        postRequest = new yRemote();

        // Display throbber
        throbber = new yg_throbber();
        throbber.show('block_saveStatusDuringAuth_throbber', null, false);

        postRequest.onLoad = function(status, data)
        {
            debug('postRequest onLoad');
            if (status == 200 && data !== null)
            {
                // Got definitive response (success or failure)
                if (data.success)
                {
                    // Run first request in a couple of seconds
                    //~ setTimeout('runSaveRequest()', 1000);
                    runSaveRequest.delay(1);
                }
                else
                {
                    if (throbber)
                        throbber.hide();
                    var backLinkTitle = 'Back to previous step';
                    var backLink = new Element('a', { href: 'javascript:yg_gameEditor.backToSaveStep1()', title: backLinkTitle }).update(backLinkTitle);
                    var backDiv = new Element('div').update(backLink);
                    $('block_saveStatusDuringAuth').appendChild(backDiv);
                }
            }
        }

        postRequest.post('/services/creation/saveGame.php', args);

        // Fire a global timeout...
        //~ setTimeout('failedSaving()', 120000); // 120 seconds (2 minutes)
        failedSaving.delay(120);

        // That's all folks!
        return true;
    },
    setEditedGameInfo: function(template, name, skin, width, height, ct)
    {
        getXmlRequest = new yRemote();

        getXmlRequest.onLoad = function(status, data)
        {
            debug('getXmlRequest onLoad');
            if (status == 200 && data !== null)
            {
                // Got definitive response (success or failure)
                xml = data;
                yg_gameEditor.selectTemplate(template, name, skin, xml, width, height, ct);
            }
        }
        debug('sending getXmlRequest');
        getXmlRequest.getRawData('/services/creation/getXml.php?gameCode='+this.gameId);

    },
    selectTemplate: function(template, name, skin, xml, width, height, ct)
    {
        var tmp;

        if (typeof(urchinTracker) == 'function')
        {
            urchinTracker('/urchin/create_select_template');
        }

        if (this.currentTemplateId == template)
            return;

        //TODO: hardcode ct v2 limit (100)
        if (template >= 100)
        {
            var answer = confirm('You will be redirected to another page for this game. Your game will not be saved. Are you sure?');
            if (answer == true)
                redirect('/create/' + template + name);
            return;
        }

        this.currentTemplateId = template;

        // Inherits xml from previous template
        if (xml !== null)
            this.currentXml = xml;
        else if (tmp = this.getCT())
            this.currentXml = tmp.ctGetXml();

        this.currentWidth = width;
        this.currentHeight = height;

        this.currentSkin = skin;

        // Okay, the template changed.
        // This means we have to (re)load both the game container and the game creation tool

        // First, shutdown the game container
        gc = this.getGC();
        if (gc != null)
        {
            if (typeof(gc.gcShutdown) != 'undefined')
            {
                gc.gcShutdown();
            }
        }

        // The creation tool *must* be reloaded prior to the container

        // Set to "unready" prior to replacing

        this.rdyIdx++;

        this.gameContainerReady = false;
        if (this.currentCT != ct)
        {
            this.currentCT = ct;
            this.creationToolReady = false;
        }

        // Disable the save buttons until both are loaded and have received their data
        this.enableSave(false);

        // Okay, the above code was failing badly with IE 7. It seems that the hoster *must* be part of the initial DOM

        tmp = '/create/ct/ct'+ct+'.swf';
        tmp += ' & flashvars = "rdyidx='+this.rdyIdx+'&synchro='+this.flsync+'"';

        debug('Loading CT file ['+tmp+']');

        if (!this.creationToolReady)
        {
            this.creationToolDiv.innerHTML = '&nbsp;' + makeFlashObject({
                id: 'create_creationTool_flashObj',
                swf: '/create/ct/ct' + ct + '.swf',
                flashvars: 'rdyidx='+this.rdyIdx+'&synchro='+this.flsync,
                width: 470,
                height: 280,
                internal: true
            });
        }

        // Same applies to the above

        // Resize the game container prior to (re)loading it

        this.gameContainerDiv.setStyle({ width: this.currentWidth+'px', height: this.currentHeight+'px' });


        // this.gameContainerDiv.innerHTML = 'This is the game container, using template ['+template+'] and skin ['+skin+']. It will finish loading in a second.';

        tmp = '/create/gc/gc.swf?rdyidx=' + this.rdyIdx + '&template=' + this.currentTemplateId;
        tmp = tmp +'&skin=' + this.currentSkin + '&synchro=' + this.flsync;

        debug('Loading GC file ['+tmp+']');

        this.gameContainerDiv.innerHTML = makeFlashObject({
            id: 'create_gameContainer_flashObj',
            swf: '/create/gc/gc.swf',
            flashvars: 'rdyidx=' + this.rdyIdx + '&template=' + this.currentTemplateId + '&skin=' + this.currentSkin + '&synchro=' + this.flsync,
            width: this.currentWidth,
            height: this.currentHeight,
            internal: true
        });

        Effect.ScrollTo('creation_gameCreationContainer');
    },
    onTitleUpdate: function()
    {
        if ((ct = this.getCT()) != null)
        {
            if (typeof(ct.ctSetTitle) != 'undefined')
            {
                ct.ctSetTitle($('create_gameInfo_name').value + '.'); // Leave the trailing dot (flash bug)!
            }
        }
    },
    sendLibraryToCreationTool: function()
    {
        var i;
        // Okay, add all images to the creation tool

        for (i in this.imgLib)
        {
            if (this.imgLib[i].loaded)
            {
                debug('Sending ['+this.imgLib[i].image+'] to CT');
                this.getCT().ctAddImage(this.imgLib[i].image, false);
            }
        }
    },
    setCreationToolReady: function(rdyIdx)
    {
        if (rdyIdx != this.rdyIdx)
            return;

        debug('setCreationToolReady('+rdyIdx+')');

        this.creationToolReady = true;

        // Okay, add all images from the library to the creation tool
        this.sendLibraryToCreationTool();

        if (this.gameContainerReady)
            this.bothReady();
    },
    setGameContainerReady: function(rdyIdx)
    {
        if (rdyIdx != this.rdyIdx)
            return;

        debug('setGameContainerReady('+rdyIdx+')');

        this.gameContainerReady = true;

        if (this.creationToolReady)
            this.bothReady();
    },
    setGameContainerSize: function(rdyIdx, gcWidth, gcHeight)
    {
        if (rdyIdx != this.rdyIdx)
            return;

        this.currentWidth = gcWidth;
        this.currentHeight = gcHeight;

        this.gameContainerDiv.setStyle({ width:this.currentWidth, height: this.currentHeight });
    },
    setSnapshotContainerReady: function(rdyIdx)
    {
        if (rdyIdx != this.rdyIdx)
            return;

        debug('setSnapshotContainerReady('+rdyIdx+')');

        this.snapshotContainerReady = true;

        // Xml, if any, should be sent to the snapshot container at this moment.
        debug('XML: ['+this.currentXml+']');
        this.getSC().scSetData(this.currentXml);
    },
    uploadPoll: function()
    {
        // Okay, cancel any poll already running (this should never happen),
        // and make sure the upload process was not canceled by user

        if (this.uploadImagePoller !== null)
            this.uploadImagePoller.abort();
        //~ else
            //~ return;

        // We cheat a bit, the verification is done on the cancel block display status
        if (!$('create_image_uploadImagePanel').visible())
            return;

        // Okay, launch new verification again!

        debug('*** FIRING NEW UPLOAD POLL');

        this.uploadImagePoller = new yRemote();
        //~ this.uploadImagePoller.onLoad = function(status, data) { yg_gameEditor.onUploadPollLoad(status, data); };
        this.uploadImagePoller.onLoad = this.onUploadPollLoad.bind(this);
        this.uploadImagePoller.onTimeout = this.onUploadPollTimeout.bind(this);

        this.uploadImagePoller.get('/services/creation/getImageUploadStatus.php', 3); // 3 seconds timeout
    }
};

/***********************************************************************/
/* Save functions */

function runSaveRequest()
{
    saveRequest = new yRemote();
    saveRequest.onTimeout = function()
    {
        // Reschedule again!
        //~ setTimeout('runSaveRequest()', 1000);
        runSaveRequest.delay(1);
    }

    saveRequest.onLoad = function(status, data)
    {
        debug('saveRequest.onLoad('+status+')');

        if (status == 200 && data !== null)
        {
            // Got response (success or failure)
            if (data.success)
            {
                if (data.saved)
                {
                    if (throbber)
                        throbber.hide();
                    debug('Game was saved');
                    if (typeof(urchinTracker) == 'function')
                    {
                        urchinTracker('/urchin/create_game_save_ok');
                    }
                    //~ setTimeout("redirect('/share.php?game=' + yg_gameEditor.gameId + '&alpha-v=1')", 100);
                    var redirectUrl = '/share.php?game=#{gamecode}&alpha-v=1'.interpolate({ gamecode: yg_gameEditor.gameId });
                    redirect.delay(0.1, redirectUrl);
                    return;
                }
            }
            else
            {
                debug('Got error');
                return;
            }
        }

        // Otherwise, reschedule
        debug('Rescheduling in two seconds');
        //~ setTimeout('runSaveRequest()', 1500);
        runSaveRequest.delay(1.5);
    }

    debug('Scheduling request...');
    saveRequest.get('/services/creation/getSaveStatus.php', 4); // 4 seconds timeout
}

function failedSaving()
{
    debug('failed saving!');
}

/****************************************************************************************************************************/
/* Wrappers for callbacks from flash movies */

function gcReady(rdyidx)
{
    debug('Container tool is ready ('+rdyidx+')');
    //~ setTimeout('yg_gameEditor.setGameContainerReady('+rdyidx+')', 50);
    yg_gameEditor.setGameContainerReady.bind(yg_gameEditor).delay(0.05, rdyidx);
}


/* These are called from the creation tool */

function ctReady(rdyidx)
{
    debug('Creation tool is ready ('+rdyidx+')');
    //~ setTimeout('yg_gameEditor.setCreationToolReady('+rdyidx+')', 50);
    yg_gameEditor.setCreationToolReady.bind(yg_gameEditor).delay(0.05, rdyidx);
}

function ctRemoveImage(imgurl)
{
    // This one is immediate
    yg_gameEditor.creationToolRemoveImage(imgurl);
}

function ctSetSize(rdyidx, gcWidth, gcHeight)
{
    yg_gameEditor.setGameContainerSize(rdyidx, gcWidth, gcHeight);
}

/* Callbacks from snapshot container */
function scReady(rdyidx)
{
    debug('Snapshot tool is ready ('+rdyidx+')');
    //~ setTimeout('yg_gameEditor.setSnapshotContainerReady('+rdyidx+')', 50);
    yg_gameEditor.setSnapshotContainerReady.bind(yg_gameEditor).delay(0.05, rdyidx);
}

/* Message Box Example */

function confirmSkipSignUp()
{
    return confirm('Are you sure? You won\'t be able to edit this game later.');
}
