/*
 * carotDlg.cpp : ここうさぎウィザード carot
 *      メインダイアログ インプリメンテーション ファイル
 *          written by H.Tsujimura  15 Oct 2004
 *
 * $Log: /makeRSS/carot/carotDlg.cpp $
 * 
 * 84    09/03/24 18:57 Tsujimura543
 * Windows Live Spaces 拡張版 metaWeblog API 採用ブログの
 * 「カテゴリ一覧取得」に対応
 * 
 * 83    09/03/23 16:14 Tsujimura543
 * Windows Live Spaces およびウェブリブログの blogID の扱いに関する修正
 * 
 * 82    09/03/20 23:00 Tsujimura543
 * ウェブリブログの XML-RPC API 経由ではない方の諸々を削除
 * 
 * 81    09/03/20 22:27 Tsujimura543
 * はてなダイアリー(の Atom API での投稿)に対応した
 * 
 * 80    09/03/20 18:27 Tsujimura543
 * ウェブリブログの XMLRPC API 対応作業開始
 * 
 * 79    07/12/05 23:18 Tsujimura543
 * unbase64() の引数追加に伴う修正を実施
 * 
 * 78    07/11/30 3:11 Tsujimura543
 * Jugem、ヤプログ!、ドリコムブログの XML-RPC API 経由の方の初期化
 * 処理を整理
 * 
 * 77    07/11/30 3:09 Tsujimura543
 * コメントを修正
 * 
 * 76    07/11/30 2:52 Tsujimura543
 * (1) Jugem、ヤプログ!、ドリコムブログの XML-RPC API 経由ではない方の
 *     諸々を削除
 * (2) しまにてぃ内日記関連の諸々を削除 (2007年11月30日でサービス終了)
 * 
 * 75    07/10/29 17:55 Tsujimura543
 * ヤプログ! の XML-RPC API に対応
 * 
 * 74    07/10/29 16:49 Tsujimura543
 * yaplog_x → yaplogX に変更
 * 
 * 73    07/10/18 0:18 Tsujimura543
 * バージョン管理用コメント、IDを入れるようにする
 */

#include "carot.h"
#include "carotDlg.h"
#include "EndPointDlg.h"
#include "BlogIDSelectDlg.h"
#include "SelectBlogPet.h"
#include "EditBlogInfoDlg.h"
#include "AddBlogInfoDlg.h"
#include "AboutDlg.h"
#include <sys/stat.h>
#include <direct.h>
#include <Shlwapi.h>

#ifndef	lint
static char	*rcs_id =
"$Header: /makeRSS/carot/carotDlg.cpp 84    09/03/24 18:57 Tsujimura543 $";
#endif

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCarotDlg ダイアログ

CCarotDlg::CCarotDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CCarotDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CCarotDlg)
	m_blogPassword = _T("");
	m_blogUserName = _T("");
	m_cousagiName = _T("");
	m_cousagiPassword = _T("");
	m_cousagiUserName = _T("");
	m_userName = _T("");
	m_endpointURL = _T("");
	m_blogID = _T("");
	m_postForcely = FALSE;
	m_associateID = _T("");
	m_blogPetID = _T("");
	m_categoryName = _T("");
	m_blogPetType = _T("");
	m_useWritingForPet = FALSE;
	m_blogName = _T("");
	m_blogURL = _T("");
	//}}AFX_DATA_INIT

    m_blogKind = unset;
    m_haiku    = false;
    m_keyword  = false;
    strcpy( m_settingDir,  "setting" );
    strcpy( m_settingFile, "carot.inf" );
    strcpy( m_petInfoFile, "blogPet.inf" );
    strcpy( m_blogInfoFile, "blogList.inf" );
    m_editorPath[0]  = NULL;
    m_currentPetID   = 0;
    m_currentBlogID  = 0;

	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

CCarotDlg::~CCarotDlg()
{
    CCarotApp   *cp = (CCarotApp *)AfxGetApp();

    if ( checkProxyInfo() ) {
        // proxy関連の設定に誤りがあると思われる場合、次回起動時に再設定可能と
        // するため、いまの設定をいったん破棄する
        cp->m_proxyType = CCarotApp::autoDetect;
        saveSetting();
    }
}

void CCarotDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCarotDlg)
	DDX_Control(pDX, IDC_COMBO_BLOGKIND, m_blogKindList);
	DDX_Control(pDX, IDC_COMBO_BLOGPETTYPE, m_blogPetTypeList);
	DDX_Control(pDX, IDC_LIST_CATEGORY, m_categoryList);
	DDX_Text(pDX, IDC_EDIT_BLOG_PASSWORD, m_blogPassword);
	DDV_MaxChars(pDX, m_blogPassword, 16);
	DDX_Text(pDX, IDC_EDIT_BLOG_USERNAME, m_blogUserName);
	DDV_MaxChars(pDX, m_blogUserName, 80);
	DDX_Text(pDX, IDC_EDIT_COUSAGI_NAME, m_cousagiName);
	DDV_MaxChars(pDX, m_cousagiName, 32);
	DDX_Text(pDX, IDC_EDIT_COUSAGI_PASSWORD, m_cousagiPassword);
	DDV_MaxChars(pDX, m_cousagiPassword, 32);
	DDX_Text(pDX, IDC_EDIT_COUSAGI_USERNAME, m_cousagiUserName);
	DDV_MaxChars(pDX, m_cousagiUserName, 80);
	DDX_Text(pDX, IDC_EDIT_USER_NAME, m_userName);
	DDV_MaxChars(pDX, m_userName, 80);
	DDX_Text(pDX, IDC_EDIT_ENDPOINT_URL, m_endpointURL);
	DDV_MaxChars(pDX, m_endpointURL, 384);
	DDX_Text(pDX, IDC_EDIT_BLOG_ID, m_blogID);
	DDV_MaxChars(pDX, m_blogID, 48);
	DDX_Check(pDX, IDC_CHECK_POST_FORCELY, m_postForcely);
	DDX_Text(pDX, IDC_EDIT_ASSOCIATE_ID, m_associateID);
	DDV_MaxChars(pDX, m_associateID, 20);
	DDX_Text(pDX, IDC_EDIT_BLOGPET_ID, m_blogPetID);
	DDV_MaxChars(pDX, m_blogPetID, 64);
	DDX_LBString(pDX, IDC_LIST_CATEGORY, m_categoryName);
	DDX_CBString(pDX, IDC_COMBO_BLOGPETTYPE, m_blogPetType);
	DDV_MaxChars(pDX, m_blogPetType, 16);
	DDX_Check(pDX, IDC_CHECK_WRITING, m_useWritingForPet);
	DDX_Text(pDX, IDC_EDIT_BLOG_NAME, m_blogName);
	DDV_MaxChars(pDX, m_blogName, 127);
	DDX_Text(pDX, IDC_EDIT_BLOG_URL, m_blogURL);
	DDV_MaxChars(pDX, m_blogURL, 384);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CCarotDlg, CDialog)
	//{{AFX_MSG_MAP(CCarotDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDOK, OnExecuteCocousagi)
	ON_BN_CLICKED(IDC_RADIO_KEYWORD_ON, OnRadioKeywordOn)
	ON_BN_CLICKED(IDC_RADIO_KEYWORD_OFF, OnRadioKeywordOff)
	ON_BN_CLICKED(IDC_RADIO_HAIKU_ON, OnRadioHaikuOn)
	ON_BN_CLICKED(IDC_RADIO_HAIKU_OFF, OnRadioHaikuOff)
	ON_WM_SHOWWINDOW()
	ON_BN_CLICKED(IDCANCEL, OnExit)
	ON_BN_CLICKED(IDC_CHECK_POST_FORCELY, OnCheckPostForcely)
	ON_BN_CLICKED(IDC_RADIO_SIMILARITY_ON, OnRadioSimlarityOn)
	ON_BN_CLICKED(IDC_RADIO_SIMILARITY_OFF, OnRadioSimilarityOff)
	ON_EN_KILLFOCUS(IDC_EDIT_ASSOCIATE_ID, OnKillfocusEditAssociateId)
	ON_BN_CLICKED(IDC_BUTTON_GET_CATEGORIES, OnButtonGetCategories)
	ON_LBN_SELCHANGE(IDC_LIST_CATEGORY, OnSelchangeListCategory)
	ON_BN_CLICKED(IDC_BUTTON_SWITCH_PET, OnButtonSwitchPet)
	ON_CBN_SELCHANGE(IDC_COMBO_BLOGPETTYPE, OnSelchangeComboBlogPetType)
	ON_CBN_SELCHANGE(IDC_COMBO_BLOGKIND, OnSelchangeComboBlogKind)
	ON_EN_KILLFOCUS(IDC_EDIT_BLOGPET_ID, OnKillfocusEditBlogPetID)
	ON_EN_KILLFOCUS(IDC_EDIT_COUSAGI_NAME, OnKillfocusEditCousagiName)
	ON_EN_KILLFOCUS(IDC_EDIT_COUSAGI_USERNAME, OnKillfocusEditCousagiUserName)
	ON_EN_KILLFOCUS(IDC_EDIT_COUSAGI_PASSWORD, OnKillfocusEditCousagiPassword)
	ON_EN_KILLFOCUS(IDC_EDIT_ENDPOINT_URL, OnKillfocusEditEndpointURL)
	ON_BN_CLICKED(IDC_BUTTON_SWITCH_BLOG, OnButtonSwitchBlog)
	ON_BN_CLICKED(IDC_CHECK_WRITING, OnCheckWriting)
	ON_EN_KILLFOCUS(IDC_EDIT_BLOG_USERNAME, OnKillfocusEditBlogUsername)
	ON_EN_KILLFOCUS(IDC_EDIT_BLOG_PASSWORD, OnKillfocusEditBlogPassword)
	ON_EN_KILLFOCUS(IDC_EDIT_BLOG_ID, OnKillfocusEditBlogID)
	ON_BN_CLICKED(IDC_BUTTON_BROWSE_BLOG, OnButtonBrowseBlog)
	ON_BN_CLICKED(IDC_BUTTON_BROWSE_BLOGPET, OnButtonBrowseBlogPet)
	ON_BN_CLICKED(IDC_BUTTON_SETPROXYINFO, OnButtonSetProxyInfo)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCarotDlg 追加メソッド

bool    CCarotDlg::allocateBlogPetInfo()
{
    CCarotApp   *cp = (CCarotApp *)AfxGetApp();

    if ( cp->m_numOfBlogPets == 0 ) {
        cp->m_blogPetList = new CCarotApp::blogPetList [MAX_NUM_OF_BLOGPETS];
        if ( cp->m_blogPetList == NULL )
            return ( false );

        for ( long i = 0; i < MAX_NUM_OF_BLOGPETS; i++ ) {
            cp->m_blogPetList[i].blogPetName[0]     = NUL;
            cp->m_blogPetList[i].blogPetID[0]       = NUL;
            cp->m_blogPetList[i].blogPetUsername[0] = NUL;
            cp->m_blogPetList[i].blogPetPassword[0] = NUL;
            cp->m_blogPetList[i].blogPetType        = BPTYPE_UNKNOWN;
        }

        return ( true );
    }

    return ( false );
}

bool    CCarotDlg::allocateBlogInfo()
{
    CCarotApp   *cp = (CCarotApp *)AfxGetApp();

    if ( cp->m_numOfBlogs == 0 ) {
        cp->m_blogList = new CCarotApp::blogList [MAX_NUM_OF_BLOGS];
        if ( cp->m_blogList == NULL )
            return ( false );

        for ( long i = 0; i < MAX_NUM_OF_BLOGS; i++ ) {
            cp->m_blogList[i].blogKind         = unset;
            cp->m_blogList[i].blogName[0]      = NUL;
            cp->m_blogList[i].blogUsername[0]  = NUL;
            cp->m_blogList[i].blogPassword[0]  = NUL;
            cp->m_blogList[i].blogID[0]        = NUL;
            cp->m_blogList[i].blogURL[0]       = NUL;
            cp->m_blogList[i].endpointURL[0]   = NUL;
            cp->m_blogList[i].numOfCategories  = 0;
            cp->m_blogList[i].catagory         = NULL;
        }

        return ( true );
    }

    return ( false );
}


void    CCarotDlg::switchKeyword( bool value )
{
    CButton *p;

    if ( value == true ) {
        p = (CButton *)GetDlgItem( IDC_RADIO_KEYWORD_ON );
        p->SetCheck( 1 );

        p = (CButton *)GetDlgItem( IDC_RADIO_KEYWORD_OFF );
        p->SetCheck( 0 );

        m_keyword = true;
    }
    else {
        p = (CButton *)GetDlgItem( IDC_RADIO_KEYWORD_OFF );
        p->SetCheck( 1 );

        p = (CButton *)GetDlgItem( IDC_RADIO_KEYWORD_ON );
        p->SetCheck( 0 );

        m_keyword = false;
    }
}

void    CCarotDlg::switchHaiku( bool value )
{
    CButton *p;

    if ( value == true ) {
        p = (CButton *)GetDlgItem( IDC_RADIO_HAIKU_ON );
        p->SetCheck( 1 );

        p = (CButton *)GetDlgItem( IDC_RADIO_HAIKU_OFF );
        p->SetCheck( 0 );

        m_haiku = true;
    }
    else {
        p = (CButton *)GetDlgItem( IDC_RADIO_HAIKU_OFF );
        p->SetCheck( 1 );

        p = (CButton *)GetDlgItem( IDC_RADIO_HAIKU_ON );
        p->SetCheck( 0 );

        m_haiku = false;
    }
}

void    CCarotDlg::switchPostForcely( bool value )
{
    CButton *p = (CButton *)GetDlgItem( IDC_CHECK_POST_FORCELY );

    if ( value == true ) {
        p->SetCheck( 1 );
        m_postForcely = TRUE;
    }
    else {
        p->SetCheck( 0 );
        m_postForcely = FALSE;
    }
}

void    CCarotDlg::switchUseWriting( bool value )
{
    CButton *p = (CButton *)GetDlgItem( IDC_CHECK_WRITING );

    if ( value == true ) {
        p->SetCheck( 1 );
        m_useWritingForPet = TRUE;
    }
    else {
        p->SetCheck( 0 );
        m_useWritingForPet = FALSE;
    }
}

void    CCarotDlg::switchSimilarity( bool value )
{
    CButton *p;

    if ( /*
         (m_blogKind == ameblo)     || */
         (m_blogKind == exciteBlog) ||
         (m_blogKind == mixi)       ||
         (m_blogKind == kinugasa)   ||
         (m_blogKind == fc2network) ||
         (m_blogKind == echoo)      ||
         (m_blogKind == colors)     ||
         (m_blogKind == openPne)    ||
         (m_blogKind == rakuten) /* ||
         (m_blogKind == webry)   */    ) {
        p = (CButton *)GetDlgItem( IDC_RADIO_SIMILARITY_ON );
        p->EnableWindow( FALSE );

        p = (CButton *)GetDlgItem( IDC_RADIO_SIMILARITY_OFF );
        p->EnableWindow( FALSE );
        value = false;
    }
    else {
        p = (CButton *)GetDlgItem( IDC_RADIO_SIMILARITY_ON );
        p->EnableWindow( TRUE );

        p = (CButton *)GetDlgItem( IDC_RADIO_SIMILARITY_OFF );
        p->EnableWindow( TRUE );
    }

    if ( value == true ) {
        p = (CButton *)GetDlgItem( IDC_RADIO_SIMILARITY_ON );
        p->SetCheck( 1 );

        p = (CButton *)GetDlgItem( IDC_RADIO_SIMILARITY_OFF );
        p->SetCheck( 0 );

        m_similarity = true;
    }
    else {
        p = (CButton *)GetDlgItem( IDC_RADIO_SIMILARITY_OFF );
        p->SetCheck( 1 );

        p = (CButton *)GetDlgItem( IDC_RADIO_SIMILARITY_ON );
        p->SetCheck( 0 );

        m_similarity = false;
    }

    switchAssociateID( value );
}

void    CCarotDlg::switchAssociateID( bool value )
{
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_ASSOCIATE_ID );
    p->SetReadOnly( value == true ? FALSE : TRUE );
    p->SetWindowText( m_associateID );
}

void    CCarotDlg::switchEndpointURL( int blogKindIndex /* = -1 */ )
{
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_ENDPOINT_URL );

    if ( (m_blogKind == movableType) ||
         (m_blogKind == bloggerAPI)  ||
         (m_blogKind == metaWeblog)  ||
         (m_blogKind == mtAPI)       ||
         (m_blogKind == atomAPI)     ||
         (m_blogKind == newPostOnly)    ) {    
     // m_endpointURL = "";
        p->SetReadOnly( FALSE );
    }
    else {
        p->SetReadOnly( TRUE );

        if ( (m_blogKind == typepad)      ||
             (m_blogKind == typepadJapan) ||
             (m_blogKind == cocolog)      ||
             (m_blogKind == cocologFree)  ||
             (m_blogKind == blogzine)     ||
             (m_blogKind == newsHandler)  ||
             (m_blogKind == ameblo)       ||
             (m_blogKind == seesaa)       ||
             (m_blogKind == netLaputa)    ||
             (m_blogKind == blogG)        ||
             (m_blogKind == fc2blog)      ||
             (m_blogKind == gooBlog)      ||
             (m_blogKind == msnSpaces)    ||
             (m_blogKind == drecomX)      ||
             (m_blogKind == yaplogX)      ||
             (m_blogKind == jugemX)       ||
             (m_blogKind == webryX)       ||
             (m_blogKind == livedoor)     ||
             (m_blogKind == lovelog)      ||
             (m_blogKind == sonet)        ||
             (m_blogKind == vox)          ||
             (m_blogKind == hatena)       ||
             (m_blogKind == blogger)         ) {
            if ( blogKindIndex == -1 ) {
                int i;
                for ( i = 0; i < m_numOfBlogKinds; i++ ) {
                    if ( m_blogKindInfo[i].blogKind == m_blogKind )
                        break;
                }
                blogKindIndex = i;
            }
            m_endpointURL = m_blogKindInfo[blogKindIndex].endpointURL;
        }
        else
            m_endpointURL = "";
    }

    p->SetWindowText( m_endpointURL );

    bool    buttonStatus = true;
    CButton *bp = (CButton *)GetDlgItem( IDOK );
    if ( m_endpointURL.GetLength() <= 0 )
        if ( (m_blogKind == movableType) ||
             (m_blogKind == metaWeblog)  ||
             (m_blogKind == mtAPI)       ||
             (m_blogKind == atomAPI)        )
            buttonStatus = false;
    if ( buttonStatus == false )
        bp->SetWindowText( "エンドポイントURL取得" );
    else
        bp->SetWindowText( "ここうさぎ実行" );
}

void    CCarotDlg::switchBlogID( const char *blogID /* = NULL */ )
{
    CEdit   *cp = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_ID );
    CButton *bp = (CButton *)GetDlgItem( IDC_BUTTON_GET_CATEGORIES );
    if ( (m_blogKind == movableType)  ||
         (m_blogKind == bloggerAPI)   ||
         (m_blogKind == metaWeblog)   ||
         (m_blogKind == mtAPI)        ||
         (m_blogKind == atomAPI)      ||
         (m_blogKind == typepad)      ||
         (m_blogKind == typepadJapan) ||
         (m_blogKind == cocolog)      ||
         (m_blogKind == cocologFree)  ||
         (m_blogKind == blogzine)     ||
         (m_blogKind == newsHandler)  ||
         (m_blogKind == seesaa)       ||
         (m_blogKind == netLaputa)    ||
         (m_blogKind == blogG)        ||
         (m_blogKind == fc2blog)      ||
         (m_blogKind == gooBlog)      ||
         (m_blogKind == msnSpaces)    ||
         (m_blogKind == drecomX)      ||
         (m_blogKind == yaplogX)      ||
         (m_blogKind == jugemX)       ||
         (m_blogKind == webryX)       ||
         (m_blogKind == livedoor)     ||
         (m_blogKind == lovelog)   /* ||
         (m_blogKind == ameblo)       ||
         (m_blogKind == sonet)        ||
         (m_blogKind == vox)          ||
         (m_blogKind == hatena)       ||
         (m_blogKind == blogger)   */     ) {
            /* 注意: So-net blog, Blogger.com, アメーバブログ では Atom API */
            /*       によるカテゴリの取得は今のところサポートされていない   */
        if ( blogID && *blogID )
            m_blogID = blogID;
        else
            m_blogID = "";
        cp->SetWindowText( (const char *)m_blogID );
        cp->SetReadOnly( FALSE );

        // 「カテゴリ一覧取得」ボタンを enable にする
        bp->EnableWindow( TRUE );
    }
    else if ( (m_blogKind == echoo)      ||
              (m_blogKind == exciteBlog) ||
              (m_blogKind == rakuten)       ) {
        m_blogID = "";
        cp->SetWindowText( "" );
        cp->SetReadOnly( TRUE );

        // 「カテゴリ一覧取得」ボタンを enable にする
        bp->EnableWindow( TRUE );
    }
    else {
        if ( m_blogKind == newPostOnly ) {
            if ( blogID && *blogID )
                m_blogID = blogID;
            else
                m_blogID = "";
        }
        else
            m_blogID = "";
        cp->SetWindowText( "" );
        cp->SetReadOnly( TRUE );

        // 「カテゴリ一覧取得」ボタンを disable にする
        bp->EnableWindow( FALSE );
    }

    switchSimilarity( m_similarity );
    m_categoryList.ResetContent();
    m_categoryName = "";
}

void    CCarotDlg::switchBlogPetInfo()
{
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_COUSAGI_NAME );
    p->SetWindowText( m_cousagiName );

    p = (CEdit *)GetDlgItem( IDC_EDIT_BLOGPET_ID );
    p->SetWindowText( (const char *)m_blogPetID );

    p = (CEdit *)GetDlgItem( IDC_EDIT_COUSAGI_USERNAME );
    p->SetWindowText( (const char *)m_cousagiUserName );

    p = (CEdit *)GetDlgItem( IDC_EDIT_COUSAGI_PASSWORD );
    p->SetWindowText( (const char *)m_cousagiPassword );
    if ( m_cousagiPassword.GetLength() == 0 ) {
        MessageBox( "BlogPet のパスワードを設定し直して下さい。    ",
                    "パスワード再設定", MB_OK|MB_ICONWARNING );
    }

    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    m_blogPetTypeList.SetCurSel( cp->m_blogPetList[m_currentPetID].blogPetType );
}

void    CCarotDlg::switchBlogInfo()
{
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_NAME );
    p->SetWindowText( m_blogName );

    p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_USERNAME );
    p->SetWindowText( (const char *)m_blogUserName );

    p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_PASSWORD );
    p->SetWindowText( (const char *)m_blogPassword );
    if ( m_blogPassword.GetLength() == 0 ) {
        MessageBox( "blog のパスワードを設定し直して下さい。    ",
                    "パスワード再設定", MB_OK|MB_ICONWARNING );
    }

    p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_ID );
    p->SetWindowText( (const char *)m_blogID );

    p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_URL );
    p->SetWindowText( (const char *)m_blogURL );

    p = (CEdit *)GetDlgItem( IDC_EDIT_ENDPOINT_URL );
    p->SetWindowText( (const char *)m_endpointURL );

    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    if ( cp->m_blogList ) {
        int i = -1;

        if ( (m_blogKind == newPostOnly) &&
             (cp->m_blogList[m_currentBlogID].useCbox == true) ) {
            // 「BlogPet 飼育箱」のための特別処理
            for ( i = 0; i < m_numOfBlogKinds; i++ ) {
                if ( !strcmp( m_blogKindInfo[i].blogKindString,
                              "BlogPet 飼育箱" ) )
                    break;
            }
        }
        else {
            for ( i = 0; i < m_numOfBlogKinds; i++ ) {
                if ( cp->m_blogList[m_currentBlogID].blogKind == 
                                                m_blogKindInfo[i].blogKind )
                    break;
            }
        }

        if ( (i >= 0) && (i < m_numOfBlogKinds) )
            m_blogKindList.SetCurSel( i );
    }

    if ( m_categoryName.GetLength() > 0 ) {
        CString str;
        for ( int i = 0; i < m_categoryList.GetCount(); i++ ) {
            m_categoryList.GetText( i, str );
            if ( !strcmp( m_categoryName, (const char *)str ) ) {
                m_categoryList.SetCurSel( i );
                break;
            }
        }
    }
}

void    CCarotDlg::switchBrowseBlog()
{
    CButton *p = (CButton *)GetDlgItem( IDC_BUTTON_BROWSE_BLOG );

    if ( m_blogURL.GetLength() > 0 )
        p->SetWindowText( "blog を見る" );
    else
        p->SetWindowText( "blog情報取得" );

    p->EnableWindow( TRUE );
}

void    CCarotDlg::switchBrowseBlogPet()
{
    CButton *p = (CButton *)GetDlgItem( IDC_BUTTON_BROWSE_BLOGPET );

    if ( m_blogPetID.GetLength() > 0 )
        p->SetWindowText( "BlogPet のプロフィールページを見る" );
    else
        p->SetWindowText( "  BlogPet ID を取得" );

    p->EnableWindow( TRUE );
}

void    CCarotDlg::initBlogKindList()
{
    int cnt = 0;

    m_numOfBlogKinds = 0;

    // #0
    m_blogKindInfo[cnt].blogKind       = typepad;
    m_blogKindInfo[cnt].blogKindString = "TypePad(, France, Germany)";
    m_blogKindInfo[cnt].blogKindID     = "typepad";
    m_blogKindInfo[cnt].endpointURL    = APIURL_TYPEPAD;
    cnt++;

    // #1
    m_blogKindInfo[cnt].blogKind       = typepadJapan;
    m_blogKindInfo[cnt].blogKindString = "TypePad Japan";
    m_blogKindInfo[cnt].blogKindID     = "typepadJapan";
    m_blogKindInfo[cnt].endpointURL    = APIURL_TYPEPADJAPAN;
    cnt++;

    // #2
    m_blogKindInfo[cnt].blogKind       = cocolog;
    m_blogKindInfo[cnt].blogKindString = "ココログ";
    m_blogKindInfo[cnt].blogKindID     = "cocolog";
    m_blogKindInfo[cnt].endpointURL    = APIURL_COCOLOG;
    cnt++;

    // #3
    m_blogKindInfo[cnt].blogKind       = cocologFree;
    m_blogKindInfo[cnt].blogKindString = "ココログフリー";
    m_blogKindInfo[cnt].blogKindID     = "cocologFree";
    m_blogKindInfo[cnt].endpointURL    = APIURL_COCOLOGFREE;
    cnt++;

    // #4
    m_blogKindInfo[cnt].blogKind       = blogzine;
    m_blogKindInfo[cnt].blogKindString = "ブログ人";
    m_blogKindInfo[cnt].blogKindID     = "blogzine";
    m_blogKindInfo[cnt].endpointURL    = APIURL_BLOGZINE;
    cnt++;

    // #5
    m_blogKindInfo[cnt].blogKind       = newsHandler;
    m_blogKindInfo[cnt].blogKindString = "News-Handler";
    m_blogKindInfo[cnt].blogKindID     = "newsHandler";
    m_blogKindInfo[cnt].endpointURL    = APIURL_NEWSHANDLER;
    cnt++;

    // #6
    m_blogKindInfo[cnt].blogKind       = seesaa;
    m_blogKindInfo[cnt].blogKindString = "Seesaa BLOG";
    m_blogKindInfo[cnt].blogKindID     = "seesaa";
    m_blogKindInfo[cnt].endpointURL    = APIURL_SEESAABLOG_SEC;
    cnt++;

    // #7
    m_blogKindInfo[cnt].blogKind       = netLaputa;
    m_blogKindInfo[cnt].blogKindString = "NetLaputa BLOG";
    m_blogKindInfo[cnt].blogKindID     = "netLaputa";
    m_blogKindInfo[cnt].endpointURL    = APIURL_NETLAPUTA;
    cnt++;

    // #8
    m_blogKindInfo[cnt].blogKind       = blogG;
    m_blogKindInfo[cnt].blogKindString = "269g";
    m_blogKindInfo[cnt].blogKindID     = "blogG";
    m_blogKindInfo[cnt].endpointURL    = APIURL_269G;
    cnt++;

    // #9
    m_blogKindInfo[cnt].blogKind       = livedoor;
    m_blogKindInfo[cnt].blogKindString = "livedoor Blog";
    m_blogKindInfo[cnt].blogKindID     = "livedoor";
    m_blogKindInfo[cnt].endpointURL    = ATOMURL_LIVEDOOR_200507;
    cnt++;

    // #10
    m_blogKindInfo[cnt].blogKind       = lovelog;
    m_blogKindInfo[cnt].blogKindString = "LOVELOG";
    m_blogKindInfo[cnt].blogKindID     = "lovelog";
    m_blogKindInfo[cnt].endpointURL    = ATOMURL_LOVELOG;
    cnt++;

    // #11
    m_blogKindInfo[cnt].blogKind       = sonet;
    m_blogKindInfo[cnt].blogKindString = "So-net blog";
    m_blogKindInfo[cnt].blogKindID     = "sonet";
    m_blogKindInfo[cnt].endpointURL    = ATOMURL_SONET;
    cnt++;

    // #12
    m_blogKindInfo[cnt].blogKind       = blogger;
    m_blogKindInfo[cnt].blogKindString = "Blogger";
    m_blogKindInfo[cnt].blogKindID     = "blogger";
    m_blogKindInfo[cnt].endpointURL    = ATOMURL_BLOGGER;
    cnt++;

    // #13
    m_blogKindInfo[cnt].blogKind       = vox;
    m_blogKindInfo[cnt].blogKindString = "Vox";
    m_blogKindInfo[cnt].blogKindID     = "vox";
    m_blogKindInfo[cnt].endpointURL    = ATOMURL_VOX;
    cnt++;

    // #14
    m_blogKindInfo[cnt].blogKind       = movableType;
    m_blogKindInfo[cnt].blogKindString = "Movable Type";
    m_blogKindInfo[cnt].blogKindID     = "movableType";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #15
    m_blogKindInfo[cnt].blogKind       = bloggerAPI;
    m_blogKindInfo[cnt].blogKindString = "blogger API サポート";
    m_blogKindInfo[cnt].blogKindID     = "bloggerAPI";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #16
    m_blogKindInfo[cnt].blogKind       = metaWeblog;
    m_blogKindInfo[cnt].blogKindString = "metaWeblog API サポート";
    m_blogKindInfo[cnt].blogKindID     = "metaWeblog";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #17
    m_blogKindInfo[cnt].blogKind       = mtAPI;
    m_blogKindInfo[cnt].blogKindString = "MovableType API サポート";
    m_blogKindInfo[cnt].blogKindID     = "mtAPI";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #18
    m_blogKindInfo[cnt].blogKind       = atomAPI;
    m_blogKindInfo[cnt].blogKindString = "Atom API サポート blog";
    m_blogKindInfo[cnt].blogKindID     = "atomAPI";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #19
    m_blogKindInfo[cnt].blogKind       = newPostOnly;
    m_blogKindInfo[cnt].blogKindString = "metaWeblog.newPost のみサポート";
    m_blogKindInfo[cnt].blogKindID     = "newPostOnly";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #20
    m_blogKindInfo[cnt].blogKind       = newPostOnly;
    m_blogKindInfo[cnt].blogKindString = "BlogPet 飼育箱";
    m_blogKindInfo[cnt].blogKindID     = "newPostOnly";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #21
    m_blogKindInfo[cnt].blogKind       = jugemX;
    m_blogKindInfo[cnt].blogKindString = "JUGEM";
    m_blogKindInfo[cnt].blogKindID     = "jugemX";
    m_blogKindInfo[cnt].endpointURL    = APIURL_JUGEM_X;
    cnt++;

    // #22
    m_blogKindInfo[cnt].blogKind       = exciteBlog;
    m_blogKindInfo[cnt].blogKindString = "exciteブログ";
    m_blogKindInfo[cnt].blogKindID     = "exciteBlog";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #23
    m_blogKindInfo[cnt].blogKind       = yaplogX;
    m_blogKindInfo[cnt].blogKindString = "ヤプログ!";
    m_blogKindInfo[cnt].blogKindID     = "yaplogX";
    m_blogKindInfo[cnt].endpointURL    = APIURL_YAPLOG_X;
    cnt++;

    // #24
    m_blogKindInfo[cnt].blogKind       = drecomX;
    m_blogKindInfo[cnt].blogKindString = "ドリコムブログ";
    m_blogKindInfo[cnt].blogKindID     = "drecomX";
    m_blogKindInfo[cnt].endpointURL    = APIURL_DRECOMBLOG_X;
    cnt++;

    // #25
    m_blogKindInfo[cnt].blogKind       = mixi;
    m_blogKindInfo[cnt].blogKindString = "mixi内日記";
    m_blogKindInfo[cnt].blogKindID     = "mixi";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #26
    m_blogKindInfo[cnt].blogKind       = kinugasa;
    m_blogKindInfo[cnt].blogKindString = "キヌガサ内日記";
    m_blogKindInfo[cnt].blogKindID     = "kinugasa";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #27
    m_blogKindInfo[cnt].blogKind       = ameblo;
    m_blogKindInfo[cnt].blogKindString = "アメーバブログ";
    m_blogKindInfo[cnt].blogKindID     = "ameblo";
    m_blogKindInfo[cnt].endpointURL    = ATOMURL_AMEBLO;
    cnt++;

    // #28
    m_blogKindInfo[cnt].blogKind       = echoo;
    m_blogKindInfo[cnt].blogKindString = "エコログ";
    m_blogKindInfo[cnt].blogKindID     = "echoo";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #29
    m_blogKindInfo[cnt].blogKind       = webryX;
    m_blogKindInfo[cnt].blogKindString = "ウェブリブログ (XML-RPC API)";
    m_blogKindInfo[cnt].blogKindID     = "webryX";
    m_blogKindInfo[cnt].endpointURL    = APIURL_WEBRY_X;
    cnt++;

    // #30
    m_blogKindInfo[cnt].blogKind       = rakuten;
    m_blogKindInfo[cnt].blogKindString = "楽天ブログ";
    m_blogKindInfo[cnt].blogKindID     = "rakuten";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #31
    m_blogKindInfo[cnt].blogKind       = fc2blog;
    m_blogKindInfo[cnt].blogKindString = "FC2BLOG";
    m_blogKindInfo[cnt].blogKindID     = "fc2blog";
    m_blogKindInfo[cnt].endpointURL    = APIURL_FC2BLOG;
    cnt++;

    // #32
    m_blogKindInfo[cnt].blogKind       = fc2network;
    m_blogKindInfo[cnt].blogKindString = "FC2NETWORK内日記";
    m_blogKindInfo[cnt].blogKindID     = "fc2network";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #33
    m_blogKindInfo[cnt].blogKind       = gooBlog;
    m_blogKindInfo[cnt].blogKindString = "goo Blog";
    m_blogKindInfo[cnt].blogKindID     = "gooBlog";
    m_blogKindInfo[cnt].endpointURL    = APIURL_GOOBLOG;
    cnt++;

    // #34
    m_blogKindInfo[cnt].blogKind       = msnSpaces;
    m_blogKindInfo[cnt].blogKindString = "Windows Live Spaces";
    m_blogKindInfo[cnt].blogKindID     = "msnSpaces";
    m_blogKindInfo[cnt].endpointURL    = APIURL_MSNSPACES;
    cnt++;

    // #35
    m_blogKindInfo[cnt].blogKind       = colors;
    m_blogKindInfo[cnt].blogKindString = "COLORS内日記";
    m_blogKindInfo[cnt].blogKindID     = "colors";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #36
    m_blogKindInfo[cnt].blogKind       = openPne;
    m_blogKindInfo[cnt].blogKindString = "OpenPNE内日記";
    m_blogKindInfo[cnt].blogKindID     = "openPne";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    // #37
    m_blogKindInfo[cnt].blogKind       = hatena;
    m_blogKindInfo[cnt].blogKindString = "はてなダイアリー";
    m_blogKindInfo[cnt].blogKindID     = "hatena";
    m_blogKindInfo[cnt].endpointURL    = ATOMURL_HATENADIARY;
    cnt++;

    // #38
    m_blogKindInfo[cnt].blogKind       = unsupported;
    m_blogKindInfo[cnt].blogKindString = "その他";
    m_blogKindInfo[cnt].blogKindID     = "unsupported";
    m_blogKindInfo[cnt].endpointURL    = "";
    cnt++;

    m_numOfBlogKinds = cnt;

    m_blogKindList.ResetContent();
    for ( int i = 0; i < cnt; i++ )
        m_blogKindList.AddString( m_blogKindInfo[i].blogKindString );
}


bool    CCarotDlg::getStringValue(
                const char *inputString,
                const char *targetName,
                char       *stringValue
            )
{
    bool        ret = false;
    const char  *p = inputString, *q;
    int         len;

    len = targetName && *targetName ? strlen( targetName ) : 0;

    if ( (len > 0) && !strncmp( p, targetName, len ) ) {
        p += len;
        while ( (*p == ' ') || (*p == '\t') )
            p++;
        q = p + (strlen( p ) - 1);
        while ( (*q == ' ') || (*q == '\t') || (*q == '\r') || (*q == '\n') )
            q--;
        q++;
        strncpy( stringValue, p, q - p );
        stringValue[q - p] = '\0';

        ret = true;
    }

    return ( ret );
}

bool    CCarotDlg::getStringValue(
                const char *inputString,
                const char *paramName,
                CString    &param,
                int        idc,
                int        paramAreaSize /* = MAX_NAMELEN */
            )
{
    bool    ret = false;
    CString targetName;
    char    *name = new char [paramAreaSize + 1];

    targetName = paramName;
    targetName += ":";

    memset( name, 0x00, paramAreaSize + 1 );
    if ( getStringValue( inputString, targetName, name ) ) {
        CEdit   *cp = (CEdit *)GetDlgItem( idc );

        cp->SetWindowText( name );
        param = name;

        ret = true;
    }

    delete [] name;

    return ( ret );
}

bool    CCarotDlg::getStringValue(
            const char      *inputString,
            const char      *targetName,
            int             &blogIndex )
{
    bool    ret = false;
    char    name[MAX_NAMELEN + 1];

    memset( name, 0x00, MAX_NAMELEN + 1 );
    if ( getStringValue( inputString, targetName, name ) ) {
        int i;
        for ( i = 0; i < m_numOfBlogKinds; i++ ) {
            if ( !strcmp( name, m_blogKindInfo[i].blogKindID ) )
                break;
        }

        m_blogKind = m_blogKindInfo[i].blogKind;
        m_blogKindList.SetCurSel( i );
        blogIndex = i;

        ret = true;
    }

    return ( ret );
}

void    CCarotDlg::decodeParameter(
            CString             &param,          // 設定先
            const unsigned char *encryptedString,// 設定すべき内容(要・復号)
            const unsigned char *rsaString )     // RSA鍵対応文字列
{
    char            *p;
    char            *decodedString;         // 復号結果格納領域へのポインタ
    unsigned char   targetString[BUFSIZ];   // 復号対象バイト列
    int             len;                    // 復号結果(文字列)の長さ
    size_t          sz = 0;

    memset( targetString, 0x00, BUFSIZ );
    p = unbase64( encryptedString, targetString, &sz );
    if ( p && *p ) {
        len = decodeByRSA( &decodedString, rsaString,
                           (unsigned char *)targetString,
                           strlen( (char *)targetString ) );
        if ( len >= 0 ) {
            param = decodedString;
            freeRSAbuffer( decodedString );
        }
    }
}

void    CCarotDlg::encodeParameter(
            FILE          *fp,
            FILE          *gp,
            const char    *param,
            const char    *paramName,
            char          *key,
            unsigned char **rsaString,
            bool          &encrypted )
{
    int           len;
    unsigned char *cryptedString = NULL;

    len = encodeByRSA( param, rsaString, &cryptedString );
    if ( len > 0 ) {
        encrypted = true;
        if ( !(key[0]) )
            strcpy( key, base64(*rsaString, strlen((char *)*rsaString)) );
        if ( fp )
            fprintf( fp, "%sEncrypted: %s\n",
                     paramName,
                     base64( cryptedString, len ) );
        if ( gp )
            fprintf( gp, "%sEncrypted: %s\n",
                     paramName,
                     base64( cryptedString, len ) );
        freeRSAbuffer( (char *)cryptedString );
    }
    else {
        if ( fp )
            fprintf( fp, "%s: %s\n", paramName, param );
    }
}


void    CCarotDlg::loadSetting()
{
    struct stat s;

    m_cousagiUserName = "";
    m_cousagiPassword = "";
    m_blogUserName    = "";
    m_blogPassword    = "";
    m_blogName        = "";
    m_cousagiName     = "";
    m_userName        = "";
    m_blogPetID       = "";
    m_endpointURL     = "";
    m_blogID          = "";
    m_blogURL         = "";
    m_associateID     = "";
    m_categoryName    = "";
    m_blogPetType     = "blogPet";
    m_editorPath[0]   = NUL;

    if ( !stat( m_settingDir, &s ) &&
         ((s.st_mode & _S_IFDIR ) == _S_IFDIR) ) {
        // 設定ファイル格納用フォルダが存在する場合
        char    filename[MAX_PATH];
        sprintf( filename, "%s/%s", m_settingDir, m_settingFile );

        FILE    *fp = fopen( filename, "r" );
        if ( fp != NULL ) {
            // 設定ファイルが存在すれば
            //   設定ファイルを読み取る
            loadSetting( fp );
            fclose( fp );

            sprintf( filename, "%s/%s", m_settingDir, m_petInfoFile );
            if ( ( fp = fopen( filename, "r" ) ) != NULL ) {
                // BlogPet情報ファイルが存在すれば
                //   BlogPet情報ファイルを読み取る
                loadBlogPetInfo( fp );
                fclose( fp );
            }
            else {
                // BlogPet情報ファイルが存在しなければ
                //   設定ファイルを元にBlogPet情報ファイルを生成する
                createBlogPetInfo();
                saveSetting();
            }

            sprintf( filename, "%s/%s", m_settingDir, m_blogInfoFile );
            if ( ( fp = fopen( filename, "r" ) ) != NULL ) {
                // blog 情報ファイルが存在すれば
                //   blog 情報ファイルを読み取る
                loadBlogInfo( fp );
                fclose( fp );
            }
            else {
                // blog 情報ファイルが存在しなければ
                //   設定ファイルを元に blog 情報ファイルを生成する
                createBlogInfo();
                saveSetting();
            }
        }
        else {
            // 何も存在しない状態からBlogPet情報ファイルを生成する
            if ( createBlogPet() == false )
                return;

            // 何も存在しない状態から blog 情報ファイルを生成する
            if ( createBlogList() == false )
                return;
        }

        // 「BlogPet 切替」ボタンを enable にする
        CButton *q = (CButton *)GetDlgItem( IDC_BUTTON_SWITCH_PET );
        q->EnableWindow( TRUE );

        //   「blog 切替」ボタンを enable にする
        q = (CButton *)GetDlgItem( IDC_BUTTON_SWITCH_BLOG );
        q->EnableWindow( TRUE );
    }
    else {
        // 設定ファイル格納用フォルダが存在しない場合
        //   設定ファイル格納用フォルダを作成する
        mkdir( m_settingDir );

        // 何も存在しない状態からBlogPet情報ファイルを生成する
        if ( createBlogPet() == false )
            return;

        //   「BlogPet 切替」ボタンを enable にする
        CButton *q = (CButton *)GetDlgItem( IDC_BUTTON_SWITCH_PET );
        q->EnableWindow( TRUE );

        // 何も存在しない状態から blog 情報ファイルを生成する
        if ( createBlogList() == false )
            return;

        //   「blog 切替」ボタンを enable にする
        q = (CButton *)GetDlgItem( IDC_BUTTON_SWITCH_BLOG );
        q->EnableWindow( TRUE );
    }
}

void    CCarotDlg::loadSetting( FILE *fp )
{
    // 設定ファイルを読み取る
    char        buf[BUFSIZ];
    char        *p;
    int         blogIndex = 0;
    bool        useCbox   = false;
    bool        encrypted = false;
    char        cousagiPasswordEncrypted[MAX_PASSWDLEN * 16];
    char        blogPasswordEncrypted[MAX_PASSWDLEN * 16];
    char        key[BUFSIZ];
    char        tmp[BUFSIZ];
    CCarotApp   *pp = (CCarotApp *)AfxGetApp();

    m_cousagiUserName = "";
    m_cousagiPassword = "";
    m_blogUserName    = "";
    m_blogPassword    = "";
    m_blogName        = "";
    m_cousagiName     = "";
    m_userName        = "";
    m_blogPetID       = "";
    m_endpointURL     = "";
    m_blogID          = "";
    m_blogURL         = "";
    m_associateID     = "";
    m_categoryName    = "";
    m_blogPetType     = "blogPet";
    m_editorPath[0]   = NUL;
    cousagiPasswordEncrypted[0] = NUL;
    blogPasswordEncrypted[0]    = NUL;
    key[0]                      = NUL;

    while ( ( p = fgets( buf, BUFSIZ - 1, fp ) ) != NULL ) {
        if ( !strncmp(p, CAROT_INF_EOF_STRING, strlen(CAROT_INF_EOF_STRING)) )
            break;

        if ( getStringValue( p, "cousagiUserName",
                             m_cousagiUserName, IDC_EDIT_COUSAGI_USERNAME ) )
            continue;   // BlogPetサーバ login ID

        if ( getStringValue( p, "cousagiPassword",
                             m_cousagiPassword, IDC_EDIT_COUSAGI_PASSWORD ) )
            continue;   // BlogPetサーバ login パスワード

        if ( getStringValue( p, "blogName",
                             m_blogName, IDC_EDIT_BLOG_NAME,
                             MAX_BLOGNAMELENGTH ) )
            continue;   // ブログ名

        if ( getStringValue( p, "blogUserName",
                             m_blogUserName, IDC_EDIT_BLOG_USERNAME ) )
            continue;   // ブログ login ID

        if ( getStringValue( p, "blogPassword",
                             m_blogPassword, IDC_EDIT_BLOG_PASSWORD ) )
            continue;   // ブログ login パスワード

        if ( getStringValue( p, "cousagiName",
                             m_cousagiName, IDC_EDIT_COUSAGI_NAME ) )
            continue;   // BlogPetの名前

        if ( getStringValue( p, "userNickName",
                             m_userName, IDC_EDIT_USER_NAME ) )
            continue;   // 飼い主のニックネーム

        if ( getStringValue( p, "blogPetID",
                             m_blogPetID, IDC_EDIT_BLOGPET_ID ) )
            continue;   // BlogPet の ID

        if ( getStringValue( p, "endpointURL",
                             m_endpointURL, IDC_EDIT_ENDPOINT_URL,
                             MAX_URLLENGTH ) )
            continue;   // エンドポイント URL

        if ( getStringValue( p, "blogID",
                             m_blogID, IDC_EDIT_BLOG_ID,
                             MAX_BLOGIDLENGTH ) )
            continue;   // blog ID

        if ( getStringValue( p, "blogURL",
                             m_blogURL, IDC_EDIT_BLOG_URL,
                             MAX_URLLENGTH ) )
            continue;   // blog のトップページの URL

        if ( !strncmp( p, "keywordLink:", 12 ) ) {
            if ( strstr( p + 12, "on" ) != NULL )
                switchKeyword( true );
            else
                switchKeyword( false );
            continue;
        }

        if ( !strncmp( p, "haiku:", 6 ) ) {
            if ( strstr( p + 6, "on" ) != NULL )
                switchHaiku( true );
            else
                switchHaiku( false );
            continue;
        }

        if ( !strncmp( p, "similarity:", 11 ) ) {
            if ( strstr( p + 11, "on" ) != NULL )
                switchSimilarity( true );
            else
                switchSimilarity( false );
            continue;
        }

        if ( !strncmp( p, "postForcely:", 12 ) ) {
            if ( strstr( p + 12, "on" ) != NULL )
                switchPostForcely( true );
            else
                switchPostForcely( false );
            continue;
        }

        if ( !strncmp( p, "useWriting:", 11 ) ) {
            if ( strstr( p + 11, "on" ) != NULL )
                switchUseWriting( true );
            else
                switchUseWriting( false );
            continue;
        }

#if 0   // 将来対応
        if ( getStringValue( p, "editorPath",
                             m_editorPath,
                             IDC_EDIT_EDITOR_PATH,
                             MAX_PATH ) )
            continue;   // 代筆記事編集用エディタのパス名
#endif

        if ( getStringValue( p, "associateID",
                             m_associateID,
                             IDC_EDIT_ASSOCIATE_ID,
                             MAX_NAMELEN ) )
            continue;   // Amazon アソシエイト ID

        if ( getStringValue( p, "blogPetType",
                             m_blogPetType, IDC_COMBO_BLOGPETTYPE ) ) {
            int idx = BPTYPE_UNKNOWN;

            if ( m_blogPetType.Compare( "usagi" ) == 0 )
                idx = BPTYPE_COUSAGI;
            else if ( m_blogPetType.Compare( "neko" ) == 0 )
                idx = BPTYPE_CONEKO;
            else if ( m_blogPetType.Compare( "inu" ) == 0 )
                idx = BPTYPE_COINU;
            else if ( m_blogPetType.Compare( "panda" ) == 0 )
                idx = BPTYPE_COPANDA;
            else if ( m_blogPetType.Compare( "nezumi" ) == 0 )
                idx = BPTYPE_CONEZUMI;
            else
                m_blogPetType = "blogPet";
            m_blogPetTypeList.SetCurSel( idx );
            continue;   // BlogPet 種別
        }

        if ( getStringValue( p, "blogType:", blogIndex ) )
            continue;   // blog種別

        if ( !strncmp( p, "cbox:", 5 ) ) {
            useCbox = true;
            continue;
        }

        if ( getStringValue( p, "cousagiPasswordEncrypted:",
                             cousagiPasswordEncrypted ) ) {
            encrypted = true;
            continue;
        }
        if ( getStringValue( p, "blogPasswordEncrypted:",
                             blogPasswordEncrypted ) ) {
            encrypted = true;
            continue;
        }
        if ( getStringValue( p, "encryptedKey:", key ) ) { /* {@@} */
            encrypted = true;
            continue;
        }

        if ( getStringValue( p, "proxyType:", tmp ) ) {
            if ( !strcmp( tmp, "notUsed" ) ) {
                pp->m_proxyType = CCarotApp::notUsed;
                pp->m_useProxy  = false;
            }
            else if ( !strcmp( tmp, "specialSetting" ) )
                pp->m_proxyType = CCarotApp::specialSetting;
            else if ( !strcmp( tmp, "manualSetting" ) )
                pp->m_proxyType = CCarotApp::manualSetting;
            else
                pp->m_proxyType = CCarotApp::autoDetect;
            continue;
        }

        if ( (pp->m_proxyType == CCarotApp::specialSetting) ||
             (pp->m_proxyType == CCarotApp::manualSetting)     ) {
            if ( !strncmp( p, "useProxy:", 9 ) ) {
                if ( strstr( p + 9, "on" ) != NULL )
                    pp->m_useProxy = true;
                else
                    pp->m_useProxy = false;
                continue;
            }
            if ( getStringValue( p, "proxyServer:", tmp ) ) {
                pp->m_proxyServerName = tmp;
                continue;
            }
            if ( getStringValue( p, "proxyPort:", tmp ) ) {
                pp->m_proxyPortNumber = atol( tmp );
                continue;
            }
            if ( getStringValue( p, "proxyUsername:", tmp ) ) {
                pp->m_proxyUserName = tmp;
                continue;
            }
            if ( getStringValue( p, "proxyPassword:", tmp ) ) {
                pp->m_proxyPassword = tmp;
                continue;
            }
        }
    }

    if ( encrypted && key[0] ) {
        /* 暗号化されているパスワードを復号する */
        char            *p;
        unsigned char   rsaString[BUFSIZ];
        size_t          sz = 0;

        memset( rsaString, 0x00, BUFSIZ );
        p = unbase64( (unsigned char *)key, (unsigned char *)rsaString, &sz );
        if ( p ) {
            if ( cousagiPasswordEncrypted[0] )
                decodeParameter( m_cousagiPassword,
                                 (unsigned char *)cousagiPasswordEncrypted,
                                 (unsigned char *)rsaString );
            if ( blogPasswordEncrypted[0] )
                decodeParameter( m_blogPassword,
                                 (unsigned char *)blogPasswordEncrypted,
                                 (unsigned char *)rsaString );
        }
    }

    // 必要に応じて、エンドポイントURL欄を enable にする
    switchEndpointURL( blogIndex );

    // 必要に応じて、blog ID 欄を enable にする
    switchBlogID( m_blogID );

    // 必要に応じて、「blog を見るボタン」を enable にする
    switchBrowseBlog();
    switchBrowseBlogPet();

    if ( (m_blogKind == newPostOnly) && (useCbox == true) ) {
        // 「BlogPet 飼育箱」のための特別処理
        int i;
        for ( i = 0; i < m_numOfBlogKinds; i++ ) {
            if ( !strcmp( m_blogKindInfo[i].blogKindString, "BlogPet 飼育箱" ) )
                break;
        }

     // m_blogKind = m_blogKindInfo[i].blogKind;
        m_blogKindList.SetCurSel( i );
    }
}

void    CCarotDlg::saveSetting( bool savedForcely /* = false */)
{
    if ( m_blogKind == unset )
        return;

    mkdir( m_settingDir );

    char    filename[MAX_PATH];
    sprintf( filename, "%s/%s", m_settingDir, m_settingFile );

    FILE    *fp = fopen( filename, "w+" );
    if ( fp ) {             /* ↑ w+ とすることで rewind() 可能とする */
        saveSetting( fp, savedForcely );
        fclose( fp );

        /* blog別設定ファイル保存 */
        int i;
        for ( i = 0; i < m_numOfBlogKinds; i++ ) {
            if ( m_blogKind == m_blogKindInfo[i].blogKind )
                break;
        }
        if ( i < m_numOfBlogKinds ) {
            sprintf( filename, "%s/%s.inf",
                     m_settingDir, m_blogKindInfo[i].blogKindID );
            if ( m_blogKind == newPostOnly ) {
                // 「BlogPet 飼育箱」のための特別処理
                CString     blogKindString;
                int         location = m_blogKindList.GetCurSel();

	            m_blogKindList.GetLBText( location, blogKindString );
                if ( blogKindString.Compare( "BlogPet 飼育箱" ) == 0 )
                    sprintf( filename, "%s/%s.inf",
                             m_settingDir, "cbox" );
            }

            fp = fopen( filename, "w+" );
            if ( fp ) {     /* ↑ w+ とすることで rewind() 可能とする */
                saveSetting( fp, savedForcely );
                fclose( fp );
            }
        }
    }
}

void    CCarotDlg::saveSetting( FILE *fp, bool savedForcely )
{
    bool            done = false;
    bool            encrypted;
    char            key[BUFSIZ];
    unsigned char   *rsaString;
    FILE            *gp;
    int             retryCount = 0;
    char            fileForCheck[MAX_PATH];
    CCarotApp       *pp = (CCarotApp *)AfxGetApp();

    sprintf( fileForCheck, "%s/chk%08dCD",
             m_settingDir, time( NULL ) % 10000000 );
    do {
        key[0]    = NUL;
        rsaString = NULL;
        encrypted = false;
        gp = fopen( fileForCheck, "w" );
        if ( gp )
            fprintf( gp, "numOfBlogPasswords: %d\n", 2 );

        if ( savedForcely ) {
            // パラメータ確定
            getParameter( savedForcely );
        }

        // 設定ファイルを書き出す
        int i;
        for ( i = 0; i < m_numOfBlogKinds; i++ ) {
            if ( m_blogKind == m_blogKindInfo[i].blogKind )
                break;
        }
        if ( i < m_numOfBlogKinds )
            fprintf( fp, "blogType:        %s\n",
                     m_blogKindInfo[i].blogKindID );

        if ( m_cousagiUserName.GetLength() > 0 )
            fprintf( fp, "cousagiUserName: %s\n",
                     (const char *)m_cousagiUserName );

        if ( m_cousagiPassword.GetLength() > 0 )
            encodeParameter( fp, gp,
                             (const char *)m_cousagiPassword,
                             "cousagiPassword",
                             key, &rsaString, encrypted );
        else {
            // checkBlogInfo() が無限に false を返すのを防止するため
            // ダミーのパスワードを設定
            encodeParameter( NULL, gp, /* gp にのみ write */
                             "dummy",
                             "cousagiPassword",
                             key, &rsaString, encrypted );
        }

        if ( m_blogName.GetLength() > 0 )
            fprintf( fp, "blogName:   %s\n",
                     (const char *)m_blogName );

        if ( m_blogUserName.GetLength() > 0 )
            fprintf( fp, "blogUserName:    %s\n",
                     (const char *)m_blogUserName );

        if ( m_blogPassword.GetLength() > 0 )
            encodeParameter( fp, gp,
                             (const char *)m_blogPassword,
                             "blogPassword",
                             key, &rsaString, encrypted );
        else {
            // checkBlogInfo() が無限に false を返すのを防止するため
            // ダミーのパスワードを設定
            encodeParameter( NULL, gp, /* gp にのみ write */
                             "dummy",
                             "blogPassword",
                             key, &rsaString, encrypted );
        }

        if ( m_cousagiName.GetLength() > 0 )
            fprintf( fp, "cousagiName:     %s\n",
                     (const char *)m_cousagiName );

        if ( m_userName.GetLength() > 0 )
            fprintf( fp, "userNickName:    %s\n",
                     (const char *)m_userName );

        if ( m_blogPetID.GetLength() > 0 )
            fprintf( fp, "blogPetID:       %s\n",
                     (const char *)m_blogPetID );

        if ( m_blogPetType.GetLength() > 0 )
            fprintf( fp, "blogPetType:     %s\n",
                     (const char *)m_blogPetType );

        if ( (m_blogKind == movableType) ||
             (m_blogKind == bloggerAPI)  ||
             (m_blogKind == metaWeblog)  ||
             (m_blogKind == mtAPI)       ||
             (m_blogKind == atomAPI)     ||
             (m_blogKind == newPostOnly)    ) {
            if ( m_endpointURL.GetLength() > 0 )
                fprintf( fp, "endpointURL:     %s\n",
                         (const char *)m_endpointURL );
        }

        if ( m_blogID.GetLength() > 0 )
            fprintf( fp, "blogID:          %s\n", m_blogID );
        if ( m_blogURL.GetLength() > 0 )
            fprintf( fp, "blogURL:         %s\n", m_blogURL );

        fprintf( fp, "keywordLink:     %s\n",
                 m_keyword  == true         ? "on" : "off" );
        fprintf( fp, "haiku:           %s\n",
                 m_haiku == true            ? "on" : "off" );
        fprintf( fp, "similarity:      %s\n",
                 m_similarity == true       ? "on" : "off" );
        fprintf( fp, "postForcely:     %s\n",
                 m_postForcely == TRUE      ? "on" : "off" );
        fprintf( fp, "useWriting:      %s\n",
                 m_useWritingForPet == TRUE ? "on" : "off" );

        if ( m_editorPath[0] != NUL )
            fprintf( fp, "editorPath:      %s\n", m_editorPath );

        if ( m_associateID.GetLength() > 0 )
            fprintf( fp, "associateID:     %s\n",
                     (const char *)m_associateID );

        if ( m_blogKind == newPostOnly ) {
            // 「BlogPet 飼育箱」のための特別処理
            CString     blogKindString;
            int         location = m_blogKindList.GetCurSel();

	        m_blogKindList.GetLBText( location, blogKindString );
            if ( blogKindString.Compare( "BlogPet 飼育箱" ) == 0 )
                fprintf( fp, "cbox:            alive\n" );
        }

        if ( m_categoryName.GetLength() > 0 )
            fprintf( fp, "categoryName:    %s\n",
                     (const char *)m_categoryName );

        if ( (pp->m_proxyType == CCarotApp::specialSetting) ||
             (pp->m_proxyType == CCarotApp::manualSetting)     ) {
            fprintf( fp, "proxyType: %s\n",
                      pp->m_proxyType == CCarotApp::specialSetting
                        ? "specialSetting"
                        : "manualSetting" );
            fprintf( fp, "useProxy: %s\n", pp->m_useProxy ? "on" : "off" );
            if ( pp->m_useProxy ) {
                fprintf( fp, "proxyServer: %s\n", pp->m_proxyServerName );
                fprintf( fp, "proxyPort:   %d\n", pp->m_proxyPortNumber );

                if ( pp->m_proxyUserName.GetLength() > 0 ) {
                    fprintf( fp, "proxyUsername: %s\n", pp->m_proxyUserName );
                    if ( pp->m_proxyPassword.GetLength() > 0 )
                        fprintf( fp, "proxyPassword: %s\n",
                                 pp->m_proxyPassword );
                }
            }
        }
        else if ( pp->m_proxyType == CCarotApp::notUsed )
            fprintf( fp, "proxyType: %s\n", "notUsed" );
        else
            fprintf( fp, "proxyType: %s\n", "autoDetect" );

        if ( encrypted && key[0] ) {
            fprintf( fp, "encryptedKey: %s\n", key );
            if ( gp )
                fprintf( gp, "encryptedKey: %s\n", key );
            freeRSAkey( rsaString );
        }
        fprintf( fp, "%s\n", CAROT_INF_EOF_STRING );

        if ( gp ) {
            fclose( gp );
            gp = NULL;
        }

        if ( encrypted && key[0] ) {
            done = checkSetting( fileForCheck );
            if ( done == false )
                rewind( fp );
        }
        else
            done = true;

        if ( done == false ) {
            retryCount++;
            if ( retryCount >= 27 )
                break;
        }
    } while ( done == false );

    unlink( fileForCheck );
}


bool    CCarotDlg::createBlogPet()
{
    // BlogPet 情報格納領域を確保
    if ( allocateBlogPetInfo() == false )
        return ( false );   // 確保失敗

    // BlogPet 登録画面を表示
    OnButtonSwitchPet();
    return ( true );
}


void    CCarotDlg::createBlogPetInfo()
{
    // 「設定ファイル」群を元に「Blog Pet 情報ファイル」を生成
    FILE    *fp, *gp;
    char    filename[MAX_PATH];

    sprintf( filename, "%s/%s", m_settingDir, m_petInfoFile );
    if ( ( gp = fopen( filename, "w+" ) ) == NULL )
        return;                 /* ↑ w+ とすることで rewind() 可能とする */

    sprintf( filename, "%s/%s", m_settingDir, m_settingFile );
    if ( ( fp = fopen( filename, "r" ) ) != NULL ) {
        registerBlogPetInfoFromFile( fp );
        fclose( fp );
    }

    for ( int i = 0; i < m_numOfBlogKinds; i++ ) {
        sprintf( filename, "%s/%s.inf",
                 m_settingDir, m_blogKindInfo[i].blogKindID );
        if ( ( fp = fopen( filename, "r" ) ) != NULL ) {
            registerBlogPetInfoFromFile( fp );
            fclose( fp );
        }
    }

    sprintf( filename, "%s/%s.inf", m_settingDir, "cbox" ); // BlogPet飼育箱
    if ( ( fp = fopen( filename, "r" ) ) != NULL ) {
        registerBlogPetInfoFromFile( fp );
        fclose( fp );
    }

    CCarotApp   *cp   = (CCarotApp *)AfxGetApp();
    m_currentPetID    = 0;
    m_blogPetID       = cp->m_blogPetList[m_currentPetID].blogPetID;
    m_cousagiName     = cp->m_blogPetList[m_currentPetID].blogPetName;
    m_cousagiUserName = cp->m_blogPetList[m_currentPetID].blogPetUsername;
    m_cousagiPassword = cp->m_blogPetList[m_currentPetID].blogPetPassword;
    m_blogPetType     = cp->m_blogPetList[m_currentPetID].blogPetType == BPTYPE_COUSAGI
                            ? "usagi" :
                        cp->m_blogPetList[m_currentPetID].blogPetType == BPTYPE_CONEKO
                            ? "neko" :
                        cp->m_blogPetList[m_currentPetID].blogPetType == BPTYPE_COINU
                            ? "inu" :
                        cp->m_blogPetList[m_currentPetID].blogPetType == BPTYPE_COPANDA
                            ? "panda" :
                        cp->m_blogPetList[m_currentPetID].blogPetType == BPTYPE_CONEZUMI
                            ? "nezumi" :
                              "blogPet";
    saveBlogPetInfo( gp );
    fclose( gp );

    switchBlogPetInfo();
}

void    CCarotDlg::registerBlogPetInfoFromFile( FILE *fp )
{
    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    char        buf[BUFSIZ], *p;

    if ( cp->m_numOfBlogPets >= MAX_NUM_OF_BLOGPETS )
        return;

    if ( cp->m_blogPetList == NULL ) {
        // BlogPet 情報格納領域を確保
        if ( allocateBlogPetInfo() == false )
            return; // 確保失敗
    }

    int     blogPetType;                    /* BlogPet種別              */
    char    blogPetTypeString[16];          /* BlogPet種別(文字列)      */
    char    blogPetID[MAX_NAMELEN + 1];     /* BlogPet ID               */
    char    blogPetName[MAX_NAMELEN];       /* ペットの名前             */
    char    blogPetUserName[MAX_NAMELEN];   /* BlogPetサーバ ユーザ名   */
    char    blogPetPassword[MAX_PASSWDLEN]; /* BlogPetサーバ パスワード */

    blogPetType        = BPTYPE_UNKNOWN;
    blogPetID[0]       = NUL;
    blogPetName[0]     = NUL;
    blogPetUserName[0] = NUL;
    blogPetPassword[0] = NUL;

    while ( ( p = fgets( buf, BUFSIZ - 1, fp ) ) != NULL ) {
        /*
         * 例) 設定ファイルの中身(のうち関連項目のみ)
         *   cousagiName:     ありみー
         *   cousagiUserName: username
         *   cousagiPassword: xxxxxxxxxx
         *   blogPetType:     panda             (ここうさぎ 2.0 以降)
         *   blogPetID:       2e1609f228b61bfe292dd9aee288af95
         *                                      (ここうさぎ 2.0 以降)
         */
        if ( getStringValue( p, "cousagiName:", blogPetName ) )
            continue;
        if ( getStringValue( p, "cousagiUserName:", blogPetUserName ) )
            continue;
        if ( getStringValue( p, "cousagiPassword:", blogPetPassword ) )
            continue;
        if ( getStringValue( p, "blogPetID:", blogPetID ) )
            continue;
        if ( getStringValue( p, "blogPetType:", blogPetTypeString ) ) {
            if ( !stricmp( blogPetTypeString, "usagi" ) )
                blogPetType = BPTYPE_COUSAGI;
            else if ( !stricmp( blogPetTypeString, "neko"   ) )
                blogPetType = BPTYPE_CONEKO;
            else if ( !stricmp( blogPetTypeString, "inu"    ) )
                blogPetType = BPTYPE_COINU;
            else if ( !stricmp( blogPetTypeString, "panda"  ) )
                blogPetType = BPTYPE_COPANDA;
            else if ( !stricmp( blogPetTypeString, "nezumi" ) )
                blogPetType = BPTYPE_CONEZUMI;
            continue;
        }
    }

    long    n = cp->m_numOfBlogPets;
    bool    found = false;

    if ( blogPetName[0] != NUL ) {
        for ( long i = 0; i < n; i++ ) {
            if ( !strcmp( blogPetName, cp->m_blogPetList[i].blogPetName ) ) {
                found = true;
                break;
            }
        }
    }

    if ( found == false ) {
        if ( blogPetID[0] != NUL )
            strcpy( cp->m_blogPetList[n].blogPetID, blogPetID );
        else
            cp->m_blogPetList[n].blogPetID[0] = NUL;

        if ( blogPetName[0] != NUL )
            strcpy( cp->m_blogPetList[n].blogPetName, blogPetName );
        else
            cp->m_blogPetList[n].blogPetName[0] = NUL;

        if ( blogPetUserName[0] != NUL )
            strcpy( cp->m_blogPetList[n].blogPetUsername, blogPetUserName );
        else
            cp->m_blogPetList[n].blogPetUsername[0] = NUL;

        if ( blogPetPassword[0] != NUL )
            strcpy( cp->m_blogPetList[n].blogPetPassword, blogPetPassword );
        else
            cp->m_blogPetList[n].blogPetPassword[0] = NUL;

        cp->m_blogPetList[n].blogPetType = blogPetType;

        cp->m_numOfBlogPets++;
    }
}

void    CCarotDlg::saveBlogPetInfo( FILE *fp /* = NULL */ )
{
    bool            done = false;
    bool            flag = false;
    bool            encrypted;
    char            key[BUFSIZ];
    unsigned char   *rsaString;
    FILE            *gp;
    char            fileForCheck[MAX_PATH];
    int             retryCount = 0;
    CCarotApp       *cp = (CCarotApp *)AfxGetApp();

    sprintf( fileForCheck, "%s/chk%08dBP",
             m_settingDir, time( NULL ) % 10000000 );
    do {
        key[0]    = NUL;
        rsaString = NULL;
        encrypted = false;

        if ( fp == NULL ) {
            char    filename[MAX_PATH];

            sprintf( filename, "%s/%s", m_settingDir, m_petInfoFile );
            if ( ( fp = fopen( filename, "w" ) ) == NULL )
                return;
            flag = true;
        }
        gp = fopen( fileForCheck, "w" );

        if ( cp->m_numOfBlogPets > 0 ) {
            fprintf( fp, "currentBlogPetIndex: %d\n", m_currentPetID );
            fprintf( fp, "numOfBlogPets: %d\n", cp->m_numOfBlogPets );
            if ( gp )
                fprintf( gp, "numOfBlogPets: %d\n", cp->m_numOfBlogPets );

            for ( long i = 0; i < cp->m_numOfBlogPets; i++ ) {
                fprintf( fp, "pet#%d_blogPetName: %s\n",
                         i + 1,
                         cp->m_blogPetList[i].blogPetName );
                if ( cp->m_blogPetList[i].blogPetID[0] != NUL )
                    fprintf( fp, "pet#%d_blogPetID: %s\n",
                             i + 1,
                             cp->m_blogPetList[i].blogPetID );

                if ( cp->m_blogPetList[i].blogPetUsername[0] != NUL )
                    fprintf( fp, "pet#%d_blogPetUserName: %s\n",
                             i + 1,
                             cp->m_blogPetList[i].blogPetUsername );

                if ( cp->m_blogPetList[i].blogPetPassword[0] != NUL ) {
                    char    paramName[BUFSIZ];

                    sprintf( paramName, "pet#%d_blogPetPassword", i + 1 );
                    encodeParameter( fp, gp,
                                     cp->m_blogPetList[i].blogPetPassword,
                                     paramName,
                                     key, &rsaString, encrypted );
                }
                else {
                    // checkBlogInfo() が無限に false を返すのを防止するため
                    // ダミーのパスワードを設定
                    char    paramName[BUFSIZ];

                    sprintf( paramName, "pet#%d_blogPetPassword", i + 1 );
                    encodeParameter( NULL, gp, /* gp にのみ write */
                                     "dummy",
                                     paramName,
                                     key, &rsaString, encrypted );
                }

                fprintf( fp, "pet#%d_blogPetType: %s\n",
                         i + 1,
                         cp->m_blogPetList[i].blogPetType == BPTYPE_COUSAGI
                             ? "usagi" :
                         cp->m_blogPetList[i].blogPetType == BPTYPE_CONEKO
                             ? "neko" :
                         cp->m_blogPetList[i].blogPetType == BPTYPE_COINU
                             ? "inu" :
                         cp->m_blogPetList[i].blogPetType == BPTYPE_COPANDA
                             ? "panda" :
                         cp->m_blogPetList[i].blogPetType == BPTYPE_CONEZUMI
                             ? "nezumi" :
                               "blogPet" );
            }

            if ( encrypted && key[0] ) {
                fprintf( fp, "encryptedKey: %s\n", key );
                if ( gp )
                    fprintf( gp, "encryptedKey: %s\n", key );
                freeRSAkey( rsaString );
            }
        }
        fprintf( fp, "%s\n", CAROT_INF_EOF_STRING );

        if ( flag ) {
            fclose( fp );
            fp = NULL;
        }
        if ( gp ) {
            fclose( gp );
            gp = NULL;
        }

        /* パスワードが decode できることを確認 */
        if ( encrypted && key[0] ) {
            done = checkBlogPetInfo( fileForCheck );
            if ( done == false )
                if ( fp )
                    rewind( fp );
        }
        else
            done = true;

        if ( done == false ) {
            retryCount++;
            if ( retryCount >= 27 )
                break;
        }
    } while ( done == false );

    unlink( fileForCheck );
}

void    CCarotDlg::loadBlogPetInfo( FILE *fp /* = NULL */ )
{
    char        buf[BUFSIZ], *p;
    char        temp[BUFSIZ];
    char        target[MAX_KEYLENGTH];
    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    long        current   = 0;
    int         count     = 0;
    bool        justOpen  = false;
    bool        encrypted = false;
    char        blogPetPasswordEncrypted[MAX_PASSWDLEN * 16];
    char        key[BUFSIZ];

    blogPetPasswordEncrypted[0] = NUL;
    if ( fp == NULL ) {
        char    filename[MAX_PATH];

        sprintf( filename, "%s/%s", m_settingDir, m_petInfoFile );
        if ( ( fp = fopen( filename, "r" ) ) == NULL )
            return;
        justOpen = true;
    }

    m_currentPetID      = 0;
    cp->m_numOfBlogPets = 0;

    if ( cp->m_blogPetList == NULL ) {
        // BlogPet 情報格納領域を確保
        if ( allocateBlogPetInfo() == false )
            return; // 確保失敗
    }

    key[0] = NUL;
    while ( ( p = fgets( buf, BUFSIZ -1, fp ) ) != NULL ) {
        if ( getStringValue( p, "encryptedKey:", key ) ) {
            encrypted = true;
            break;
        }
    }
    rewind( fp );

    while ( ( p = fgets( buf, BUFSIZ -1, fp ) ) != NULL ) {
        if ( !strncmp(p, CAROT_INF_EOF_STRING, strlen(CAROT_INF_EOF_STRING)) )
            break;

        if ( getStringValue( p, "currentBlogPetIndex:", temp ) ) {
            m_currentPetID = atol( temp );
            if ( m_currentPetID < 0 )
                m_currentPetID = 0;
            continue;
        }
        if ( getStringValue( p, "numOfBlogPets:", temp ) ) {
            cp->m_numOfBlogPets = atol( temp );
            if ( cp->m_numOfBlogPets < 0 )
                cp->m_numOfBlogPets = 0;
            continue;
        }

        if ( cp->m_numOfBlogPets > 0 ) {
            sprintf( target, "pet#%d_", current + 2 );
            if ( !strncmp( p, target, strlen( target ) ) ) {
                current++;
                if ( current >= cp->m_numOfBlogPets )
                    break;
                count = 0;
            }

            sprintf( target, "pet#%d_blogPetName:", current + 1 );
            if ( getStringValue( p, target, cp->m_blogPetList[current].blogPetName ) )
                count++;
            else {
                sprintf( target, "pet#%d_blogPetID:", current + 1 );
                if ( getStringValue( p, target, cp->m_blogPetList[current].blogPetID ) )
                    count++;
                else {
                    sprintf( target, "pet#%d_blogPetUserName:", current + 1 );
                    if ( getStringValue( p, target, cp->m_blogPetList[current].blogPetUsername ) )
                        count++;
                    else {
                        sprintf( target, "pet#%d_blogPetPassword:", current + 1 );
                        if ( getStringValue( p, target, cp->m_blogPetList[current].blogPetPassword ) )
                            count++;
                        else {
                            sprintf( target, "pet#%d_blogPetPasswordEncrypted:", current + 1 );
                            if ( encrypted && key[0] &&
                                 getStringValue( p, target, blogPetPasswordEncrypted ) ) {
                                /* 暗号化されているパスワードを復号する */
                                char            *p;
                                unsigned char   rsaString[BUFSIZ];
                                CString         blogPetPassword;
                                size_t          sz = 0;

                                count++;
                                memset( rsaString, 0x00, BUFSIZ );
                                p = unbase64( (unsigned char *)key,
                                              (unsigned char *)rsaString,
                                              &sz );
                                if ( p ) {
                                    if ( blogPetPasswordEncrypted[0] ) {
                                        decodeParameter(
                                            blogPetPassword,
                                             (unsigned char *)blogPetPasswordEncrypted,
                                             (unsigned char *)rsaString );
                                        strcpy( cp->m_blogPetList[current].blogPetPassword,
                                                (const char *)blogPetPassword );
                                    }
                                }
                            }
                            else {
                                sprintf( target, "pet#%d_blogPetType:", current + 1 );
                                if ( getStringValue( p, target, temp ) ) {
                                    if ( !stricmp( temp, "usagi" ) )
                                        cp->m_blogPetList[current].blogPetType = BPTYPE_COUSAGI;
                                    else if ( !stricmp( temp, "neko"   ) )
                                        cp->m_blogPetList[current].blogPetType = BPTYPE_CONEKO;
                                    else if ( !stricmp( temp, "inu"    ) )
                                        cp->m_blogPetList[current].blogPetType = BPTYPE_COINU;
                                    else if ( !stricmp( temp, "panda"  ) )
                                        cp->m_blogPetList[current].blogPetType = BPTYPE_COPANDA;
                                    else if ( !stricmp( temp, "nezumi" ) )
                                        cp->m_blogPetList[current].blogPetType = BPTYPE_CONEZUMI;
                                    else
                                        cp->m_blogPetList[current].blogPetType = BPTYPE_UNKNOWN;
                                    count++;
                                }
                            }
                        }
                    }
                }
            }

            if ( count == 5 ) {
                current++;
                if ( current >= cp->m_numOfBlogPets )
                    break;
                count = 0;
            }
        }
    }

    if ( count >= 1 )
        if ( current < cp->m_numOfBlogPets )
            current++;

    if ( m_currentPetID >= cp->m_numOfBlogPets )
        m_currentPetID = 0;

    m_blogPetID       = cp->m_blogPetList[m_currentPetID].blogPetID;
    m_cousagiName     = cp->m_blogPetList[m_currentPetID].blogPetName;
    m_cousagiUserName = cp->m_blogPetList[m_currentPetID].blogPetUsername;
    m_cousagiPassword = cp->m_blogPetList[m_currentPetID].blogPetPassword;
    m_blogPetType     = cp->m_blogPetList[m_currentPetID].blogPetType == BPTYPE_COUSAGI
                            ? "usagi" :
                        cp->m_blogPetList[m_currentPetID].blogPetType == BPTYPE_CONEKO
                            ? "neko" :
                        cp->m_blogPetList[m_currentPetID].blogPetType == BPTYPE_COINU
                            ? "inu" :
                        cp->m_blogPetList[m_currentPetID].blogPetType == BPTYPE_COPANDA
                            ? "panda" :
                        cp->m_blogPetList[m_currentPetID].blogPetType == BPTYPE_CONEZUMI
                            ? "nezumi" :
                              "blogPet";
    switchBlogPetInfo();

    if ( justOpen )
        fclose( fp );
}


bool    CCarotDlg::createBlogList()
{
    // blog 情報格納領域を確保
    if ( allocateBlogInfo() == false )
        return ( false );   // 確保失敗

    //   blog 登録画面を表示
    OnButtonSwitchBlog();
    return ( true );
}

void    CCarotDlg::createBlogInfo()
{
    // 「設定ファイル」群を元に「Blog 情報ファイル」を生成
    FILE    *fp, *gp;
    char    filename[MAX_PATH];

    sprintf( filename, "%s/%s", m_settingDir, m_blogInfoFile );
    if ( ( gp = fopen( filename, "w+" ) ) == NULL )
        return;                 /* ↑ w+ とすることで rewind() 可能とする */

    sprintf( filename, "%s/%s", m_settingDir, m_settingFile );
    if ( ( fp = fopen( filename, "r" ) ) != NULL ) {
        registerBlogInfoFromFile( fp );
        fclose( fp );
    }

    for ( int i = 0; i < m_numOfBlogKinds; i++ ) {
        sprintf( filename, "%s/%s.inf",
                 m_settingDir, m_blogKindInfo[i].blogKindID );
        if ( ( fp = fopen( filename, "r" ) ) != NULL ) {
            registerBlogInfoFromFile( fp );
            fclose( fp );
        }
    }

    sprintf( filename, "%s/%s.inf", m_settingDir, "cbox" ); // BlogPet飼育箱
    if ( ( fp = fopen( filename, "r" ) ) != NULL ) {
        registerBlogInfoFromFile( fp );
        fclose( fp );
    }

    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    m_currentBlogID = 0;
    m_blogKind      =
        (enum CCarotDlg::blogKind)(cp->m_blogList[m_currentBlogID].blogKind);
    m_blogName      = cp->m_blogList[m_currentBlogID].blogName;
    m_blogUserName  = cp->m_blogList[m_currentBlogID].blogUsername;
    m_blogPassword  = cp->m_blogList[m_currentBlogID].blogPassword;
    m_blogID        = cp->m_blogList[m_currentBlogID].blogID;
    m_blogURL       = cp->m_blogList[m_currentBlogID].blogURL;

    if ( cp->m_blogList[m_currentBlogID].endpointURL[0] )
        m_endpointURL = cp->m_blogList[m_currentBlogID].endpointURL;
    else {
        int blogKindIndex = -1;
        for ( int j = 0; j < m_numOfBlogKinds; j++ ) {
            if ( m_blogKind == m_blogKindInfo[j].blogKind ) {
                blogKindIndex = j;
                break;
            }
        }
        if ( blogKindIndex >= 0 )
            m_endpointURL = m_blogKindInfo[blogKindIndex].endpointURL;
        else
            m_endpointURL = "";
    }

    m_categoryList.ResetContent();
    m_categoryName  = "";

    saveBlogInfo( gp );
    fclose( gp );

    switchBlogInfo();
}

void    CCarotDlg::loadBlogInfo( FILE *fp /* = NULL */ )
{
    char            buf[BUFSIZ], *p;
    char            temp[BUFSIZ];
    char            target[MAX_KEYLENGTH];
    CCarotApp       *cp = (CCarotApp *)AfxGetApp();
    long            current   = 0;
    int             count     = 0;
    int             catCount  = 0;
    bool            justOpen  = false;
    bool            encrypted = false;
    char            key[BUFSIZ];
    char            blogPasswordEncrypted[MAX_PASSWDLEN * 16];

    if ( fp == NULL ) {
        char    filename[MAX_PATH];

        sprintf( filename, "%s/%s", m_settingDir, m_blogInfoFile );
        if ( ( fp = fopen( filename, "r" ) ) == NULL )
            return;
        justOpen = true;
    }

    m_currentBlogID  = 0;
    cp->m_numOfBlogs = 0;

    if ( cp->m_blogList == NULL ) {
        // blog 情報格納領域を確保
        if ( allocateBlogInfo() == false )
            return; // 確保失敗
    }

    key[0] = NUL;
    blogPasswordEncrypted[0] = NUL;
    while ( ( p = fgets( buf, BUFSIZ -1, fp ) ) != NULL ) {
        if ( getStringValue( p, "encryptedKey:", key ) ) {
            encrypted = true;
            break;
        }
    }
    rewind( fp );

    while ( ( p = fgets( buf, BUFSIZ -1, fp ) ) != NULL ) {
        if ( !strncmp(p, CAROT_INF_EOF_STRING, strlen(CAROT_INF_EOF_STRING)) )
            break;

        if ( getStringValue( p, "currentBlogIndex:", temp ) ) {
            m_currentBlogID = atol( temp );
            if ( m_currentBlogID < 0 )
                m_currentBlogID = 0;
            continue;
        }
        if ( getStringValue( p, "numOfBlogs:", temp ) ) {
            cp->m_numOfBlogs = atol( temp );
            if ( cp->m_numOfBlogs < 0 )
                cp->m_numOfBlogs = 0;
            continue;
        }

        if ( cp->m_numOfBlogs > 0 ) {
            sprintf( target, "blog#%d_", current + 2 );
            if ( !strncmp( p, target, strlen( target ) ) ) {
                current++;
                if ( current >= cp->m_numOfBlogs )
                    break;
                count    = 0;
                catCount = 0;
                cp->m_blogList[current].useCbox = false;
            }

            do {
                sprintf( target, "blog#%d_blogType:", current + 1 );
                if ( getStringValue( p, target, temp ) ) {
                    for ( int j = 0; j < m_numOfBlogKinds; j++ ) {
                        if ( !stricmp(temp, m_blogKindInfo[j].blogKindID) ) {
                            cp->m_blogList[current].blogKind =
                                                m_blogKindInfo[j].blogKind;
                            count++;
                            break;
                        }
                    }
                    break;
                }

                sprintf( target, "blog#%d_blogName:", current + 1 );
                if ( getStringValue( p, target,
                                     cp->m_blogList[current].blogName ) ) {
                    count++;
                    break;
                }

                sprintf( target, "blog#%d_blogID:", current + 1 );
                if ( getStringValue( p, target,
                                     cp->m_blogList[current].blogID ) ) {
                    count++;
                    break;
                }

                sprintf( target, "blog#%d_blogURL:", current + 1 );
                if ( getStringValue( p, target,
                                     cp->m_blogList[current].blogURL ) ) {
                    count++;
                    break;
                }

                sprintf( target, "blog#%d_blogUsername:", current + 1 );
                if ( getStringValue(p, target,
                                    cp->m_blogList[current].blogUsername) ) {
                    count++;
                    break;
                }

                sprintf( target, "blog#%d_blogPassword:", current + 1 );
                if ( getStringValue(p, target,
                                    cp->m_blogList[current].blogPassword) ) {
                    count++;
                    break;
                }
                sprintf( target, "blog#%d_blogPasswordEncrypted:",
                         current + 1 );
                if ( encrypted && key[0] &&
                     getStringValue( p, target, blogPasswordEncrypted ) ) {
                    /* 暗号化されているパスワードを復号する */
                    char            *p;
                    unsigned char   rsaString[BUFSIZ];
                    CString         blogPassword;
                    size_t          sz = 0;

                    count++;
                    memset( rsaString, 0x00, BUFSIZ );
                    p = unbase64( (unsigned char *)key,
                                  (unsigned char *)rsaString,
                                  &sz );
                    if ( p ) {
                        if ( blogPasswordEncrypted[0] ) {
                            decodeParameter(
                                    blogPassword,
                                    (unsigned char *)blogPasswordEncrypted,
                                    (unsigned char *)rsaString );
                            strcpy( cp->m_blogList[current].blogPassword,
                                    (const char *)blogPassword );
                        }
                    }
                }

                sprintf( target, "blog#%d_endpointURL:", current + 1 );
                if ( getStringValue( p, target,
                                     cp->m_blogList[current].endpointURL ) ) {
                    count++;
                    break;
                }

                sprintf( target, "blog#%d_cbox:", current + 1 );
                if ( getStringValue( p, target, temp ) ) {
                    cp->m_blogList[current].useCbox = true;
                    count++;
                    break;
                }

                sprintf( target, "blog#%d_numOfCategories:", current + 1 );
                if ( getStringValue( p, target, temp ) ) {
                    long    numOfCats = atol( temp );

                    if (cp->m_blogList[current].numOfCategories != numOfCats){
                        if ( cp->m_blogList[current].catagory ) {
                            for ( int j = 0;
                                  j < cp->m_blogList[current].numOfCategories;
                                  j++ )
                                free( cp->m_blogList[current].catagory[j] );
                            free( cp->m_blogList[current].catagory );
                        }

                        cp->m_blogList[current].numOfCategories = numOfCats;
                        cp->m_blogList[current].catagory =
                          (char **)malloc( 
                                     cp->m_blogList[current].numOfCategories *
                                                          sizeof ( char * ) );
                        if ( cp->m_blogList[current].catagory ) {
                            for ( int j = 0;
                                  j < cp->m_blogList[current].numOfCategories;
                                  j++ ) {
                                cp->m_blogList[current].catagory[j] =
                                        (char *)malloc(
                                           MAX_CATNAMELENGTH * sizeof (char));
                                if ( !(cp->m_blogList[current].catagory[j]) )
                                    break;
                            }
                        }
                    }
                    count++;
                    break;
                }

                if ((cp->m_blogList[current].numOfCategories > catCount) &&
                    (cp->m_blogList[current].catagory != NULL)             ) {
                    sprintf( target, "blog#%d_category#%d_name:",
                             current + 1, catCount + 1 );
                    if ( getStringValue( p, target,
                             cp->m_blogList[current].catagory[catCount] ) ) {
                        count++;
                        catCount++;
                        break;
                    }
                }
            } while ( false );

            if ( count == 9 + cp->m_blogList[current].numOfCategories ) {
                current++;
                if ( current >= cp->m_numOfBlogs )
                    break;
                count    = 0;
                catCount = 0;
                cp->m_blogList[current].useCbox = false;
            }
        }
    }

    if ( count >= 1 )
        if ( current < cp->m_numOfBlogs )
            current++;

    if ( m_currentBlogID >= cp->m_numOfBlogs )
        m_currentBlogID = 0;

    m_blogKind      =
        (enum CCarotDlg::blogKind)(cp->m_blogList[m_currentBlogID].blogKind);
    m_blogName      = cp->m_blogList[m_currentBlogID].blogName;
    m_blogUserName  = cp->m_blogList[m_currentBlogID].blogUsername;
    m_blogPassword  = cp->m_blogList[m_currentBlogID].blogPassword;
    m_blogID        = cp->m_blogList[m_currentBlogID].blogID;
    m_blogURL       = cp->m_blogList[m_currentBlogID].blogURL;

    if ( cp->m_blogList[m_currentBlogID].endpointURL[0] )
        m_endpointURL = cp->m_blogList[m_currentBlogID].endpointURL;
    else {
        int blogKindIndex = -1;
        for ( int j = 0; j < m_numOfBlogKinds; j++ ) {
            if ( m_blogKind == m_blogKindInfo[j].blogKind ) {
                blogKindIndex = j;
                break;
            }
        }
        if ( blogKindIndex >= 0 )
            m_endpointURL = m_blogKindInfo[blogKindIndex].endpointURL;
        else
            m_endpointURL = "";
    }

    switchBlogInfo();

    if ( justOpen )
        fclose( fp );
}

void    CCarotDlg::saveBlogInfo( FILE *fp /* = NULL */ )
{
    bool            done = false;
    bool            flag = false;
    bool            encrypted;
    char            key[BUFSIZ];
    unsigned char   *rsaString;
    FILE            *gp;
    char            fileForCheck[MAX_PATH];
    int             retryCount = 0;
    CCarotApp       *cp = (CCarotApp *)AfxGetApp();

    sprintf( fileForCheck, "%s/chk%08dBI",
             m_settingDir, time( NULL ) % 10000000 );
    do {
        key[0]    = NUL;
        rsaString = NULL;
        encrypted = false;

        if ( fp == NULL ) {
            char    filename[MAX_PATH];

            sprintf( filename, "%s/%s", m_settingDir, m_blogInfoFile );
            if ( ( fp = fopen( filename, "w" ) ) == NULL )
                return;
            flag = true;
        }
        gp = fopen( fileForCheck, "w" );

        if ( cp->m_numOfBlogs > 0 ) {
            char    blogKindString[16];

            fprintf( fp, "currentBlogIndex: %d\n", m_currentBlogID );
            fprintf( fp, "numOfBlogs: %d\n", cp->m_numOfBlogs );
            if ( gp )
                fprintf( gp, "numOfBlogs: %d\n", cp->m_numOfBlogs );

            for ( long i = 0; i < cp->m_numOfBlogs; i++ ) {
                /*  blog 種別               */
                blogKindString[0] = NUL;
                for ( int j = 0; j < m_numOfBlogKinds; j++ ) {
                    if ( cp->m_blogList[i].blogKind ==
                                            m_blogKindInfo[j].blogKind ) {
                        strcpy( blogKindString, m_blogKindInfo[j].blogKindID );
                        break;
                    }
                }

                if ( blogKindString[0] != NUL )
                    fprintf( fp, "blog#%d_blogType: %s\n",
                             i + 1,
                             blogKindString );

                /*  blog の名前             */
                if ( cp->m_blogList[i].blogName[0] != NUL )
                    fprintf( fp, "blog#%d_blogName: %s\n",
                             i + 1,
                             cp->m_blogList[i].blogName );

                /*  blog ID                 */
                if ( cp->m_blogList[i].blogID[0] != NUL )
                    fprintf( fp, "blog#%d_blogID: %s\n",
                             i + 1,
                             cp->m_blogList[i].blogID );

                /*  blogのトップページのURL */
                if ( cp->m_blogList[i].blogURL[0] != NUL )
                    fprintf( fp, "blog#%d_blogURL: %s\n",
                             i + 1,
                             cp->m_blogList[i].blogURL );

                /*  blog ログインユーザ名   */
                if ( cp->m_blogList[i].blogUsername[0] != NUL )
                    fprintf( fp, "blog#%d_blogUsername: %s\n",
                             i + 1,
                             cp->m_blogList[i].blogUsername );

                /*  blog ログインパスワード */
                if ( cp->m_blogList[i].blogPassword[0] != NUL ) {
                    char    paramName[BUFSIZ];

                    sprintf( paramName, "blog#%d_blogPassword", i + 1 );
                    encodeParameter( fp, gp,
                                     cp->m_blogList[i].blogPassword,
                                     paramName,
                                     key, &rsaString, encrypted );
                }
                else {
                    // checkBlogInfo() が無限に false を返すのを防止するため
                    // ダミーのパスワードを設定
                    char    paramName[BUFSIZ];

                    sprintf( paramName, "blog#%d_blogPassword", i + 1 );
                    encodeParameter( NULL, gp, /* gp にのみ write */
                                     "dummy",
                                     paramName,
                                     key, &rsaString, encrypted );
                }

                /*  エンドポイントURL       */
                if ( cp->m_blogList[i].endpointURL[0] != NUL )
                    fprintf( fp, "blog#%d_endpointURL: %s\n",
                             i + 1,
                             cp->m_blogList[i].endpointURL );

                /*  for “Blog Pet 飼育箱” */
                if ( cp->m_blogList[i].useCbox )
                    fprintf( fp, "blog#%d_cbox: alive\n", i + 1 );

                /* カテゴリ一覧 */
                if ( cp->m_blogList[i].numOfCategories > 0 ) {
                    fprintf( fp, "blog#%d_numOfCategories: %d\n",
                             i + 1,
                             cp->m_blogList[i].numOfCategories );
                    for ( int j = 0; j < cp->m_blogList[i].numOfCategories; j++ ) {
                        fprintf( fp, "blog#%d_category#%d_name: %s\n",
                                 i + 1, j + 1,
                                 cp->m_blogList[i].catagory[j] );
                    }
                }
            }

            if ( encrypted && key[0] ) {
                fprintf( fp, "encryptedKey: %s\n", key );
                if ( gp )
                    fprintf( gp, "encryptedKey: %s\n", key );
                freeRSAkey( rsaString );
            }
        }
        fprintf( fp, "%s\n", CAROT_INF_EOF_STRING );

        if ( flag ) {
            fclose( fp );
            fp = NULL;
        }
        if ( gp ) {
            fclose( gp );
            gp = NULL;
        }

        /* パスワードが decode できることを確認 */
        if ( encrypted && key[0] ) {
            done = checkBlogInfo( fileForCheck );
            if ( done == false )
                if ( fp )
                    rewind( fp );
        }
        else
            done = true;

        if ( done == false ) {
            retryCount++;
            if ( retryCount >= 27 )
                break;
        }
    } while ( done == false );

    unlink( fileForCheck );
}

void    CCarotDlg::registerBlogInfoFromFile( FILE *fp )
{
    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    char        buf[BUFSIZ], *p;

    if ( cp->m_numOfBlogs >= MAX_NUM_OF_BLOGS )
        return;

    if ( cp->m_blogList == NULL ) {
        // blog 情報格納領域を確保
        if ( allocateBlogInfo() == false )
            return; // 確保失敗
    }

    char            blogKindString[16];
    char            cboxString[16];
    enum blogKind   blogKind;                   /*  blog 種別               */
    char            blogName[MAX_NAMELEN];      /*  blog の名前             */
    char            blogUsername[MAX_NAMELEN];  /*  blog ログインユーザ名   */
    char            blogPassword[MAX_PASSWDLEN];/*  blog ログインパスワード */
    char            blogID[MAX_BLOGIDLENGTH + 1];/* blog ID                 */
    char            blogURL[MAX_URLLENGTH];     /*  blogのトップページのURL */
    char            endpointURL[MAX_URLLENGTH]; /*  エンドポイントURL       */
    bool            useCbox;                    /*  for “Blog Pet 飼育箱” */

    blogKind        = unset;
    blogName[0]     = NUL;
    blogUsername[0] = NUL;
    blogPassword[0] = NUL;
    blogID[0]       = NUL;
    blogURL[0]      = NUL;
    endpointURL[0]  = NUL;
    useCbox         = false;

    while ( ( p = fgets( buf, BUFSIZ - 1, fp ) ) != NULL ) {
        /*
         * 例) 設定ファイルの中身(のうち関連項目のみ)
         * blogType:      movableType
         * blogUserName:  tsupo
         * blogPassword:  xxxxxxxxxx
         * endpointURL:   http://example.com/blog/mt/mt.cgi
         * blogID:        1
         * blogURL:       http://example.com/blog/mt/
         * cbox:          alive
         * blogName:      ○△ブログ (ここうさぎ 2.20 以降)
         */
        if ( getStringValue( p, "blogUserName:", blogUsername ) )
            continue;
        if ( getStringValue( p, "blogPassword:", blogPassword ) )
            continue;
        if ( getStringValue( p, "endpointURL:", endpointURL ) )
            continue;
        if ( getStringValue( p, "blogID:", blogID ) )
            continue;
        if ( getStringValue( p, "blogURL:", blogURL ) )
            continue;
        if ( getStringValue( p, "blogName:", blogName ) )
            continue;

        if ( getStringValue( p, "blogType:", blogKindString ) ) {
            blogKind = unset;
            for ( int i = 0; i < m_numOfBlogKinds; i++ ) {
                if ( !stricmp( blogKindString, m_blogKindInfo[i].blogKindID ) ) {
                    blogKind =  m_blogKindInfo[i].blogKind;
                    break;
                }
            }
            continue;
        }

        if ( getStringValue( p, "cbox:", cboxString ) ) {
            useCbox = true;
            continue;
        }
    }

    long    n = cp->m_numOfBlogs;
    bool    found = false;

    if ( blogName[0] != NUL ) {
        for ( long i = 0; i < n; i++ ) {
            if ( !strcmp( blogName, cp->m_blogList[i].blogName ) ) {
                found = true;
                break;
            }
        }
    }
    else {
        for ( long i = 0; i < n; i++ ) {
            if ( blogKind == cp->m_blogList[i].blogKind ) {
                found = true;
                break;
            }
        }
    }

    if ( found == false ) {
        if ( blogUsername[0] != NUL )
            strcpy( cp->m_blogList[n].blogUsername, blogUsername );
        else
            cp->m_blogList[n].blogUsername[0] = NUL;

        if ( blogPassword[0] != NUL )
            strcpy( cp->m_blogList[n].blogPassword, blogPassword );
        else
            cp->m_blogList[n].blogPassword[0] = NUL;

        if ( endpointURL[0] != NUL )
            strcpy( cp->m_blogList[n].endpointURL, endpointURL );
        else
            cp->m_blogList[n].endpointURL[0] = NUL;

        if ( blogID[0] != NUL )
            strcpy( cp->m_blogList[n].blogID, blogID );
        else
            cp->m_blogList[n].blogID[0] = NUL;

        if ( blogURL[0] != NUL )
            strcpy( cp->m_blogList[n].blogURL, blogURL );
        else
            cp->m_blogList[n].blogURL[0] = NUL;

        if ( blogName[0] != NUL )
            strcpy( cp->m_blogList[n].blogName, blogName );
        else
            cp->m_blogList[n].blogName[0] = NUL;

        cp->m_blogList[n].blogKind = blogKind;
        cp->m_blogList[n].useCbox  = useCbox;

        cp->m_numOfBlogs++;
    }
}


/* エンコード済みパスワードが本当にデコードできるのかどうか事前に */
/* 確認しておく (decodeByRSA() がデコードに失敗することがあること */
/* が判明、このメソッドを用意することで[暫定的な]対策とする)      */
bool
CCarotDlg::checkEncodedPassword( const char *filename )
{
    bool    ret = true;
    int     numOfPasswords = 0;
    int     num = 0;
    char    **passwordEncrypted = NULL;
    CString password;
    char    key[BUFSIZ];
    char    buf[BUFSIZ];
    char    *p, *q;
    FILE    *fp;

    key[0] = NUL;

    if ( ( fp = fopen( filename, "r" ) ) != NULL ) {
        while ( ( p = fgets( buf, BUFSIZ - 1, fp ) ) != NULL ) {
            while ( (*p == ' ') || (*p == '\t') )
                p++;
            while ( *p && (p[strlen( p ) - 1] == '\n') )
                p[strlen( p ) - 1] = NUL;
            if ( !(*p) )
                continue;

            if ( !strncmp( p, "numOf", 5 )        &&
                 ((q = strchr( p, ':' )) != NULL)    ) {
                numOfPasswords = atol( q + 1 );

                passwordEncrypted = (char **)malloc( sizeof ( char *) * numOfPasswords );
                for ( int i = 0; i < numOfPasswords; i++ ) {
                    passwordEncrypted[i] = (char *)malloc( MAX_PASSWDLEN * 16 );
                    memset( passwordEncrypted[i], 0x00, MAX_PASSWDLEN * 16 );
                }
                break;
            }
        }

        if ( numOfPasswords > 0 ) {
            rewind( fp );
            while ( ( p = fgets( buf, BUFSIZ - 1, fp ) ) != NULL ) {
                if ( strstr( p, "Encrypted: " ) != NULL ) {
                    if ( num < numOfPasswords ) {
                        q = strchr( p, ':' ) + 1;
                        while ( (*q == ' ') || (*q == '\t') )
                            q++;
                        strcpy( passwordEncrypted[num], q );
                    }
                    num++;
                }
                else if ( !strncmp( p, "encryptedKey: ", 14 ) ) {
                    q = strchr( p, ':' ) + 1;
                    while ( (*q == ' ') || (*q == '\t') )
                        q++;
                    strcpy( key, q );
                }
            }
        }
        fclose( fp );
    }

    if ( numOfPasswords > 0 ) {
        if ( key[0] != NUL ) {
            unsigned char   rsaString[BUFSIZ];
            size_t          sz = 0;

            p = unbase64( (unsigned char *)key,
                          (unsigned char *)rsaString,
                          &sz );
            if ( p ) {
                for ( int i = 0; i < numOfPasswords; i++ ) {
                    password = "";
                    decodeParameter( password,
                                     (unsigned char *)passwordEncrypted[i],
                                     (unsigned char *)rsaString );
                    if ( password.GetLength() == 0 ) {
                        ret = false;
#ifdef  _DEBUG_RSA
                        MessageBox( "パスワードのデコードに失敗しました。  ",
                                    "デコードエラー",
                                    MB_OK|MB_ICONWARNING );
#endif
                    }
                }
            }
        }

        for ( int i = numOfPasswords; i > 0; i-- )
            free( passwordEncrypted[i - 1] );
        free( passwordEncrypted );
    }

    return ( ret ); /* true: デコード成功, false: デコード失敗 */
}

bool
CCarotDlg::checkSetting( const char *filename )
{
    return ( checkEncodedPassword( filename ) );
}

bool
CCarotDlg::checkBlogInfo( const char *filename )
{
    return ( checkEncodedPassword( filename ) );
}

bool
CCarotDlg::checkBlogPetInfo( const char *filename )
{
    return ( checkEncodedPassword( filename ) );
}

void CCarotDlg::SetProxyInfo( bool saveForcely /* = false */ )
{
    CCarotApp               *bp = (CCarotApp *)AfxGetApp();
    CCarotApp::proxyType    saveProxyType = bp->m_proxyType;

    if ( bp->m_proxyType == CCarotApp::autoDetect ) {
        setConfirmProxyInfoFunc( (CONF_FUNC)(-1) );
        bp->m_useProxy = isUsedProxy() == TRUE ? true : false;
    }
    if ( (bp->m_proxyType == CCarotApp::manualSetting)  ||
         (bp->m_proxyType == CCarotApp::specialSetting)    ) {
        if ( bp->m_useProxy ) {
            setProxyInfo( bp->m_proxyServerName,
                          (unsigned short)(bp->m_proxyPortNumber),
                          bp->m_proxyUserName,
                          bp->m_proxyPassword );
        }
    }
    setUseProxy( bp->m_useProxy );

    if ( saveForcely || (saveProxyType != bp->m_proxyType) )
        saveSetting();
    if ( saveForcely )
        setConfirmProxyInfoFunc( (CONF_FUNC)(-1) );
}

/////////////////////////////////////////////////////////////////////////////
// CCarotDlg メッセージ ハンドラ

BOOL CCarotDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	SetIcon(m_hIcon, TRUE);			// 大きいアイコンを設定
	SetIcon(m_hIcon, FALSE);		// 小さいアイコンを設定
	
    switchKeyword( m_keyword );
    switchHaiku( m_haiku );

	return TRUE;
}

void CCarotDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

void CCarotDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 描画用のデバイス コンテキスト

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// クライアントの矩形領域内の中央
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR CCarotDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

bool    CCarotDlg::getParameter( bool savedForcely /* = FALSE */ )
{
    bool    ret = false;
    CEdit   *p;

    if ( m_blogKind == unset ) {
        MessageBox( "Blog種別を設定してください    ",
                    "設定確認", MB_OK|MB_ICONWARNING );
        return ( ret );
    }

    // BlogPet の名前 (optional)
    p = (CEdit *)GetDlgItem( IDC_EDIT_COUSAGI_NAME );
    p->GetWindowText( m_cousagiName );

    // BlogPet の ID (optional)
    p = (CEdit *)GetDlgItem( IDC_EDIT_BLOGPET_ID );
    p->GetWindowText( m_blogPetID );

    // 飼い主のニックネーム (optional)
    p = (CEdit *)GetDlgItem( IDC_EDIT_USER_NAME );
    p->GetWindowText( m_userName );

    // BlogPetサーバ login パスワード (optional)
    p = (CEdit *)GetDlgItem( IDC_EDIT_COUSAGI_PASSWORD );
    p->GetWindowText( m_cousagiPassword );

    // ブログ login パスワード (optional)
    p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_PASSWORD );
    p->GetWindowText( m_blogPassword );

    // Amazon associete ID (optional)
    p = (CEdit *)GetDlgItem( IDC_EDIT_ASSOCIATE_ID );
    p->GetWindowText( m_associateID );

    // BlogPetサーバ login ID (必須)
    p = (CEdit *)GetDlgItem( IDC_EDIT_COUSAGI_USERNAME );
    p->GetWindowText( m_cousagiUserName );
    if ( (m_cousagiUserName.GetLength() <= 0) && (savedForcely == false) ) {
        MessageBox( "「BlogPetサーバ」にloginするときの"
                    "ユーザ名を設定してください    ",
                    "設定確認", MB_OK|MB_ICONWARNING );
        return ( ret );
    }

    // ブログ login ID (必須)
    p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_USERNAME );
    p->GetWindowText( m_blogUserName );
    if ( (m_blogUserName.GetLength() <= 0) && (savedForcely == false) ) {
        MessageBox( "blog にloginするときのユーザ名を設定してください    ",
                    "設定確認", MB_OK|MB_ICONWARNING );
        return ( ret );
    }

    // エンドポイント URL (optional)
    p = (CEdit *)GetDlgItem( IDC_EDIT_ENDPOINT_URL );
    p->GetWindowText( m_endpointURL );
    if ( (m_endpointURL.GetLength() <= 0) && (savedForcely == false) ) {
        if ( (m_blogKind == movableType) ||
             (m_blogKind == metaWeblog)  ||
             (m_blogKind == mtAPI)       ||
             (m_blogKind == atomAPI)        ) {
            // エンドポイントURLの自動取得を試みる
            //  -- トップページ URL を取得
            char    topPageURL[MAX_URLLENGTH + 1];
            CEndPointDlg    dialog;
            int res = dialog.DoModal();
            if ( (res == IDOK) && (dialog.m_endPointURL.GetLength() > 0) ) {
                strcpy( topPageURL, (const char *)dialog.m_endPointURL );

                // -- エンドポイントURL と blog ID を取得
                char    id[MAX_BLOGIDLENGTH + 1];
                char    *url = NULL;

                memset( id, 0x00, MAX_BLOGIDLENGTH + 1 );
                if ( m_blogKind == atomAPI )
                    url = getEndpointURLbyAutoDiscoveryOnAtomAPI(
                                                         topPageURL, id );
                else
                    url = getEndpointURLbyAutoDiscovery( topPageURL, id );

                if ( url && *url ) {
                    MessageBox( "エンドポイントURLの取得に成功しました。    ",
                                "取得成功", MB_OK|MB_ICONINFORMATION );
                    m_endpointURL = url;
                    p->SetWindowText( (const char *)m_endpointURL );

                    if ( id[0] ) {
                        p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_ID );
                        m_blogID = id;
                        p->SetWindowText( (const char *)m_blogID );
                    }
                }
            }

            if ( m_endpointURL.GetLength() <= 0 ) {
                MessageBox( "エンドポイントURLを設定してください    ",
                            "設定確認", MB_OK|MB_ICONWARNING );
                return ( ret );
            }
        }
    }

    // blog ID (optional)
    p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_ID );
    p->GetWindowText( m_blogID );
    if ( (m_blogID.GetLength() <= 0) && (savedForcely == false) ) {
        if ( (m_blogKind == movableType)  ||
             (m_blogKind == bloggerAPI)   ||
             (m_blogKind == metaWeblog)   ||
             (m_blogKind == mtAPI)        ||
             (m_blogKind == atomAPI)      ||
             (m_blogKind == typepad)      ||
             (m_blogKind == typepadJapan) ||
             (m_blogKind == cocolog)      ||
             (m_blogKind == cocologFree)  ||
             (m_blogKind == blogzine)     ||
             (m_blogKind == newsHandler)  ||
             (m_blogKind == ameblo)       ||
             (m_blogKind == seesaa)       ||
             (m_blogKind == netLaputa)    ||
             (m_blogKind == blogG)        ||
             (m_blogKind == fc2blog)      ||
             (m_blogKind == gooBlog)      ||
             (m_blogKind == msnSpaces)    ||
             (m_blogKind == drecomX)      ||
             (m_blogKind == yaplogX)      ||
             (m_blogKind == jugemX)       ||
             (m_blogKind == webryX)       ||
             (m_blogKind == livedoor)     ||
             (m_blogKind == lovelog)      ||
             (m_blogKind == sonet)        ||
             (m_blogKind == vox)          ||
             (m_blogKind == hatena)       ||
             (m_blogKind == blogger)         ) {
            // blog ID の自動取得を試みる
            //  -- 複数の blog が存在する場合は一覧表示し、
            //     ユーザに選択してもらう

            if ( m_blogPassword.GetLength() <= 0 ) {
                // blog ID の取得にはパスワード必須
                MessageBox( "blog ID の自動取得を試みます。\n"
                            "blog ID の自動取得には、「blog にloginする"
                            "ときのパスワード」が必要です。    \n"
                            "blog にloginするときのパスワードを設定して"
                            "ください。",
                            "設定確認", MB_OK|MB_ICONWARNING );
                return ( ret );
            }

#define MAX_BLOGS       30  /* 同一システム内最大設置可能blog数 */
            BLOGINF blogInfo[MAX_BLOGS];
            int     numOfBlogs = MAX_BLOGS;
            int     r;

            /* --- 投稿可能な blog 一覧の取得 */
            setTargetURL( m_endpointURL );
            if ( (m_blogKind == livedoor) ||
                 (m_blogKind == lovelog)  ||
                 (m_blogKind == sonet)    ||
                 (m_blogKind == vox)      ||
                 (m_blogKind == hatena)   ||
                 (m_blogKind == blogger)  ||
                 (m_blogKind == atomAPI)     ) {
                //  --- Atom API 系の場合
                CWaitCursor cur;    // マウスカーソルを砂時計表示
                r = getBlogIDsOnAtomAPI( m_blogUserName, m_blogPassword,
                                         &numOfBlogs, blogInfo );
                        /* 備考: 本家の blogger.com に対しては blogger API */
                        /*       ではなく Atom API を適用する              */
            }
            else {
                //  --- blogger API 系の場合
                CWaitCursor cur;    // マウスカーソルを砂時計表示
                r = getBlogIDs( m_blogUserName, m_blogPassword,
                                &numOfBlogs, blogInfo );    /* blogger API */
            }
            if ( r == 1 ) {
                MessageBox( "blog ID の取得に成功しました。    ",
                            "取得成功", MB_OK|MB_ICONINFORMATION );
                m_blogID = blogInfo[0].blogID;  /* 確定 */

                if ( m_blogID == "" )
                    if ( (m_blogKind == msnSpaces) ||
                         (m_blogKind == webryX)       )
                        m_blogID = "MyBlog";

                p->SetWindowText( (const char *)m_blogID );
            }
            else if ( r > 1 ) {
                /* ---- 投稿先 blog の選択 */
                CBlogIDSelectDlg    dlg;
                dlg.initialize( blogInfo, r );
                int res = dlg.DoModal();
                if ( (res == IDOK) && (dlg.m_blogIDlistIndex != -1) ) {
                    if ( (dlg.m_blogIDlistIndex >= 0) && (dlg.m_blogIDlistIndex < r) ) {
                        r = dlg.m_blogIDlistIndex;
                        m_blogID = blogInfo[r].blogID;  /* 確定 */

                        if ( m_blogID == "" )
                            if ( (m_blogKind == msnSpaces) ||
                                 (m_blogKind == webryX)       )
                                m_blogID = "MyBlog";

                        p->SetWindowText( (const char *)m_blogID );
                        MessageBox( "blog ID の取得に成功しました。    ",
                                    "取得成功", MB_OK|MB_ICONINFORMATION );
                    }
                }
                else {
                    MessageBox( "blog ID を設定してください    ",
                                "設定確認", MB_OK|MB_ICONWARNING );
                    return ( ret );
                }
            }
            else {
                MessageBox( "blog ID の取得に失敗しました。\n"
                            "blog に login するユーザ名かパスワードが"
                            "間違っていないか、確認してください。    ",
                            "取得失敗", MB_OK|MB_ICONWARNING );
                return ( ret );
            }
        }
        else if ( m_blogKind == newPostOnly ) {
            m_blogID = "0";
            p->SetWindowText( (const char *)m_blogID );
        }
    }

    // blog のトップページの URL (optional)
    p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_URL );
    p->GetWindowText( m_blogURL );

    // カテゴリ名 (option)
    CString     categoryString;
    int         location = m_categoryList.GetCurSel();

    if ( location >= 0 ) {
    	m_categoryList.GetText( location, categoryString );
        m_categoryName = categoryString;
    }

    ret = true;

    return ( ret );
}


UINT
ExecuteCocousagi( LPVOID pParam )
{
    const char *p = (const char *)pParam;

    if ( p && *p )
        system( p );

    return ( 0 );
}

char    *
GetTargetPath( const char *targetCommand )
{
    static char targetPath[MAX_PATH];
    char        origPath[MAX_PATH];
    char        realPath[MAX_PATH];

    strcpy( origPath, targetCommand );
    strcpy( realPath, targetCommand );
    PathFindOnPath( realPath, NULL );
    if ( !strcmp( origPath, realPath ) ) {
        char    cwd[MAX_PATH];

        getcwd( cwd, MAX_PATH );
        strcpy( targetPath, cwd );
    }
    else {
        char    *p = strrchr( realPath, '\\' );
        if ( !p )
            p = strrchr( realPath, '/' );
        if ( p ) {
            strncpy( targetPath, realPath, p - realPath );
            targetPath[p - realPath] = NUL;
        }
        else
            strcpy( targetPath, realPath );
    }

    return ( targetPath );
}

void CCarotDlg::OnExecuteCocousagi() 
{
    bool    buttonState = true;
    CString buttonStr;
    CButton *bp = (CButton *)GetDlgItem( IDOK );
    bp->GetWindowText( buttonStr );
    if ( buttonStr.Compare( "ここうさぎ実行" ) != 0 )
        buttonState = false;

    // パラメータ確定
    if ( getParameter() == false )
        return;

    // 設定ファイル保存
    saveSetting();

    if ( buttonState == false ) {
        if ( m_endpointURL.GetLength() > 0  )
            bp->SetWindowText( "ここうさぎ実行" );
        return;
    }

    // 各種ボタンを disable にする
 // bp = (CButton *)GetDlgItem( IDOK );
    BOOL    bOk = bp->IsWindowEnabled();
    bp->EnableWindow( FALSE );

    bp = (CButton *)GetDlgItem( IDCANCEL );
    BOOL    bCancel = bp->IsWindowEnabled();
    bp->EnableWindow( FALSE );

    bp = (CButton *)GetDlgItem( IDC_BUTTON_SWITCH_PET );
    BOOL    bSwitchPet = bp->IsWindowEnabled();
    bp->EnableWindow( FALSE );

    bp = (CButton *)GetDlgItem( IDC_BUTTON_SWITCH_BLOG );
    BOOL    bSwitchBlog = bp->IsWindowEnabled();
    bp->EnableWindow( FALSE );

    bp = (CButton *)GetDlgItem( IDC_BUTTON_BROWSE_BLOG );
    BOOL    bBrowseBlog = bp->IsWindowEnabled();
    bp->EnableWindow( FALSE );

    bp = (CButton *)GetDlgItem( IDC_BUTTON_GET_CATEGORIES );
    BOOL    bGetcategories = bp->IsWindowEnabled();
    bp->EnableWindow( FALSE );

    bp = (CButton *)GetDlgItem( IDC_BUTTON_SETPROXYINFO );
    BOOL    bSetPloxyInfo = bp->IsWindowEnabled();
    bp->EnableWindow( FALSE );

    // cocousagi.exe に渡すパラメータを組み立て
    const char  *targetCommand = "cocousagi.exe";
    CString     commandLine    = targetCommand;
    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
#ifdef  _DEBUG
    commandLine += " -v";
#endif
    commandLine += " -V";
    if ( cp->m_useProxy ) {
        cp->MakeProxyText( GetTargetPath(targetCommand) );
        commandLine += " -p";
    }
    if ( m_postForcely )
        commandLine += " -A";
    if ( m_useWritingForPet )
        commandLine += " -E";

    commandLine += " -f ";
    commandLine += m_settingDir;
    commandLine += "\\";
    commandLine += m_settingFile;

    // cocousagi.exe 起動スレッドを起動
    char    *cmd = new char[commandLine.GetLength() + 1];
    strcpy( cmd, commandLine );
    CWinThread  *tp = AfxBeginThread( ExecuteCocousagi,
                                      (void *)cmd );
    if ( tp ) {
        DWORD   exitCode = 0;
        int     status;

        // cocousagi.exe 起動スレッドが終了するのを待つ
        tp->m_bAutoDelete = FALSE;
        do {
            status = GetExitCodeThread( tp->m_hThread, &exitCode );
            if ( status == FALSE )
                break;
            if ( exitCode == STILL_ACTIVE ) {
                MSG msg;
                if ( PeekMessage( &msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE ) )
                    DispatchMessage( &msg );
                Sleep( 200 );
            }
        } while ( exitCode == STILL_ACTIVE );
        delete tp;
    }
    delete [] cmd;

    // 各種ボタンを enable にする
    bp = (CButton *)GetDlgItem( IDOK );
    bp->EnableWindow( bOk );

    bp = (CButton *)GetDlgItem( IDCANCEL );
    bp->EnableWindow( bCancel );

    bp = (CButton *)GetDlgItem( IDC_BUTTON_SWITCH_PET );
    bp->EnableWindow( bSwitchPet );

    bp = (CButton *)GetDlgItem( IDC_BUTTON_SWITCH_BLOG );
    bp->EnableWindow( bSwitchBlog );

    bp = (CButton *)GetDlgItem( IDC_BUTTON_BROWSE_BLOG );
    bp->EnableWindow( bBrowseBlog );

    bp = (CButton *)GetDlgItem( IDC_BUTTON_GET_CATEGORIES );
    bp->EnableWindow( bGetcategories );

    bp = (CButton *)GetDlgItem( IDC_BUTTON_SETPROXYINFO );
    bp->EnableWindow( bSetPloxyInfo );
}

void CCarotDlg::OnRadioKeywordOn() 
{
    switchKeyword( true );
}

void CCarotDlg::OnRadioKeywordOff() 
{
    switchKeyword( false );
}

void CCarotDlg::OnRadioHaikuOn() 
{
    switchHaiku( true );
}

void CCarotDlg::OnRadioHaikuOff() 
{
    switchHaiku( false );
}

void CCarotDlg::OnShowWindow(BOOL bShow, UINT nStatus) 
{
	CDialog::OnShowWindow(bShow, nStatus);

    if ( bShow ) {
        m_blogKindList.InitStorage( CAROT_NUM_OF_BLOG_KINDS,
                                    CAROT_MAX_BLOG_NAME_LENGTH );
        /*
        m_blogPetTypeList.InitStorage( CAROT_NUM_OF_BLOGPET_TYPES,
                                       CAROT_MAX_BLOGPETTYPE_LENGTH );
        */
        initBlogKindList();

    	CString versionString;
	    versionString.LoadString( IDS_CAROT_VERSION );

        CString version = _T("ここうさぎウィザード  Ver ");
        version += versionString;

        CStatic *s = (CStatic *)GetDlgItem( IDC_CAROT_VERSION );
        s->SetWindowText(version);
    }

    // エンドポイントURL欄を disable にする
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_ENDPOINT_URL );
    p->SetReadOnly( TRUE );

    // blog ID 欄を disable にする
    p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_ID );
    p->SetReadOnly( TRUE );

    // blog 名の欄を disable にする
    p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_NAME );
    p->SetReadOnly( TRUE );

    // blog URLの欄を disable にする
    p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_URL );
    p->SetReadOnly( TRUE );

    // 「BlogPet 切替」ボタンを disable にする
    CButton *q = (CButton *)GetDlgItem( IDC_BUTTON_SWITCH_PET );
    q->EnableWindow( FALSE );

    // 「blog 切替」ボタンを disable にする
    q = (CButton *)GetDlgItem( IDC_BUTTON_SWITCH_BLOG );
    q->EnableWindow( FALSE );

    // 「blog を見る」ボタンを disable にする
    q = (CButton *)GetDlgItem( IDC_BUTTON_BROWSE_BLOG );
    q->EnableWindow( FALSE );

    // 「カテゴリ一覧取得」ボタンを disable にする
    q = (CButton *)GetDlgItem( IDC_BUTTON_GET_CATEGORIES );
    q->EnableWindow( FALSE );

    // 設定ファイルを読み込んで画面を初期化
    loadSetting();
    SetProxyInfo();
}

void CCarotDlg::OnExit() 
{
    // 設定ファイル保存
    saveSetting( TRUE );

    OnOK();
}

void CCarotDlg::OnCheckPostForcely() 
{
    m_postForcely = (m_postForcely == TRUE) ? FALSE : TRUE;
}

void CCarotDlg::OnRadioSimlarityOn() 
{
    switchSimilarity( true );
}

void CCarotDlg::OnRadioSimilarityOff() 
{
    switchSimilarity( false );
}

void CCarotDlg::OnKillfocusEditAssociateId() 
{
    char    buf[MAX_NAMELEN + 1];
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_ASSOCIATE_ID );

    memset( buf, 0x00, MAX_NAMELEN + 1 );
    p->GetWindowText( buf, MAX_NAMELEN );
    if ( buf[0] ) {
        if ((strlen( buf ) < 4)                          ||
            (strcmp( buf + strlen(buf) - 3, "-22" ) != 0)  ) {
            MessageBox( "Amazon アソシエイト ID の中身が変です。    \n"
                        "設定し直してください。",
                        "設定確認", MB_OK|MB_ICONWARNING );
            p->SetFocus();
        }
        else
            m_associateID = buf;
    }
}

void CCarotDlg::OnButtonGetCategories() 
{
    m_categoryList.ResetContent();
    // パラメータ確定
    if ( getParameter() == false )
        return;

    // 念のためにいったん保存
    saveSetting();
    saveBlogInfo();

	/* カテゴリ一覧取得 */
    if ( (m_blogKind == typepad)       ||
         (m_blogKind == typepadJapan ) ||
         (m_blogKind == cocolog )      ||
         (m_blogKind == cocologFree )  ||
         (m_blogKind == blogzine )     ||
         (m_blogKind == seesaa )       ||
         (m_blogKind == netLaputa )    ||
         (m_blogKind == blogG )        ||
         (m_blogKind == newsHandler )  ||
         (m_blogKind == fc2blog )      ||
         (m_blogKind == gooBlog )      ||
         (m_blogKind == drecomX)       ||
         (m_blogKind == yaplogX)       ||
         (m_blogKind == jugemX)        ||
         (m_blogKind == movableType )  ||
         (m_blogKind == mtAPI )           ) {
        /* MovableType 互換 API 利用可能 blog の場合 */
        CWaitCursor cur;    // マウスカーソルを砂時計表示
        CATLISTINF  categoryList[MAX_CATS];
        long        numOfCategories;

        if ( m_blogKind == CCarotDlg::jugemX ) {
            if ( m_blogUserName.GetLength() > 0 ) {
                char    url[MAX_URLLENGTH];
                char    endpointURL[MAX_URLLENGTH];

                strcpy( endpointURL, m_endpointURL );

                const char  *q = strchr( endpointURL, '$' );
                if ( q )
                    q++;
                else
                    q = ".jugem.jp/admin/xmlrpc.php";
                sprintf( url, "http://%s%s",
                         (const char *)m_blogUserName,
                         q );

                m_endpointURL = url;
                CEdit *p = (CEdit *)GetDlgItem( IDC_EDIT_ENDPOINT_URL );
                p->SetWindowText( m_endpointURL );
            }
        }

        setTargetURL( m_endpointURL );
        numOfCategories = MAX_CATS;
        getCategoryList( (const char *)m_blogID,
                         (const char *)m_blogUserName,
                         (const char *)m_blogPassword,
                         &numOfCategories,
                         categoryList );    /* Movable Type API */
        if ( numOfCategories > 0 ) {
            int numOfCats = 0;
            for ( long i = 0; i < numOfCategories; i++ ) {
                char    *p = utf2sjis( categoryList[i].categoryName );
                if ( p ) {
                    m_categoryList.AddString( p );
                    numOfCats++;
                }
            }
            numOfCategories = numOfCats;
        }
    }
    else
    if ( (m_blogKind == msnSpaces) ||
         (m_blogKind == webryX )      ) {
        /* Windows Live Spaces 拡張版 metaWeblog API 採用 blog の場合 */
        CWaitCursor cur;    // マウスカーソルを砂時計表示
        CATEGORIES  categoryList[MAX_CATS];
        long        numOfC = MAX_CATS;
        int         numOfCategories;

        setTargetURL( m_endpointURL );
        numOfCategories = 
            getCategories( "MyBlog",
                           (const char *)m_blogUserName,
                           (const char *)m_blogPassword,
                           &numOfC,
                           categoryList );
        int numOfCats = 0;
        for ( long i = 0; i < numOfCategories; i++ ) {
            char    *p = utf2sjis( categoryList[i].categoryTitle );
            if ( p ) {
                m_categoryList.AddString( p );
                numOfCats++;
            }
        }
        numOfCategories = numOfCats;
    }
    else
    if ( (m_blogKind == livedoor) ||
         (m_blogKind == lovelog)  ||
         (m_blogKind == sonet)    ||
         (m_blogKind == ameblo)   ||
         (m_blogKind == livedoor) ||
         (m_blogKind == vox )     ||
         (m_blogKind == hatena )  ||
         (m_blogKind == blogger ) ||
         (m_blogKind == atomAPI )    ) {
        /* Atom API 利用可能 blog の場合 */
        CWaitCursor cur;    // マウスカーソルを砂時計表示
        CATLISTINF  categoryList[MAX_CATS];
        long        numOfC = MAX_CATS;
        int         numOfCategories;

        setTargetURL( m_endpointURL );
        numOfCategories = 
            listCategoriesOnAtomAPI( (const char *)m_blogUserName,
                                     (const char *)m_blogPassword,
                                     (const char *)m_blogID,
                                     &numOfC,
                                     categoryList );
        int numOfCats = 0;
        for ( long i = 0; i < numOfCategories; i++ ) {
            char    *p = utf2sjis( categoryList[i].categoryName );
            if ( p ) {
                m_categoryList.AddString( p );
                numOfCats++;
            }
        }
        numOfCategories = numOfCats;
    }
    else if ( (m_blogKind == echoo)      ||
              (m_blogKind == exciteBlog) ||
              (m_blogKind == rakuten)       ) {
        /* エコログ、exciteブログ、楽天ブログ の場合 */
        CWaitCursor cur;    // マウスカーソルを砂時計表示
        CATLISTINF  categoryList[MAX_CATS];
        long        numOfCategories;

        numOfCategories = MAX_CATS;

        switch ( m_blogKind ) {
        case echoo:
            getCategoryListEchoo( (const char *)m_blogUserName,
                                  (const char *)m_blogPassword,
                                  &numOfCategories,
                                  categoryList );
            break;

        case exciteBlog:
            getCategoryListExciteBlog( (const char *)m_blogUserName,
                                       (const char *)m_blogPassword,
                                       &numOfCategories,
                                       categoryList );
            break;

        case rakuten:
            getCategoryListRakuten( (const char *)m_blogUserName,
                                    (const char *)m_blogPassword,
                                    &numOfCategories,
                                    categoryList );
            break;
        }

        if ( numOfCategories > 0 ) {
            for ( long i = 0; i < numOfCategories; i++ ) {
                m_categoryList.AddString( categoryList[i].categoryName );
            }
        }
    }
    else {
        MessageBox(
          "申し訳ありませんが、このバージョンの「ここうさぎウィザード」    \n"
          "では、カテゴリ一覧の取得はできません",
                    "カテゴリ一覧取得", MB_OK|MB_ICONWARNING );
        return;
    }
}

void CCarotDlg::OnSelchangeListCategory() 
{
    CString     categoryString;
    int         location = m_categoryList.GetCurSel();

	m_categoryList.GetText( location, categoryString );
    m_categoryName = categoryString;
}

void CCarotDlg::OnButtonSwitchPet() 
{
	CSelectBlogPet  dialog;

    dialog.m_currentPetID = m_currentPetID;

    int res = dialog.DoModal();
    if ( res == IDOK ) {
        CWaitCursor cur;    // マウスカーソルを砂時計表示

        // BlogPet 切替
        m_currentPetID    = dialog.m_currentPetID;
        m_blogPetID       = dialog.m_blogPetID;
        m_cousagiName     = dialog.m_blogPetName;
        m_blogPetType     = dialog.m_blogPetType;
        m_cousagiUserName = dialog.m_blogPetUsername;
        m_cousagiPassword = dialog.m_blogPetPassword;
        saveBlogPetInfo();
        switchBlogPetInfo();
        switchBrowseBlogPet();
    }
    else
        loadBlogPetInfo();
}

void CCarotDlg::OnSelchangeComboBlogPetType() 
{
    CString     blogPetTypeString;
    int         location = m_blogPetTypeList.GetCurSel();

	m_blogPetTypeList.GetLBText( location, blogPetTypeString );

    if ( !blogPetTypeString.Compare( "こうさぎ" ) )
        m_blogPetType = "usagi";
    else if ( !blogPetTypeString.Compare( "こねこ" ) )
        m_blogPetType = "neko";
    else if ( !blogPetTypeString.Compare( "こいぬ" ) )
        m_blogPetType = "inu";
    else if ( !blogPetTypeString.Compare( "こぱんだ" ) )
        m_blogPetType = "panda";
    else if ( !blogPetTypeString.Compare( "こねずみ" ) )
        m_blogPetType = "nezumi";
    else
        m_blogPetType = "blogPet";

    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    if ( cp->m_blogPetList[m_currentPetID].blogPetType != location ) {
        cp->m_blogPetList[m_currentPetID].blogPetType = location;
        saveBlogPetInfo();
        switchBrowseBlogPet();
    }
}

void CCarotDlg::OnSelchangeComboBlogKind() 
{
    CString     blogKindString;
    int         location = m_blogKindList.GetCurSel();
    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    bool        useCbox = false;

	m_blogKindList.GetLBText( location, blogKindString );

    if ( !blogKindString.Compare( m_blogKindInfo[location].blogKindString ) ) {
        m_blogKind      = m_blogKindInfo[location].blogKind;
        m_endpointURL   = "";
        switchEndpointURL( location );
        switchBlogID();

        // blog別設定ファイル読み込み
        int i;
        for ( i = 0; i < m_numOfBlogKinds; i++ ) {
            if ( m_blogKind == m_blogKindInfo[i].blogKind )
                break;
        }
        if ( i < m_numOfBlogKinds ) {
            char    filename[MAX_PATH];

            sprintf( filename, "%s/%s.inf",
                     m_settingDir, m_blogKindInfo[i].blogKindID );
            if ( m_blogKind == newPostOnly ) {
                // 「BlogPet 飼育箱」のための特別処理
                CString     blogKindString;
                int         location = m_blogKindList.GetCurSel();

	            m_blogKindList.GetLBText( location, blogKindString );
                if ( blogKindString.Compare( "BlogPet 飼育箱" ) == 0 ) {
                    sprintf( filename, "%s/%s.inf",
                             m_settingDir, "cbox" );
                    useCbox = true;
                }
            }

            FILE    *fp = fopen( filename, "r" );
            if ( fp ) {
                loadSetting( fp );
                fclose( fp );
            }
            else {
                // blog 情報追加
                if ( cp->m_numOfBlogs < MAX_NUM_OF_BLOGS - 1 ) {
                    // パラメータ確定
                    if ( getParameter() == false )
                        return;

                    // 設定ファイル保存
                    saveSetting();

                    strcpy( cp->m_blogList[cp->m_numOfBlogs].blogID,
                            (const char *)m_blogID );
                    strcpy( cp->m_blogList[cp->m_numOfBlogs].blogURL,
                            (const char *)m_blogURL );
                    strcpy( cp->m_blogList[cp->m_numOfBlogs].blogUsername,
                            (const char *)m_blogUserName );
                    strcpy( cp->m_blogList[cp->m_numOfBlogs].blogPassword,
                            (const char *)m_blogPassword );
                    strcpy( cp->m_blogList[cp->m_numOfBlogs].blogName,
                            (const char *)m_blogName );
                    strcpy( cp->m_blogList[cp->m_numOfBlogs].endpointURL,
                            (const char *)m_endpointURL );
                    cp->m_blogList[cp->m_numOfBlogs].useCbox = useCbox;

                    enum blogKind   blogKindValue = unset;
                    for ( int i = 0; i < m_numOfBlogKinds; i++ ) {
                        if ( !strcmp( blogKindString, m_blogKindInfo[i].blogKindString ) ) {
                            blogKindValue = m_blogKindInfo[i].blogKind;
                            break;
                        }
                    }
                    cp->m_blogList[cp->m_numOfBlogs].blogKind = blogKindValue;

                    m_currentBlogID = cp->m_numOfBlogs;
                    (cp->m_numOfBlogs)++;

                    switchBlogInfo();
                    saveBlogInfo();

                    return;
                }
            }
        }

        // m_currentBlogID の確定
        for ( i = 0; i < cp->m_numOfBlogs; i++ ) {
            if ( ((m_blogID.GetLength() == 0)                 ||
                  (cp->m_blogList[i].blogID[0] == NUL)        ||
                  !m_blogID.Compare( cp->m_blogList[i].blogID ))               &&
                 ((m_blogName.GetLength() == 0)               ||
                  (cp->m_blogList[i].blogName[0] == NUL)      ||
                  !m_blogName.Compare( cp->m_blogList[i].blogName ))           &&
                 ((m_blogUserName.GetLength() == 0)           ||
                  (cp->m_blogList[i].blogUsername[0] == NUL)  ||
                  !m_blogUserName.Compare( cp->m_blogList[i].blogUsername ))   &&
                 ((m_blogPassword.GetLength() == 0)           ||
                  (cp->m_blogList[i].blogPassword[0] == NUL)  ||
                  !m_blogPassword.Compare( cp->m_blogList[i].blogPassword ))   &&
                 ((m_endpointURL.GetLength() == 0)            ||
                  (cp->m_blogList[i].endpointURL[0] == NUL)   ||
                  !m_endpointURL.Compare( cp->m_blogList[i].endpointURL ))     &&
                 (m_blogKind == (enum blogKind)(cp->m_blogList[i].blogKind))      ) {
                // カレント blog を特定
                m_currentBlogID = i;
                if ( m_blogID.GetLength() == 0 )
                    m_blogID = cp->m_blogList[i].blogID;
                if ( m_blogName.GetLength() == 0 )
                    m_blogName = cp->m_blogList[i].blogName;
                if ( m_blogUserName.GetLength() == 0 )
                    m_blogUserName = cp->m_blogList[i].blogUsername;
                if ( m_blogPassword.GetLength() == 0 )
                    m_blogPassword = cp->m_blogList[i].blogPassword;
                if ( m_endpointURL.GetLength() == 0 )
                    m_endpointURL = cp->m_blogList[i].endpointURL;
                if ( m_blogURL.GetLength() == 0 )
                    m_blogURL = cp->m_blogList[i].blogURL;
                break;
            }
        }

        switchBlogInfo();
        switchBrowseBlog();
        saveBlogInfo();
    }
}

void CCarotDlg::OnKillfocusEditBlogPetID() 
{
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_BLOGPET_ID );
    p->GetWindowText( m_blogPetID );

    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    if ( m_blogPetID.Compare( cp->m_blogPetList[m_currentPetID].blogPetID ) ) {
        strcpy( cp->m_blogPetList[m_currentPetID].blogPetID, (const char *)m_blogPetID );
        saveBlogPetInfo();
    }
}

void CCarotDlg::OnKillfocusEditCousagiName() 
{
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_COUSAGI_NAME );
    p->GetWindowText( m_cousagiName );

    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    if ( m_cousagiName.Compare( cp->m_blogPetList[m_currentPetID].blogPetName ) ) {
        strcpy( cp->m_blogPetList[m_currentPetID].blogPetName, (const char *)m_cousagiName );
        saveBlogPetInfo();
    }
}

void CCarotDlg::OnKillfocusEditCousagiUserName() 
{
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_COUSAGI_USERNAME );
    p->GetWindowText( m_cousagiUserName );

    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    if ( m_cousagiUserName.Compare( cp->m_blogPetList[m_currentPetID].blogPetUsername ) ) {
        strcpy( cp->m_blogPetList[m_currentPetID].blogPetUsername, (const char *)m_cousagiUserName );
        saveBlogPetInfo();
    }
}

void CCarotDlg::OnKillfocusEditCousagiPassword() 
{
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_COUSAGI_PASSWORD );
    p->GetWindowText( m_cousagiPassword );

    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    if ( m_cousagiPassword.Compare( cp->m_blogPetList[m_currentPetID].blogPetPassword ) ) {
        strcpy( cp->m_blogPetList[m_currentPetID].blogPetPassword, (const char *)m_cousagiPassword );
        saveBlogPetInfo();
    }
}

void CCarotDlg::OnKillfocusEditEndpointURL() 
{
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_ENDPOINT_URL );
    p->GetWindowText( m_endpointURL );

    bool    buttonStatus = true;
    CButton *bp = (CButton *)GetDlgItem( IDOK );
    if ( m_endpointURL.GetLength() <= 0 )
        if ( (m_blogKind == movableType) ||
             (m_blogKind == metaWeblog)  ||
             (m_blogKind == mtAPI)       ||
             (m_blogKind == atomAPI)        )
            buttonStatus = false;
    if ( buttonStatus == false )
        bp->SetWindowText( "エンドポイントURL取得" );
    else
        bp->SetWindowText( "ここうさぎ実行" );

    DWORD   res = p->GetStyle();
    if ( (res & ES_READONLY) != ES_READONLY ) {
        CCarotApp   *cp = (CCarotApp *)AfxGetApp();
        if ( m_endpointURL.Compare( cp->m_blogList[m_currentBlogID].endpointURL ) ) {
            strcpy( cp->m_blogList[m_currentBlogID].endpointURL, (const char *)m_endpointURL );
            saveBlogInfo();
        }
    }
}

void CCarotDlg::OnButtonSwitchBlog() 
{
    CEditBlogInfoDlg    dlg;
    
    dlg.m_currentBlogID = m_currentBlogID;
    dlg.m_blogInfo      = this;

    int res = dlg.DoModal();
    if ( res == IDOK ) {
        CWaitCursor cur;    // マウスカーソルを砂時計表示
        int blogKindIndex = -1;

        // blog 切替
        m_currentBlogID = dlg.m_currentBlogID;
        m_blogKind      = (enum blogKind)dlg.m_blogKind;
        m_blogName      = dlg.m_blogName;
        m_blogUserName  = dlg.m_blogUsername;
        m_blogPassword  = dlg.m_blogPassword;
        m_blogID        = dlg.m_blogID;
        m_blogURL       = dlg.m_blogURL;

        if ( m_blogKind == CCarotDlg::jugemX ) {
            if ( m_blogUserName.GetLength() > 0 ) {
                char    url[MAX_URLLENGTH];
                char    endpointURL[MAX_URLLENGTH];

                strcpy( endpointURL, m_endpointURL );

                const char  *q = strchr( endpointURL, '$' );
                if ( q )
                    q++;
                else
                    q = ".jugem.jp/admin/xmlrpc.php";
                sprintf( url, "http://%s%s",
                         (const char *)m_blogUserName,
                         q );

                m_endpointURL = url;
                CEdit *p = (CEdit *)GetDlgItem( IDC_EDIT_ENDPOINT_URL );
                p->SetWindowText( m_endpointURL );
            }
        }

        if ( m_blogKind == CCarotDlg::hatena ) {
            if ( strstr( m_endpointURL, "{hatenaID}" ) ) {
                m_endpointURL =
                    "http://d.hatena.ne.jp/" + m_blogUserName + "/atom/blog";
                CEdit *p = (CEdit *)GetDlgItem( IDC_EDIT_ENDPOINT_URL );
                p->SetWindowText( m_endpointURL );
            }
        }

        if ( dlg.m_endpointURL.GetLength() > 0 )
            m_endpointURL = dlg.m_endpointURL;
        else {
            int j;
            for ( j = 0; j < m_numOfBlogKinds; j++ ) {
                if ( m_blogKind == m_blogKindInfo[j].blogKind ) {
                    blogKindIndex = j;
                    break;
                }
            }
            if ( blogKindIndex >= 0 )
                m_endpointURL = m_blogKindInfo[j].endpointURL;
            else
                m_endpointURL = "";
        }

        m_categoryList.ResetContent();
        m_categoryName  = "";

        switchEndpointURL( blogKindIndex );
        if ( m_blogID.GetLength() > 0 )
            switchBlogID( m_blogID );
        else
            switchBlogID();
        switchBlogInfo();
        switchBrowseBlog();
        saveBlogInfo();
    }

    CWaitCursor cur;    // マウスカーソルを砂時計表示
    loadBlogInfo();
}

void CCarotDlg::OnCheckWriting() 
{
    m_useWritingForPet = (m_useWritingForPet == TRUE) ? FALSE : TRUE;
}

void CCarotDlg::OnKillfocusEditBlogUsername() 
{
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_USERNAME );
    p->GetWindowText( m_blogUserName );

    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    if ( m_blogUserName.Compare( cp->m_blogList[m_currentBlogID].blogUsername ) ) {
        strcpy( cp->m_blogList[m_currentBlogID].blogUsername, (const char *)m_blogUserName );
        saveBlogInfo();
    }
}

void CCarotDlg::OnKillfocusEditBlogPassword() 
{
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_PASSWORD );
    p->GetWindowText( m_blogPassword );

    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    if ( m_blogPassword.Compare( cp->m_blogList[m_currentBlogID].blogPassword ) ) {
        strcpy( cp->m_blogList[m_currentBlogID].blogPassword, (const char *)m_blogPassword );
        saveBlogInfo();
    }
}

void CCarotDlg::OnKillfocusEditBlogID() 
{
    CEdit   *p = (CEdit *)GetDlgItem( IDC_EDIT_BLOG_ID );
    p->GetWindowText( m_blogID );

    CCarotApp   *cp = (CCarotApp *)AfxGetApp();
    if ( m_blogID.Compare( cp->m_blogList[m_currentBlogID].blogID ) ) {
        strcpy( cp->m_blogList[m_currentBlogID].blogID, (const char *)m_blogID );
        saveBlogInfo();
    }
}

void CCarotDlg::OnButtonBrowseBlog() 
{
    char        cmd[BUFSIZ];
    CCarotApp   *cp = (CCarotApp *)AfxGetApp();

    cmd[0] = NUL;
    if ( cp->m_blogList[m_currentBlogID].blogURL[0] ) {
        // blog (または SNS の日記)を見る
        strcpy( cmd, cp->m_blogList[m_currentBlogID].blogURL );
        ShellExecute( NULL, "open", cmd, NULL, NULL, SW_SHOWNORMAL );
    }
    else {
        // blog (追加)情報を取得する
	    CAddBlogInfoDlg dlg;
        int             res;

        dlg.m_blogInfo = this;
        dlg.m_mode     = false;

        dlg.m_blogKind     = cp->m_blogList[m_currentBlogID].blogKind;
        dlg.m_blogName     = cp->m_blogList[m_currentBlogID].blogName;
        dlg.m_blogUserName = cp->m_blogList[m_currentBlogID].blogUsername;
        dlg.m_blogPassword = cp->m_blogList[m_currentBlogID].blogPassword;
        dlg.m_blogID       = cp->m_blogList[m_currentBlogID].blogID;
        dlg.m_blogURL      = cp->m_blogList[m_currentBlogID].blogURL;
        dlg.m_endpointURL  = cp->m_blogList[m_currentBlogID].endpointURL;
        dlg.m_useCbox      = cp->m_blogList[m_currentBlogID].useCbox;

        res = dlg.DoModal();
        if ( res == IDOK ) {
            CWaitCursor cur;    // マウスカーソルを砂時計表示

            m_blogKind     = (enum blogKind)dlg.m_blogKind;
            m_blogName     = dlg.m_blogName;
            m_blogUserName = dlg.m_blogUserName;
            m_blogPassword = dlg.m_blogPassword;
            m_blogID       = dlg.m_blogID;
            m_blogURL      = dlg.m_blogURL;
            m_endpointURL  = dlg.m_endpointURL;

            cp->m_blogList[m_currentBlogID].blogKind = dlg.m_blogKind;
            strcpy( cp->m_blogList[m_currentBlogID].blogName,     dlg.m_blogName );
            strcpy( cp->m_blogList[m_currentBlogID].blogUsername, dlg.m_blogUserName );
            strcpy( cp->m_blogList[m_currentBlogID].blogPassword, dlg.m_blogPassword );
            strcpy( cp->m_blogList[m_currentBlogID].blogID,       dlg.m_blogID );
            strcpy( cp->m_blogList[m_currentBlogID].blogURL,      dlg.m_blogURL );
            strcpy( cp->m_blogList[m_currentBlogID].endpointURL,  dlg.m_endpointURL );
            cp->m_blogList[m_currentBlogID].useCbox = dlg.m_useCbox;

            switchEndpointURL();
            if ( m_blogID.GetLength() > 0 )
                switchBlogID( m_blogID );
            else
                switchBlogID();
            switchBlogInfo();
            switchBrowseBlog();
            saveBlogInfo();
        }
    }
}

void CCarotDlg::OnButtonBrowseBlogPet() 
{
    char        cmd[BUFSIZ];
    CCarotApp   *cp = (CCarotApp *)AfxGetApp();

    cmd[0] = NUL;
    if ( cp->m_blogPetList[m_currentPetID].blogPetID[0] ) {
        // BlogPet のプロフィールページを見る
        strcpy( cmd, "http://www.blogpet.net/profile.php?id=" );
        strcat( cmd, cp->m_blogPetList[m_currentPetID].blogPetID );
        ShellExecute( NULL, "open", cmd, NULL, NULL, SW_SHOWNORMAL );
    }
    else {
        // BlogPet ID を取得する
        CWaitCursor cur;    // マウスカーソルを砂時計表示

        cp->GetBlogPetID( cp->m_blogPetList[m_currentPetID].blogPetUsername,
                          cp->m_blogPetList[m_currentPetID].blogPetPassword,
                          cp->m_blogPetList[m_currentPetID].blogPetID );
        m_blogPetID = cp->m_blogPetList[m_currentPetID].blogPetID;

        saveBlogPetInfo();
        switchBlogPetInfo();
        switchBrowseBlogPet();
    }
}

void CCarotDlg::OnButtonSetProxyInfo() 
{
    CCarotApp       *cp = (CCarotApp *)AfxGetApp();
    int             useProxy = cp->m_useProxy;
    char            proxyServer[MAX_SERVERNAME];
    unsigned short  proxyPort;
    char            proxyUserName[MAX_NAMELEN + 1];
    char            proxyPassword[MAX_NAMELEN + 1];

    setConfirmProxyInfoFunc( (CONF_FUNC)(-1) );
    proxyServer[0]   = NUL;
    proxyPort        = 0;
    proxyUserName[0] = NUL;
    proxyPassword[0] = NUL;
    initProxyInfo();
    if ( cp->m_proxyServerName.GetLength() == 0 ) {
        useProxy = FALSE;
        getProxyInfo( &useProxy, proxyServer, &proxyPort,
                      proxyUserName, proxyPassword );
    }
    else {
        strcpy( proxyServer, cp->m_proxyServerName );
        proxyPort = (unsigned short)(cp->m_proxyPortNumber);
        strcpy( proxyUserName, cp->m_proxyUserName );
        strcpy( proxyPassword, cp->m_proxyPassword );
    }
    confirmProxyInfo( &useProxy, proxyServer, &proxyPort,
                      proxyUserName, proxyPassword );

    if ( useProxy == FALSE ) {
        cp->m_proxyType = CCarotApp::notUsed;
        cp->m_useProxy  = false;
    }
    else if ( cp->m_proxyType == CCarotApp::manualSetting ) {
        cp->m_proxyType = CCarotApp::specialSetting;
        if ( cp->m_useProxy ) {
            setProxyInfo( cp->m_proxyServerName,
                          (unsigned short)(cp->m_proxyPortNumber),
                          cp->m_proxyUserName,
                          cp->m_proxyPassword );
        }
    }
    setUseProxy( cp->m_useProxy );
    syncProxyInfo();
    saveSetting();
}
