/*
 * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "jaccesswalker.h"
#include "AccessInfo.h"

HWND ourHwnd;
HWND topLevelWindow;
int depth = -1;
FILE *logfile;
HMENU popupMenu;

char theJaccesswalkerClassName[] = "JaccesswalkerWin";
char theAccessInfoClassName[] = "AccessInfoWin";

HWND theJaccesswalkerWindow;
HWND theTreeControlWindow;
HINSTANCE theInstance;
Jaccesswalker *theJaccesswalker;
AccessibleNode *theSelectedNode;
AccessibleNode *thePopupNode;
AccessibleContext theSelectedAccessibleContext;
HWND hwndTV;    // handle of tree-view control

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{

    if (logfile == null) {
        logfile = fopen(JACCESSWALKER_LOG, "w"); // overwrite existing log file
        logString(logfile, "Starting jaccesswalker.exe %s\n", getTimeAndDate());
    }

    theInstance = hInstance;

    // start Jaccesswalker
    theJaccesswalker = new Jaccesswalker(nCmdShow);

    return 0;
}

Jaccesswalker::Jaccesswalker(int nCmdShow) {

    HWND hwnd;
    static char szAppName[] = "jaccesswalker";
    static char szMenuName[] = "JACCESSWALKERMENU";
    MSG msg;
    WNDCLASSEX wc;

    // jaccesswalker window
    wc.cbSize = sizeof(wc);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WinProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = theInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDI_APPLICATION);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = szMenuName;
    wc.lpszClassName = szAppName;
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    RegisterClassEx(&wc);

    // AccessInfo Window
    wc.cbSize = sizeof(WNDCLASSEX);

    wc.hInstance = theInstance;
    wc.lpszClassName = theAccessInfoClassName;
    wc.lpfnWndProc = (WNDPROC)AccessInfoWindowProc;
    wc.style = 0;

    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);

    wc.lpszMenuName = "";
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;

    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);

    RegisterClassEx(&wc);

    // create the jaccesswalker window
    hwnd = CreateWindow(szAppName,
                        szAppName,
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        NULL,
                        NULL,
                        theInstance,
                        NULL);

    ourHwnd = hwnd;

    /* Initialize the common controls. */
    INITCOMMONCONTROLSEX cc;
    cc.dwSize = sizeof(INITCOMMONCONTROLSEX);
    cc.dwICC = ICC_TREEVIEW_CLASSES;
    InitCommonControlsEx(&cc);

    ShowWindow(hwnd, nCmdShow);

    UpdateWindow(hwnd);

    BOOL result = initializeAccessBridge();
    if (result != FALSE) {
        while (GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        shutdownAccessBridge();
    }
}

/*
 * the jaccesswalker window proc
 */
LRESULT CALLBACK WinProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {

    int command;
    short width, height;

    switch(iMsg) {

    case WM_CREATE:
        // create the accessibility tree view
        theTreeControlWindow = CreateATreeView(hwnd);

        // load the popup menu
        popupMenu = LoadMenu(theInstance, "PopupMenu");
        popupMenu = GetSubMenu(popupMenu, 0);
        break;

    case WM_CLOSE:
        EndDialog(hwnd, TRUE);
        PostQuitMessage (0);
        break;

    case WM_SIZE:
        width = LOWORD(lParam);
        height = HIWORD(lParam);
        SetWindowPos(theTreeControlWindow, NULL, 0, 0, width, height, 0);
        return FALSE;  // let windows finish handling this

    case WM_COMMAND:
        command = LOWORD(wParam);
        switch(command) {

        case cExitMenuItem:
            EndDialog(hwnd, TRUE);
            PostQuitMessage (0);
            break;

        case cRefreshTreeItem:
            // update the accessibility tree
            theJaccesswalker->buildAccessibilityTree();
            break;

        case cAPIMenuItem:
            // open a new window with the Accessibility API in it for the
            // selected element in the tree
            if (theSelectedNode != (AccessibleNode *) 0) {
                theSelectedNode->displayAPIWindow();
            }
            break;

        case cAPIPopupItem:
            // open a new window with the Accessibility API in it for the
            // element in the tree adjacent to the popup menu
            if (thePopupNode != (AccessibleNode *) 0) {
                thePopupNode->displayAPIWindow();
            }
            break;

        }
        break;

    case WM_NOTIFY:  // receive tree messages

        NMTREEVIEW *nmptr = (LPNMTREEVIEW) lParam;
        switch (nmptr->hdr.code) {

        case TVN_SELCHANGED:
            // get the selected tree node
            theSelectedNode = (AccessibleNode *) nmptr->itemNew.lParam;
            break;

        case NM_RCLICK:

            // display a popup menu over the tree node
            POINT p;
            GetCursorPos(&p);
            TrackPopupMenu(popupMenu, 0, p.x, p.y, 0, hwnd, NULL);

            // get the tree node under the popup menu
            TVHITTESTINFO hitinfo;
            ScreenToClient(theTreeControlWindow, &p);
            hitinfo.pt = p;
            HTREEITEM node = TreeView_HitTest(theTreeControlWindow, &hitinfo);

            if (node != null) {
                TVITEMEX tvItem;
                tvItem.hItem = node;
                if (TreeView_GetItem(hwndTV, &tvItem) == TRUE) {
                    thePopupNode = (AccessibleNode *)tvItem.lParam;
                }
            }
            break;
        }
    }
    return DefWindowProc(hwnd, iMsg, wParam, lParam);
}

/*
 * Accessibility information window proc
 */
LRESULT CALLBACK AccessInfoWindowProc(HWND hWnd, UINT message,
                                    UINT wParam, LONG lParam) {
    short width, height;
    HWND dlgItem;

    switch (message) {
    case WM_CREATE:
        RECT rcClient;    // dimensions of client area
        HWND hwndEdit;    // handle of tree-view control

        // Get the dimensions of the parent window's client area,
        // and create the edit control.
        GetClientRect(hWnd, &rcClient);
        hwndEdit = CreateWindow("Edit",
                                "",
                                WS_VISIBLE | WS_TABSTOP | WS_CHILD |
                                ES_MULTILINE | ES_AUTOVSCROLL |
                                ES_READONLY | WS_VSCROLL,
                                0, 0, rcClient.right, rcClient.bottom,
                                hWnd,
                                (HMENU) cAccessInfoText,
                                theInstance,
                                NULL);
        break;

    case WM_CLOSE:
        DestroyWindow(hWnd);
        break;

    case WM_SIZE:
        width = LOWORD(lParam);
        height = HIWORD(lParam);
        dlgItem = GetDlgItem(hWnd, cAccessInfoText);
        SetWindowPos(dlgItem, NULL, 0, 0, width, height, 0);
        return FALSE;  // let windows finish handling this
        break;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }

    return 0;
}

/**
 * Build a tree (and the treeview control) of all accessible Java components
 *
 */
void Jaccesswalker::buildAccessibilityTree() {
    TreeView_DeleteAllItems (theTreeControlWindow);
    // have MS-Windows call EnumWndProc() with all of the top-level windows
    EnumWindows((WNDENUMPROC) EnumWndProc, NULL);
}

/**
 * Create (and display) the accessible component nodes of a parent AccessibleContext
 *
 */
BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lParam) {
    if (IsJavaWindow(hwnd)) {
        long vmID;
        AccessibleContext ac;
        if (GetAccessibleContextFromHWND(hwnd, &vmID, &ac) == TRUE) {
            theJaccesswalker->addComponentNodes(vmID, ac, (AccessibleNode *) NULL,
                                         hwnd, TVI_ROOT, theTreeControlWindow);
        }
        topLevelWindow = hwnd;
    } else {
        char szClass [MAX_PATH] = {0};
        ::GetClassNameA(hwnd, szClass, sizeof(szClass) - 1);
        if ( ( 0 == ::strcmp(szClass, "IEFrame") )
             || ( 0 == ::strcmp(szClass, "MozillaUIWindowClass") ) ) {
            EnumChildWindows(hwnd, (WNDENUMPROC) EnumChildProc, NULL);
        }
    }
    return TRUE;
}

/*
Detects whether or not the specified Java window is one from which no useable
information can be obtained.

This function tests for various scenarios I have seen in Java applets where the
Java applet had no meaningful accessible information.  It does not detect all
scenarios, just the most common ones.
*/
BOOL IsInaccessibleJavaWindow(const HWND hwnd)
{
    BOOL ret_val ( FALSE );
    {
        BOOL bT ( FALSE );
        long vmIdWindow ( 0 );
        AccessibleContext acWindow ( 0 );
        bT = GetAccessibleContextFromHWND(hwnd, &vmIdWindow, &acWindow);
        if ( ( bT ) && ( 0 != vmIdWindow ) && ( 0 != acWindow ) ) {
            AccessibleContextInfo infoWindow = {0};
            bT = GetAccessibleContextInfo(vmIdWindow, acWindow, &infoWindow);
            if ( ( bT )
                 && ( 0 == infoWindow.name [0] )
                 && ( 0 == infoWindow.description [0] )
                 && ( 0 == ::wcscmp(infoWindow.role_en_US, L"frame") ) ) {
                if ( 0 == infoWindow.childrenCount ) {
                    ret_val = TRUE;
                } else if ( 1 == infoWindow.childrenCount ) {
                    AccessibleContext acChild ( 0 );
                    acChild =
                        GetAccessibleChildFromContext(vmIdWindow, acWindow, 0);
                    if ( NULL != acChild ) {
                        AccessibleContextInfo infoChild = {0};
                        bT = GetAccessibleContextInfo( vmIdWindow, acChild,
                                                       &infoChild );
                        if ( ( bT )
                             && ( 0 == infoChild.name [0] )
                             && ( 0 == infoChild.description [0] )
                             && ( 0 == ::wcscmp(infoChild.role_en_US, L"panel") )
                             && ( 1 == infoChild.childrenCount ) ) {
                            AccessibleContext acChild1 ( 0 );
                            acChild1 = GetAccessibleChildFromContext( vmIdWindow,
                                                                      acChild, 0);
                            if ( NULL != acChild1 ) {
                                AccessibleContextInfo infoChild1 = {0};
                                bT = GetAccessibleContextInfo( vmIdWindow,
                                                               acChild1, &infoChild1 );
                                if ( ( bT )
                                     && ( 0 == infoChild1.name [0] )
                                     && ( 0 == infoChild1.description [0] )
                                     && ( 0 == ::wcscmp(infoChild1.role_en_US, L"frame") )
                                     && ( 0 == infoChild1.childrenCount ) ) {
                                    ret_val = TRUE;
                                } else if ( ( bT )
                                            && ( 0 == infoChild1.name [0] )
                                            && ( 0 == infoChild1.description [0] )
                                            && ( 0 == ::wcscmp( infoChild1.role_en_US,
                                                                L"panel") )
                                            && ( 1 == infoChild1.childrenCount ) ) {
                                    AccessibleContext acChild2 ( 0 );
                                    acChild2 = GetAccessibleChildFromContext(
                                                    vmIdWindow, acChild1, 0 );
                                    if ( NULL != acChild2 ) {
                                        AccessibleContextInfo infoChild2 = {0};
                                        bT = GetAccessibleContextInfo(
                                                vmIdWindow, acChild2, &infoChild2 );
                                        if ( ( bT )
                                             && ( 0 == infoChild2.name [0] )
                                             && ( 0 == infoChild2.description [0] )
                                             && ( 0 == ::wcscmp( infoChild2.role_en_US,
                                                                 L"frame") )
                                             && ( 0 == infoChild2.childrenCount ) ) {
                                            ret_val = TRUE;
                                        }
                                    }
                                }
                            }
                        } else if ( ( bT )
                                    && ( 0 == infoChild.name [0] )
                                    && ( 0 == infoChild.description [0] )
                                    && ( 0 == ::wcscmp( infoChild.role_en_US,
                                                        L"canvas") )
                                    && ( 0 == infoChild.childrenCount ) ) {
                            ret_val = TRUE;
                        }
                    }
                }
            } else if ( ( bT )
                        && ( 0 == infoWindow.name [0] )
                        && ( 0 == infoWindow.description [0] )
                        && ( 0 == ::wcscmp(infoWindow.role_en_US, L"panel") ) ) {
                if ( 1 == infoWindow.childrenCount ) {
                    AccessibleContext acChild ( 0 );
                    acChild = GetAccessibleChildFromContext( vmIdWindow,
                                                             acWindow, 0 );
                    if ( NULL != acChild ) {
                        AccessibleContextInfo infoChild = {0};
                        bT = GetAccessibleContextInfo( vmIdWindow,
                                                       acChild, &infoChild );
                        if ( ( bT )
                             && ( 0 == infoChild.name [0] )
                             && ( 0 == infoChild.description [0] )
                             && ( 0 == ::wcscmp(infoChild.role_en_US, L"frame") )
                             && ( 0 == infoChild.childrenCount ) ) {
                                ret_val = TRUE;
                        } else if ( ( bT )
                                    && ( 0 == infoChild.name [0] )
                                    && ( 0 == infoChild.description [0] )
                                    && ( 0 == ::wcscmp( infoChild.role_en_US,
                                                        L"panel") )
                                    && ( 1 == infoChild.childrenCount ) ) {
                            AccessibleContext acChild1 ( 0 );
                            acChild1 = GetAccessibleChildFromContext( vmIdWindow,
                                                                      acChild, 0);
                            if ( NULL != acChild1 ) {
                                AccessibleContextInfo infoChild1 = {0};
                                bT = GetAccessibleContextInfo( vmIdWindow,
                                                               acChild1,
                                                               &infoChild1 );
                                if ( ( bT )
                                     && ( 0 == infoChild1.name [0] )
                                     && ( 0 == infoChild1.description [0] )
                                     && ( 0 == ::wcscmp( infoChild1.role_en_US,
                                                         L"frame") )
                                     && ( 0 == infoChild1.childrenCount ) ) {
                                    ret_val = TRUE;
                                }
                            }
                        }
                    }
                }
            }
        } else if ( FALSE == bT ) {
            ret_val = TRUE;
        }
    }
    return ret_val;
}

BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
    if ( ( IsJavaWindow(hwnd) )
         && ( FALSE == IsInaccessibleJavaWindow(hwnd) ) ) {
        long vmID ( 0 );
        AccessibleContext ac ( 0 );
        if ( TRUE == GetAccessibleContextFromHWND(hwnd, &vmID, &ac) ) {
            theJaccesswalker->addComponentNodes(
                vmID, ac, (AccessibleNode *) NULL,
                hwnd, TVI_ROOT, theTreeControlWindow);
        }
        topLevelWindow = hwnd;
    } else {
        EnumChildWindows(hwnd, (WNDENUMPROC) EnumChildProc, NULL);
    }
    return TRUE;
}

// CreateATreeView - creates a tree-view control.
// Returns the handle of the new control if successful or NULL
//     otherwise.
// hwndParent - handle of the control's parent window
HWND CreateATreeView(HWND hwndParent) {
    RECT rcClient;  // dimensions of client area

    // Get the dimensions of the parent window's client area, and create
    // the tree-view control.
    GetClientRect(hwndParent, &rcClient);
    hwndTV = CreateWindow(WC_TREEVIEW,
                          "",
                          WS_VISIBLE | WS_TABSTOP | WS_CHILD |
                          TVS_HASLINES | TVS_HASBUTTONS |
                          TVS_LINESATROOT,
                          0, 0, rcClient.right, rcClient.bottom,
                          hwndParent,
                          (HMENU) cTreeControl,
                          theInstance,
                          NULL);

    return hwndTV;
}

/**
 * Create (and display) the accessible component nodes of a parent AccessibleContext
 *
 */
void Jaccesswalker::addComponentNodes(long vmID, AccessibleContext context,
                                    AccessibleNode *parent, HWND hwnd,
                                    HTREEITEM treeNodeParent, HWND treeWnd) {

    AccessibleNode *newNode = new AccessibleNode( vmID, context, parent, hwnd,
                                                  treeNodeParent );

    AccessibleContextInfo info;
    if (GetAccessibleContextInfo(vmID, context, &info) != FALSE) {
        char s[LINE_BUFSIZE];

        wsprintf(s, "%ls", info.name);
        newNode->setAccessibleName(s);
        wsprintf(s, "%ls", info.role);
        newNode->setAccessibleRole(s);

        wsprintf(s, "%ls [%ls]", info.name, info.role);

        TVITEM tvi;
        tvi.mask = TVIF_PARAM | TVIF_TEXT;
        tvi.pszText = (char *) s; // Accessible name and role
        tvi.cchTextMax = (int)strlen(s);
        tvi.lParam = (long) newNode; // Accessibility information

        TVINSERTSTRUCT tvis;
        tvis.hParent = treeNodeParent;
        tvis.hInsertAfter = TVI_LAST;
        tvis.item = tvi;

        HTREEITEM treeNodeItem = TreeView_InsertItem(treeWnd, &tvis);

        for (int i = 0; i < info.childrenCount; i++) {
            addComponentNodes(vmID, GetAccessibleChildFromContext(vmID, context, i),
                              newNode, hwnd, treeNodeItem, treeWnd);
        }
    } else {
        char s[LINE_BUFSIZE];
        sprintf( s,
            "ERROR calling GetAccessibleContextInfo; vmID = %X, context = %X",
            vmID, context );

        TVITEM tvi;
        tvi.mask = TVIF_PARAM | TVIF_TEXT;  // text and lParam are only valid parts
        tvi.pszText = (char *) s;
        tvi.cchTextMax = (int)strlen(s);
        tvi.lParam = (long) newNode;

        TVINSERTSTRUCT tvis;
        tvis.hParent = treeNodeParent;
        tvis.hInsertAfter = TVI_LAST;  // make tree in order given
        tvis.item = tvi;

        HTREEITEM treeNodeItem = TreeView_InsertItem(treeWnd, &tvis);
    }
}

// -----------------------------

/**
 * Create an AccessibleNode
 *
 */
AccessibleNode::AccessibleNode(long JavaVMID, AccessibleContext context,
                               AccessibleNode *parent, HWND hwnd,
                               HTREEITEM parentTreeNodeItem) {
    vmID = JavaVMID;
    ac = context;
    parentNode = parent;
    baseHWND = hwnd;
    treeNodeParent = parentTreeNodeItem;

    // setting accessibleName and accessibleRole not done here,
    // in order to minimize calls to the AccessBridge
    // (since such a call is needed to enumerate children)
}

/**
 * Destroy an AccessibleNode
 *
 */
AccessibleNode::~AccessibleNode() {
    ReleaseJavaObject(vmID, ac);
}

/**
 * Set the accessibleName string
 *
 */
void AccessibleNode::setAccessibleName(char *name) {
    strncpy(accessibleName, name, MAX_STRING_SIZE);
}

/**
 * Set the accessibleRole string
 *
 */
void AccessibleNode::setAccessibleRole(char *role) {
    strncpy(accessibleRole, role, SHORT_STRING_SIZE);
}







/**
 * Create an API window to show off the info for this AccessibleContext
 */
BOOL AccessibleNode::displayAPIWindow() {

    HWND apiWindow = CreateWindow(theAccessInfoClassName,
                                  "Java Accessibility API view",
                                  WS_OVERLAPPEDWINDOW,
                                  CW_USEDEFAULT,
                                  CW_USEDEFAULT,
                                  600,
                                  750,
                                  HWND_DESKTOP,
                                  NULL,
                                  theInstance,
                                  (void *) NULL);

    if (!apiWindow) {
        printError("cannot create API window");
        return FALSE;
    }

    char buffer[HUGE_BUFSIZE];
    buffer[0] = '\0';
    getAccessibleInfo(vmID, ac, buffer, sizeof(buffer));
    displayAndLog(apiWindow, cAccessInfoText, logfile, buffer);

    ShowWindow(apiWindow, SW_SHOWNORMAL);
    UpdateWindow(apiWindow);

    return TRUE;
}



