/*
 * 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(msidb);


/* 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 = msi_alloc( 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;

    msi_free( 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,
                MSIRECORD *rec )
{
    MSIORDERVIEW *ov = (MSIORDERVIEW*)view;

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

    if( !ov->table )
         return ERROR_FUNCTION_FAILED;

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

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

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

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

    msi_free( ov->reorder );
    ov->reorder = NULL;

    msiobj_release( &ov->db->hdr );
    msi_free( 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
};

static UINT ORDER_AddColumn( MSIORDERVIEW *ov, LPCWSTR name )
{
    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;
}

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

    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 = msi_alloc_zero( 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;

    for( x = columns; x ; x = x->next )
        ORDER_AddColumn( ov, x->column );

    return ERROR_SUCCESS;
}
