/*
 * Implementation of the Microsoft Installer (msi.dll)
 *
 * Copyright 2002 Mike McCormack for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/debug.h"
#include "msi.h"
#include "msiquery.h"
#include "objbase.h"
#include "objidl.h"
#include "msipriv.h"
#include "winnls.h"

#include "query.h"

WINE_DEFAULT_DEBUG_CHANNEL(msi);


/* below is the query interface to a table */

typedef struct tagMSIORDERVIEW
{
    MSIVIEW        view;
    MSIDATABASE   *db;
    MSIVIEW       *table;
    UINT          *reorder;
    UINT           num_cols;
    UINT           cols[1];
} MSIORDERVIEW;

static UINT ORDER_compare( MSIORDERVIEW *ov, UINT a, UINT b, UINT *swap )
{
    UINT r, i, a_val = 0, b_val = 0;

    *swap = 0;
    for( i=0; i<ov->num_cols; i++ )
    {
        r = ov->table->ops->fetch_int( ov->table, a, ov->cols[i], &a_val );
        if( r != ERROR_SUCCESS )
            return r;

        r = ov->table->ops->fetch_int( ov->table, b, ov->cols[i], &b_val );
        if( r != ERROR_SUCCESS )
            return r;

        if( a_val != b_val )
        {
            if( a_val > b_val )
                *swap = 1;
            break;
        }
    }

    return ERROR_SUCCESS;
}

static UINT ORDER_mergesort( MSIORDERVIEW *ov, UINT left, UINT right )
{
    UINT r, centre = (left + right)/2, temp, swap = 0, i, j;
    UINT *array = ov->reorder;

    if( left == right )
        return ERROR_SUCCESS;

    /* sort the left half */
    r = ORDER_mergesort( ov, left, centre );
    if( r != ERROR_SUCCESS )
        return r;

    /* sort the right half */
    r = ORDER_mergesort( ov, centre+1, right );
    if( r != ERROR_SUCCESS )
        return r;

    for( i=left, j=centre+1; (i<=centre) && (j<=right); i++ )
    {
        r = ORDER_compare( ov, array[i], array[j], &swap );
        if( r != ERROR_SUCCESS )
            return r;
        if( swap )
        { 
            temp = array[j];
            memmove( &array[i+1], &array[i], (j-i)*sizeof (UINT) );
            array[i] = temp;
            j++;
            centre++;
        }
    }

    return ERROR_SUCCESS;
}

static UINT ORDER_verify( MSIORDERVIEW *ov, UINT num_rows )
{
    UINT i, swap, r;

    for( i=1; i<num_rows; i++ )
    {
        r = ORDER_compare( ov, ov->reorder[i-1], ov->reorder[i], &swap );
        if( r != ERROR_SUCCESS )
            return r;
        if( !swap )
            continue;
        ERR("Bad order! %d\n", i);
        return ERROR_FUNCTION_FAILED;
    }

    return ERROR_SUCCESS;
}

static UINT ORDER_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
{
    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;

    TRACE("%p %d %d %p\n", ov, row, col, val );

    if( !ov->table )
         return ERROR_FUNCTION_FAILED;

    row = ov->reorder[ row ];

    return ov->table->ops->fetch_int( ov->table, row, col, val );
}

static UINT ORDER_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
    UINT r, num_rows = 0, i;

    TRACE("%p %p\n", ov, record);

    if( !ov->table )
         return ERROR_FUNCTION_FAILED;

    r = ov->table->ops->execute( ov->table, record );
    if( r != ERROR_SUCCESS )
        return r;

    r = ov->table->ops->get_dimensions( ov->table, &num_rows, NULL );
    if( r != ERROR_SUCCESS )
        return r;

    ov->reorder = HeapAlloc( GetProcessHeap(), 0, num_rows*sizeof(UINT) );
    if( !ov->reorder )
        return ERROR_FUNCTION_FAILED;

    for( i=0; i<num_rows; i++ )
        ov->reorder[i] = i;

    r = ORDER_mergesort( ov, 0, num_rows - 1 );
    if( r != ERROR_SUCCESS )
        return r;

    r = ORDER_verify( ov, num_rows );
    if( r != ERROR_SUCCESS )
        return r;

    return ERROR_SUCCESS;
}

static UINT ORDER_close( struct tagMSIVIEW *view )
{
    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;

    TRACE("%p\n", ov );

    if( !ov->table )
         return ERROR_FUNCTION_FAILED;

    if( ov->reorder )
        HeapFree( GetProcessHeap(), 0, ov->reorder );
    ov->reorder = NULL;

    return ov->table->ops->close( ov->table );
}

static UINT ORDER_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
{
    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;

    TRACE("%p %p %p\n", ov, rows, cols );

    if( !ov->table )
         return ERROR_FUNCTION_FAILED;

    return ov->table->ops->get_dimensions( ov->table, rows, cols );
}

static UINT ORDER_get_column_info( struct tagMSIVIEW *view,
                UINT n, LPWSTR *name, UINT *type )
{
    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;

    TRACE("%p %d %p %p\n", ov, n, name, type );

    if( !ov->table )
         return ERROR_FUNCTION_FAILED;

    return ov->table->ops->get_column_info( ov->table, n, name, type );
}

static UINT ORDER_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
{
    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;

    TRACE("%p %d %ld\n", ov, eModifyMode, hrec );

    if( !ov->table )
         return ERROR_FUNCTION_FAILED;

    return ov->table->ops->modify( ov->table, eModifyMode, hrec );
}

static UINT ORDER_delete( struct tagMSIVIEW *view )
{
    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;

    TRACE("%p\n", ov );

    if( ov->table )
        ov->table->ops->delete( ov->table );

    if( ov->reorder )
        HeapFree( GetProcessHeap(), 0, ov->reorder );
    ov->reorder = NULL;

    msiobj_release( &ov->db->hdr );
    HeapFree( GetProcessHeap(), 0, ov );

    return ERROR_SUCCESS;
}


MSIVIEWOPS order_ops =
{
    ORDER_fetch_int,
    NULL,
    NULL,
    NULL,
    ORDER_execute,
    ORDER_close,
    ORDER_get_dimensions,
    ORDER_get_column_info,
    ORDER_modify,
    ORDER_delete
};

UINT ORDER_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
{
    MSIORDERVIEW *ov = NULL;
    UINT count = 0, r;

    TRACE("%p\n", ov );

    r = table->ops->get_dimensions( table, NULL, &count );
    if( r != ERROR_SUCCESS )
    {
        ERR("can't get table dimensions\n");
        return r;
    }

    ov = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 
                    sizeof *ov + sizeof (UINT) * count );
    if( !ov )
        return ERROR_FUNCTION_FAILED;
    
    /* fill the structure */
    ov->view.ops = &order_ops;
    msiobj_addref( &db->hdr );
    ov->db = db;
    ov->table = table;
    ov->reorder = NULL;
    ov->num_cols = 0;
    *view = (MSIVIEW*) ov;

    return ERROR_SUCCESS;
}

UINT ORDER_AddColumn( MSIVIEW *view, LPWSTR name )
{
    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
    UINT n, count, r;
    MSIVIEW *table;

    TRACE("%p adding %s\n", ov, debugstr_w( name ) );

    if( ov->view.ops != &order_ops )
        return ERROR_FUNCTION_FAILED;

    table = ov->table;
    if( !table )
        return ERROR_FUNCTION_FAILED;
    if( !table->ops->get_dimensions )
        return ERROR_FUNCTION_FAILED;
    if( !table->ops->get_column_info )
        return ERROR_FUNCTION_FAILED;

    r = table->ops->get_dimensions( table, NULL, &count );
    if( r != ERROR_SUCCESS )
        return r;

    if( ov->num_cols >= count )
        return ERROR_FUNCTION_FAILED;

    r = VIEW_find_column( table, name, &n );
    if( r != ERROR_SUCCESS )
        return r;

    ov->cols[ov->num_cols] = n;
    TRACE("Ordering by column %s (%d)\n", debugstr_w( name ), n);

    ov->num_cols++;

    return ERROR_SUCCESS;
}
