/* Create a new AwtTextArea or AwtTextField object and window.   */
AwtTextComponent* AwtTextComponent::Create(jobject peer, jobject parent, BOOL isMultiline)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject target = NULL;
    AwtTextComponent* c = NULL;

    try {
        if (env->EnsureLocalCapacity(1) < 0) {
            return NULL;
        }

        PDATA pData;
        AwtCanvas* awtParent;
        JNI_CHECK_PEER_GOTO(parent, done);

        awtParent = (AwtCanvas*)pData;
        JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);

        target = env->GetObjectField(peer, AwtObject::targetID);
        JNI_CHECK_NULL_GOTO(target, "null target", done);

        if(isMultiline) {
            c = new AwtTextArea();
        } else {
            c = new AwtTextField();
        }

        {
            /* Adjust style for scrollbar visibility and word wrap  */
            DWORD scroll_style;

            if(isMultiline) {

                jint scrollbarVisibility =
                    env->GetIntField(target, AwtTextArea::scrollbarVisibilityID);

                switch (scrollbarVisibility) {
                case java_awt_TextArea_SCROLLBARS_NONE:
                    scroll_style = ES_AUTOVSCROLL;
                    break;
                case java_awt_TextArea_SCROLLBARS_VERTICAL_ONLY:
                    scroll_style = WS_VSCROLL | ES_AUTOVSCROLL;
                    break;
                case java_awt_TextArea_SCROLLBARS_HORIZONTAL_ONLY:
                    scroll_style = WS_HSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL;
                    break;
                case java_awt_TextArea_SCROLLBARS_BOTH:
                    scroll_style = WS_VSCROLL | WS_HSCROLL |
                                   ES_AUTOVSCROLL | ES_AUTOHSCROLL;
                    break;
                }
            }

            DWORD style = WS_CHILD | WS_CLIPSIBLINGS | ES_LEFT;

            /*
             * Specify ES_DISABLENOSCROLL - RichEdit control style to disable
             * scrollbars instead of hiding them when not needed.
             */
            style |= isMultiline ?  ES_MULTILINE | ES_WANTRETURN | scroll_style
                     | ES_DISABLENOSCROLL : ES_AUTOHSCROLL;


            DWORD exStyle = WS_EX_CLIENTEDGE;
            if (GetRTL()) {
                exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
                if (GetRTLReadingOrder())
                    exStyle |= WS_EX_RTLREADING;
            }


            jint x = env->GetIntField(target, AwtComponent::xID);
            jint y = env->GetIntField(target, AwtComponent::yID);
            jint width = env->GetIntField(target, AwtComponent::widthID);
            jint height = env->GetIntField(target, AwtComponent::heightID);

            c->CreateHWnd(env, L"", style, exStyle,
                          x, y, width, height,
                          awtParent->GetHWnd(),
                          reinterpret_cast<HMENU>(static_cast<INT_PTR>(
                                  awtParent->CreateControlID())),
                          ::GetSysColor(COLOR_WINDOWTEXT),
                          ::GetSysColor(COLOR_WINDOW),
                          peer);

            // Fix for 4753116.
            // If it is not win95 (we are using Richedit 2.0)
            // we set plain text mode, in which the control is
            // similar to a standard edit control:
            //  - The text in a plain text control can have only
            //    one format.
            //  - The user cannot paste rich text formats, such as RTF
            //    or embedded objects into a plain text control.
            //  - Rich text mode controls always have a default
            //    end-of-document marker or carriage return,
            //    to format paragraphs.
            // [email protected]
            c->SendMessage(EM_SETTEXTMODE, TM_PLAINTEXT, 0);

            c->m_backgroundColorSet = TRUE;
            /* suppress inheriting parent's color. */
            c->UpdateBackground(env, target);
            c->SendMessage(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN,
                           MAKELPARAM(1, 1));
            /*
             * Fix for BugTraq Id 4260109.
             * Set the text limit to the maximum.
             * Use EM_EXLIMITTEXT for RichEdit controls.
             * For some reason RichEdit 1.0 becomes read-only if the
             * specified limit is greater than 0x7FFFFFFD.
             */
            c->SendMessage(EM_EXLIMITTEXT, 0, 0x7FFFFFFD);

            /* Unregister RichEdit built-in drop target. */
            VERIFY(::RevokeDragDrop(c->GetHWnd()) != DRAGDROP_E_INVALIDHWND);

            /* To enforce CF_TEXT format for paste operations. */
            VERIFY(c->SendMessage(EM_SETOLECALLBACK, 0,
                                  (LPARAM)&GetOleCallback()));

            c->SendMessage(EM_SETEVENTMASK, 0, ENM_CHANGE);
        }
    } catch (...) {
        env->DeleteLocalRef(target);
        throw;
    }

done:
    env->DeleteLocalRef(target);

    return c;
}