/*
** Implements the image tray, which keeps track of all of the user's uploaded
** images, via a list of thumbnails.
**
** Images can be dragged from the tray to the image thumbnail for a given item,
** and the associated image will be used for the item.
**
** Currrent implementation is build on top of YUI classes, for basic functionality
** and for drag and drop.
**
** Notes:
**
*/

/*
** External interface, called on page initialzation to create the tray and
** set everything up properly.
*/
function init_image_tray(tray_node, parent, button, target, image_id, image_desc_id, 
                         thumbnail_width, acct_id, on_dropped_file_func)
{
    var init_tray;
    
    init_tray = function()
    {
        var tray, tparams, yparams;
        var num_cols, num_rows, width;
    
        /*
        ** Set up the size of the tray and the number of rows and columns, based 
        ** on the size of the images.
        **
        ** Note: Setting the 'height' property will lead to a translucent area 
        ** around the actual content, if the content size is smaller than the
        ** specified size. 
        */
    
        num_cols = 4;
        num_rows = 2;
    
        width = num_cols * (thumbnail_width + 12);
        tparams =
        {
            num_cols:       num_cols,
            num_rows:       num_rows,
            image_id:       image_id,
            image_desc_id:  image_desc_id,
            flash_border:   '3px solid #0033ff',
            
            drop_file_func: on_dropped_file_func
            // target_flash_elem:  'drop_target_highlight'
        };

        // Config for the Yahoo object
        yparams = 
        { 
            width:      width + 'px',
            visible:    false,
            draggable:  true,
            close:      true,
        
            // context:    [ button, 'tl', 'tr' ]
            
            // Position at the top right of the visible window
            x:          YAHOO.util.Dom.getViewportWidth() - width - 10,
            y:          3
            
        };
    
        tray = new cImageTray(parent, target, acct_id, tparams, yparams);
    
        // tray.align(YAHOO.widget.Overlay.TOP_LEFT, YAHOO.widget.Overlay.TOP_RIGHT);
        // tray.align('tl', 'tr');
    
        tray.render(tray_node);
    
        YAHOO.util.Event.addListener(button, "click", tray.show, tray, true);

        YAHOO.store.image_tray = tray;
    }
    
    YAHOO.util.Event.addListener(window, "load", init_tray);
}


/*
** This sucks, as it will only allow us to have a singleton object,
** which is okay at the moment, but sucks.
**
** This is only until I figure out how to refer to an object method in 
** a Javascript URL.
**
** Feh.
*/

var g_Tray;

function load_tray_page(page)
{
    if (!g_Tray)
        return;

    g_Tray.load_new_page(page);
}    


function delete_image(img_id)
{
    if (!confirm('Delete this image?'))
        return;

    g_Tray.delete_image(img_id);
}

// parent:  parent element or element ID
// config:  configuration information
// acct_id: ID of currently-logged-in user
//
function cImageTray(parent, target, acct_id, params, yconfig)
{
    /*
    ** Temp-O-Kludge
    */
    
    g_Tray = this;

    /*
    ** EOK
    */
    
    // parent ctor
    this.base = YAHOO.widget.Panel;
    this.base(parent, yconfig);
    
    // class vars
    this.acct_id = acct_id;
    this.drop_target = target;
    
    this.image_id = params.image_id,
    this.image_desc_id = params.image_desc_id,
    
    //this.drop_target_desc = target_desc;
    
    this.num_rows = params.num_rows;
    this.num_cols = params.num_cols;
    this.drop_file_func = params.drop_file_func;
    this.flash_border = params.flash_border;
    
    // this.target_flash_elem = params.target_flash_elem;
    
    // more tK
    
    // Set up the various sections of the tray, as YUI wants them
    this.setHeader("All the images you've uploaded to the Store! site.<br>" +
                   "Drag one onto the thumbnail to use it for this item.");
                   
    // Must set body to something or else it will not get set in the callback.
    // Who knew?
    this.setBody("");
    
    // Enable this if we want the image description in the footer
    // this.setFooter("");
    
    // And fill it with yummy images
    this.make_content();
}

cImageTray.prototype = new YAHOO.widget.Panel;

cImageTray.prototype.base_desc_id   = '_desc';  // Appended to dragged image ID
cImageTray.prototype.dd_objs        = [];
cImageTray.prototype.image_descs    = [];

// Page sizing, display, etc.
cImageTray.prototype.num_rows;  //       = 2;
cImageTray.prototype.num_cols;  //       = 4; //6;
cImageTray.prototype.flash_border;
cImageTray.prototype.target_border;
cImageTray.prototype.target_flash_elem;

cImageTray.prototype.current_page   = 1;
cImageTray.prototype.start_page     = 1;

// Fucntion to be called when we drop a file on the target; set externally
cImageTray.prototype.drop_file_func;

cImageTray.prototype.dd_target;

cImageTray.prototype.make_content = function(page, params)
{
    var url;
    var set_content;
    
    // Fucking scoping rules...
    var that = this;
    
    /*
    ** Note: 
    **
    ** The "for (i in elems) metahopr for going through the returned list from
    ** getElementsByTagName() et. al DOES NOT work in Safari - must use 
    ** "for (i = 0; i < elems.length; i++)" instead...
    */
    set_content = function(arg)
    {
        var table, elems, el, i, id, args;
        var dd, dd_num;
        
        that.setBody(arg);
    
        // arg is a <table> with <span>s for each image
        // Add a drag handler to each
        table = document.getElementById('tray_source');

        args = { resizeFrame: false };
        
        that.dd_objs = [];
        dd_num = 0;    
        
        elems = table.getElementsByTagName('img');
        for (i = 0; i < elems.length; i++)
        {
            el = elems[i];
        
            /******
            // Only looking at <img> elements
            if (el.tagName != 'IMG')
                continue;
            ******/
            
            /*
            ** Set up the drap and drop
            */
            
            // dd = new YAHOO.util.DDProxy(el.id, 'default', args);
            
            dd = new YAHOO.util.DDProxy(el.id);
            that.dd_objs[dd_num++] = dd;
            
            /*********************************************
            // Kill the popup description when drag starts
            dd.onMouseDown = function(e)
            {
                var desc;
                
                desc = that.image_descs[this.id];
                
                desc.visible = false;
                
                // alert(desc + ' : ' + desc.visible);
                
            }
            **********************************************/
            
            /***
            dd.startDrag = function(x, y)
            {
                var desc;
                
                desc = that.image_descs[this.id];
                
                desc.visible = false;
            }
            ***/
            
            dd.onDragEnter = function(e, id)
            {
                if (id != that.drop_target)
                {
                    return;
                }
                
                that.flash_drop_target(id, true);
            }
            
            dd.onDragOut = function(e, id)
            {
                if (id != that.drop_target)
                {
                    return;
                }
            
                that.flash_drop_target(id, false);
            }
                        
            dd.onDragDrop = function(e, id)
            {
                // Bail if this is not the expected destination
                if (id != that.drop_target)
                {
                    return;
                }
                
                // alert('dropped on ' + id);
             
                // p3 = true: Show no border at all
                that.flash_drop_target(id, false, true);
                that.set_item_image(this, id);
            }
            
            dd.endDrag = function(e)
            {
                // alert('done dragging');
            }
            
            /*
            ** Add handlers to the image so that we will see a little 
            ** description of the file at the bottom of the tray when 
            ** the mouse moves over it.
            **
            ** Note: Beware!  These (or, at least the onmouseout handler)
            ** sometimes get called during the page load process.  Gawd
            ** knows why.  And when they do, they throw a 'desc_line has 
            ** no properties' error.  Yippie!  Javascript!
            */
            
            el.onmouseover = function(e)
            {
                var desc, desc_line;
            
                desc = document.getElementById(this.id + '_desc');
                desc_line = document.getElementById('current_image_desc');
                if (desc && desc_line)
                    desc_line.innerHTML = desc.innerHTML;
                
                // Do we want the description in the tray footer instead?
                // that.setFooter(desc.innerHTML);
            }
            
            el.onmouseout = function(e)
            {
                var desc_line;
            
                desc_line = document.getElementById('current_image_desc');
                if (desc_line)
                    desc_line.innerHTML = '&nbsp;<br>&nbsp;';
            }
            
            /*
            ** Build a little popup with the file's description
            */
            
            /************************************************
            
            var desc;
            
            desc = document.getElementById(el.id + '_desc');
            
            // alert(el.id + '_desc : ' + desc.inneHTML;
            
            that.image_descs[el.id] = new YAHOO.widget.Tooltip(el.id + '_description', 
                                     { 
                                        context: el.id,
                                        text: desc.innerHTML
                                     });
            *************************************************/
            
            /*
            **
            var finfo;
            
            finfo = gFileInfo[el.id];
            if (finfo)
            {
                new YAHOO.widget.Tooltip(el.id + '_desc_', 
                                         { context: "'" + el.id + "'",
                                           text: finfo.desc
                                         });
            }
            
            **
            */
            
        }
        
        // Look for proto-links for different pages, and turn them into real links
        var link, p, page_num;
        
        link = document.getElementById('first_tray_page');
        if (link)
        {
            page_num = link.innerHTML - 0;
            link.innerHTML = 
                '<a href = "javascript:load_tray_page(' + page_num + ')">&laquo; First page</a>';
        }
        link = document.getElementById('prev_tray_page');
        if (link)
        {
            page_num = link.innerHTML - 0;
            link.innerHTML = 
                '<a href = "javascript:load_tray_page(' + page_num + ')">&lsaquo; Previous page</a>';
        }
        link = document.getElementById('next_tray_page');
        if (link)
        {
            page_num = link.innerHTML - 0;
            link.innerHTML = 
                '<a href = "javascript:load_tray_page(' + page_num + ')">Next page &rsaquo;</a>';
        }
        link = document.getElementById('last_tray_page');
        if (link)
        {
            page_num = link.innerHTML - 0;
            link.innerHTML = 
                '<a href = "javascript:load_tray_page(' + page_num + ')">Last page &raquo;</a>';
        }
        
        // Do the same for the links to delete individual images
        // var elems, elem, i, img_id;
        var img_id;

        elems = table.getElementsByTagName('span');
        for (i = 0; i < elems.length; i++)
        {
            el = elems[i];
 
            if (el.getAttribute('name') != 'img_delete')
            // if (el.className != 'foo')
                continue;
        
            img_id = el.innerHTML - 0;
            el.innerHTML = 
                '<a href = "javascript:delete_image(' + img_id + ')">Delete this</a>';
        }
    }
    
    // Now set up the drop target
    // Eventually: may be an array of targets
    that.dd_target = new YAHOO.util.DDTarget(that.drop_target);
    
    // Keep track of original target border so we can toggle between it and the 
    // 'item is over target' border
    that.target_border = YAHOO.util.Dom.getStyle(that.drop_target, 'border');    
    
    // Get the thumbnails.  If the page is not specified, show the first page.
    if (!page)
        page = this.start_page;
    this.current_page = page;
    
    // Incoming params are not used for normal display, but for e.g. deleting an image
    if (!params)
        params = {};
        
    params.page = page;
    that.do_command(set_content, params);
}

cImageTray.prototype.do_command = function(callback, params)
{
    var url, f;
    
    if (!params.page)
        params.page = this.start_page;
        
    url = '_get_image_tray.php?' +
    
          'cid='   + this.acct_id + 
          '&rows=' + this.num_rows + 
          '&cols=' + this.num_cols;

    for (f in params)
    {
        url += '&' + f + '=' + params[f];
    }
          
    req = new http_req(HTTP_GET, callback);
    req.send(null, url);
}    

cImageTray.prototype.load_new_page = function(page)
{
    this.make_content(page);
}

cImageTray.prototype.delete_image = function(img_id)
{
    var params;
    
    params = { cmd: 'delete_img', img_id: img_id };
    this.make_content(this.current_page, params);    
}

cImageTray.prototype.flash_drop_target = function(id, state, no_border)
{
    var border;

    if (!this.flash_border)
        return;
        
    /*
    ** For some ungodly reason, IE will barf up an 'invalid argument' error
    ** if there is a ';' at the end of this declaration!
    */
    border = state ? this.flash_border : (no_border ? '' : this.target_border);
    
    if (!border)
        border = '';
        
    YAHOO.util.Dom.setStyle(id, 'border', border);    
}

/***************************************************************************
cImageTray.prototype.flash_drop_target = function(id, state)
{
    var border;

    if (!this.target_flash_elem)
    {
        return;
    }
    
    //
    // For some ungodly reason, IE will barf up an 'invalid argument' error
    // if there is a ';' at the end of this declaration!
    //
    border = state ? '3px solid #0033ff' : '';
 
    YAHOO.util.Dom.setStyle(this.target_flash_elem, 'border', border);    
}
******************************************************************************/

cImageTray.prototype.set_item_image = function(DDSrc, drop_id)
{
    var target, src_id, new_el;
    var src_desc, target_desc;
    
    // Make a copy of the dragged image, and replace the current
    // target thumbnail

    // Copy source, saving original ID but removing it from the copy
    new_el = DDSrc.getEl().cloneNode(true);
    src_id = new_el.id;
    new_el.id = '';
    
    // Get the drop target and replace the image
    // Drop target is not the same as image, but image is contained within
    // Note unintuitive order of parameters in replaceChild()!
    // target = document.getElementById(drop_id);
    
    target = document.getElementById(this.image_id);
    target.replaceChild(new_el, target.firstChild);

    // target.width = new_el.width + 1;
    // target.height = new_el.height + 1;
    
//    YAHOO.util.Dom.setStyle(drop_id, 'width', YAHOO.util.Dom.getStyle(src_id, 'width'));
//    YAHOO.util.Dom.setStyle(drop_id, 'height', YAHOO.util.Dom.getStyle(src_id, 'height'));
    
    // And update the image description
    
//    src_desc = document.getElementById(src_id + this.base_desc_id);
//    target_desc = document.getElementById(this.drop_target_desc);
    
    src_desc = document.getElementById(src_id + this.base_desc_id);
    target_desc = document.getElementById(this.image_desc_id);
    
    target_desc.innerHTML = src_desc.innerHTML;
    
    // Call the background script that will attach the associated
    // image to the proper order item
    if (typeof this.drop_file_func == 'function')
    {
        var m, file_id;
        var callback;
        
        // Update the suggested print size, etc.
        // May not always be applicable
        callback = function(arg)
        {
            var sugg;
            
            sugg = document.getElementById('file_suggestions');
            if (sugg)
                sugg.innerHTML = arg;
        }
        
        // File DB ID is src_id minus any non-numeric characters
        m = src_id.match(/([0-9]+)/);
        file_id = m[1];
    
        this.drop_file_func(file_id, callback);
    }
    
}