//*****************************************************************************
// SortStrEx.cpp : CString配列のソート各種。
//*****************************************************************************

#include "stdafx.h"

void SortStrEx( CString* pstr , int ecount  , int bAbcd ) ;
void SortStrEx2( CString* pstr , int ecount  , int bAbcd , CString* pnstr ) ;
void SortStrEx2Sx( CString* pstr , int ecount  , int bAbcd , CString* pnstr , BYTE* pflag ) ;
void SortStrByIntEx( CString* pstr , int* pint , int ecount  , int bAbcd ) ;
void SortStrExByIntValue( CString* pstr , int ecount , int bAbcd ) ;


static CString* m_pStrToBeSorted ; 
static int m_bSortAbcd ;
//******************************************************************************
// 機能 :
//  注意  :
//******************************************************************************
static int lfcompare( const void *arg1, const void *arg2 )
{
    int index1 = *( (int*)arg1 ) ;
    int index2 = *( (int*)arg2 ) ;

    int ret = _stricmp( (const char*)m_pStrToBeSorted[index1] , (const char*)m_pStrToBeSorted[index2] ) ;

    if ( !m_bSortAbcd )
        ret = -ret ;

    return ret ;


}

//******************************************************************************
// 機能 :指定のCStringポインタ配列をソートする。
//  注意  :bAbcd=TRUE:昇順、FALSE:降順
//******************************************************************************
void SortStrEx( CString* pstr , int ecount  , int bAbcd )
{
    if ( ecount <= 1 )
        return ;

    if ( ecount > 100000 )              
    {                               // 10万個を越える場合は、しない!!!
        MessageBeep( -1 ) ;
        return ;

    }

    m_pStrToBeSorted = pstr ;
    m_bSortAbcd = bAbcd ;

    int* pindex = new int[ecount+10] ;          // 解放を忘れるな!!!

    int i ;
    for ( i = 0 ; i < ecount ; i++ )
        pindex[i] = i ;

    qsort( (void*)pindex , ecount , sizeof(int) , lfcompare ) ;
    
    CString* pwkstr = new CString[ecount+10] ;  // 解放を忘れるな!!!

    int k ;
    for ( i = 0 , k = 0 ; i < ecount ; i++ )
    {
        int index = pindex[i] ;
        pwkstr[k] = pstr[index] ;
        k++ ;

    }

    delete [] pindex ;                  // 解放を忘れるな!!!

    for ( i = 0 ; i < ecount ; i++ )
        pstr[i] = pwkstr[i] ;


    delete [] pwkstr ;                  // 解放を忘れるな!!!


}


//******************************************************************************
// 機能 :指定のCStringポインタ配列をソートする。
//  注意  :bAbcd=TRUE:昇順、FALSE:降順
//          pnstr[]も。pstr[]のソートに連動して再配置
//          ソートチェック対象は、pstr[]の方!!!
//******************************************************************************
void SortStrEx2( CString* pstr , int ecount  , int bAbcd , CString* pnstr )
{
    if ( ecount <= 1 )
        return ;

    if ( ecount > 100000 )              
    {                               // 10万個を越える場合は、しない!!!
        MessageBeep( -1 ) ;
        return ;

    }

    m_pStrToBeSorted = pstr ;
    m_bSortAbcd = bAbcd ;

    int* pindex = new int[ecount+10] ;          // 解放を忘れるな!!!

    int i ;
    for ( i = 0 ; i < ecount ; i++ )
        pindex[i] = i ;

    qsort( (void*)pindex , ecount , sizeof(int) , lfcompare ) ;
    
    CString* pwkstr = new CString[ecount+10] ;  // 解放を忘れるな!!!
    CString* p_nwkstr = new CString[ecount+10] ;    // 解放を忘れるな!!!

    int k ;
    for ( i = 0 , k = 0 ; i < ecount ; i++ )
    {
        int index = pindex[i] ;
        pwkstr[k] = pstr[index] ;
        p_nwkstr[k] = pnstr[index] ;
        k++ ;

    }

    delete [] pindex ;                  // 解放を忘れるな!!!

    for ( i = 0 ; i < ecount ; i++ )
    {
        pstr[i] = pwkstr[i] ;
        pnstr[i] = p_nwkstr[i] ;

    }

    delete [] pwkstr ;                  // 解放を忘れるな!!!
    delete [] p_nwkstr ;                // 解放を忘れるな!!!


}


//******************************************************************************
// 機能 :指定のCStringポインタ配列をソートする。
//  注意  :bAbcd=TRUE:昇順、FALSE:降順
//          pnstr[]も。pstr[]のソートに連動して再配置
//          ソートチェック対象は、pstr[]の方!!!
//          
//          BYTE* pflag 付き!!!!
//******************************************************************************
void SortStrEx2Sx( CString* pstr , int ecount  , int bAbcd , CString* pnstr , BYTE* pflag )
{
    if ( ecount <= 1 )
        return ;

    if ( ecount > 100000 )              
    {                               // 10万個を越える場合は、しない!!!
        MessageBeep( -1 ) ;
        return ;

    }

    m_pStrToBeSorted = pstr ;
    m_bSortAbcd = bAbcd ;

    int* pindex = new int[ecount+10] ;          // 解放を忘れるな!!!

    int i ;
    for ( i = 0 ; i < ecount ; i++ )
        pindex[i] = i ;

    qsort( (void*)pindex , ecount , sizeof(int) , lfcompare ) ;
    
    CString* pwkstr = new CString[ecount+10] ;      // 解放を忘れるな!!!
    CString* p_nwkstr = new CString[ecount+10] ;    // 解放を忘れるな!!!
    BYTE* p_newflag = new BYTE[ecount+10] ;         // 解放を忘れるな!!!

    int k ;
    for ( i = 0 , k = 0 ; i < ecount ; i++ )
    {
        int index = pindex[i] ;
        pwkstr[k] = pstr[index] ;
        p_nwkstr[k] = pnstr[index] ;
        p_newflag[k] = pflag[index] ;
        k++ ;

    }

    delete [] pindex ;                  // 解放を忘れるな!!!

    for ( i = 0 ; i < ecount ; i++ )
    {
        pstr[i] = pwkstr[i] ;
        pnstr[i] = p_nwkstr[i] ;
        pflag[i] = p_newflag[i] ;

    }

    delete [] pwkstr ;                  // 解放を忘れるな!!!
    delete [] p_nwkstr ;                // 解放を忘れるな!!!
    delete [] p_newflag ;               // 解放を忘れるな!!!

}


static int* m_pIntToBeSorted_Ex ; 
static int m_bSortAbcd_Ex ;
//******************************************************************************
// 機能 :
//  注意  :
//******************************************************************************
static int lfcompare_ex( const void *arg1, const void *arg2 )
{
    int index1 = *( (int*)arg1 ) ;
    int index2 = *( (int*)arg2 ) ;

    int ret ;
    if ( m_pIntToBeSorted_Ex[index1] < m_pIntToBeSorted_Ex[index2] )
        ret = -1 ;
    else if ( m_pIntToBeSorted_Ex[index1] > m_pIntToBeSorted_Ex[index2] )
        ret = 1 ;
    else
        ret = 0 ;

    if ( !m_bSortAbcd_Ex )
        ret = -ret ;

    return ret ;


}



//******************************************************************************
// 機能 :指定のCStringポインタ配列を対応するpint[]の値でソートする。
//  注意  :bAbcd=TRUE:昇順、FALSE:降順
//******************************************************************************
void SortStrByIntEx( CString* pstr , int* pint , int ecount  , int bAbcd )
{
    if ( ecount <= 1 )
        return ;

    if ( ecount > 100000 )              
    {                               // 10万個を越える場合は、しない!!!
        MessageBeep( -1 ) ;
        return ;

    }

    m_pIntToBeSorted_Ex = pint ;
    m_bSortAbcd_Ex  = bAbcd ;

    int* pindex = new int[ecount+10] ;          // 解放を忘れるな!!!

    int i ;
    for ( i = 0 ; i < ecount ; i++ )
        pindex[i] = i ;

    qsort( (void*)pindex , ecount , sizeof(int) , lfcompare_ex ) ;
    
    CString* pwkstr = new CString[ecount+10] ;  // 解放を忘れるな!!!

    int k ;
    for ( i = 0 , k = 0 ; i < ecount ; i++ )
    {
        int index = pindex[i] ;
        pwkstr[k] = pstr[index] ;
        k++ ;

    }

    delete [] pindex ;                  // 解放を忘れるな!!!

    for ( i = 0 ; i < ecount ; i++ )
        pstr[i] = pwkstr[i] ;


    delete [] pwkstr ;                  // 解放を忘れるな!!!


}


//******************************************************************************
// 機能 :指定のCStringポインタ配列をソートする。pstr[]のatoi値に従ってソート!!!
//  注意  :bAbcd=TRUE:昇順、FALSE:降順
//******************************************************************************
void SortStrExByIntValue( CString* pstr , int ecount , int bAbcd )
{
    if ( ecount <= 1 )
        return ;

    int* pival = new int[ecount] ;      // 解放を忘れるな!!!

    int i ;
    for ( i = 0 ; i < ecount ; i++ )
        pival[i] = atoi( (const char*)pstr[i] ) ;

    SortStrByIntEx( pstr , pival , ecount  , bAbcd ) ;

    delete [] pival ;                   // 解放を忘れるな!!!

}

//*****************************************************************************
// SortStrEx.cpp : Ver1.00  2007/01/03
// Example :
//  CString plstr[2] ;
//  plstr[0] = "bbb" ;
//  plstr[1] = "aaa" ;
//  SortStrEx( plstr , 2  , TRUE ) ;
//
// Copyright(C) Edcom Inc. (http://www.edcom.jp/) All rights reserved. 
//*****************************************************************************