/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation and Others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Takashi ITOH - initial API and implementation
 *******************************************************************************/
package org.eclipse.actf.visualization.gui.util;

import java.text.MessageFormat;

import org.eclipse.actf.accservice.swtbridge.AccessibleObject;
import org.eclipse.actf.accservice.swtbridge.IA2;
import org.eclipse.actf.accservice.swtbridge.MSAA;
import org.eclipse.actf.accservice.swtbridge.ia2.Accessible2;
import org.eclipse.actf.accservice.swtbridge.ia2.IA2Util;
import org.eclipse.actf.visualization.gui.Messages;
import org.eclipse.actf.visualization.gui.common.WebBrowserUtil;
import org.eclipse.actf.visualization.gui.flash.FlashUtil;
import org.eclipse.actf.visualization.gui.ui.views.IFlashDOMView;
import org.eclipse.actf.visualization.gui.ui.views.MSAATreeContentProvider;
import org.eclipse.actf.visualization.gui.ui.views.MSAAViewRegistory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;


public class ScreenReaderRenderer {
	private int lastHwnd = 0;
	private String lastText = ""; //$NON-NLS-1$
	private StyledText text;
	private TextMap textMap;
    private static final MSAATreeContentProvider provider = MSAATreeContentProvider.getDefault();
    private static final Display display = Display.getCurrent();
    private static RenderThread renderThread = null;
    private static DisposeListener disposeListener = null;
    private static final int IDLE_WAIT = 5; 
    private static final int BUSY_WAIT = 500; 
    public static int waitMS = IDLE_WAIT;
    private IFlashDOMView flashDOMView = (IFlashDOMView)MSAAViewRegistory.findView(MSAAViewRegistory.FlashDOMView_ID);
	
    private static final String[] BROWSER_CONTENT_CLASSNAMES = new String[] { 
        "Internet Explorer_Server",  //$NON-NLS-1$
        "MozillaWindowClass",  //$NON-NLS-1$
        "MozillaContentWindowClass"  //$NON-NLS-1$
    };
    
    private static boolean isBrowserContent(String className) {
        for( int i=0; i<BROWSER_CONTENT_CLASSNAMES.length; i++ ) {
            if( BROWSER_CONTENT_CLASSNAMES[i].equals(className) ) {
                return true;
            }
        }
        return false;
    }
    
	public ScreenReaderRenderer(StyledText text, TextMap textMap) {
		this.text = text;
		this.textMap = textMap;
        if( null == disposeListener ) {
            disposeListener = new DisposeListener(){
                public void widgetDisposed(DisposeEvent e) {
                    if( null != renderThread ) {
                        renderThread.cancel = true;
                        renderThread.interrupt();
                        renderThread = null;
                        disposeListener = null;
                    }
                }
            };
            text.addDisposeListener(disposeListener);
        }
	}
	
	public void renderAll(AccessibleObject object) {
        if( null != renderThread ) {
            renderThread.cancel = true;
            renderThread.interrupt();
        }
		text.setText(""); //$NON-NLS-1$
		if( null != textMap ) {
			textMap.clear();
		}
		AccessibleObject parent = object.getCachedParent();
		if( null !=parent ) {
            renderThread = new RenderThread(provider.getElements(parent));
            renderThread.start();
            Thread.yield();
		}
	}
    
    private class RenderThread extends Thread{
        
        private Object[] startElements;
        
        public boolean cancel = false;
        public RenderThread(Object[] startElements) {
            super();
            this.startElements = startElements;
        }

        public void run() {
            try {
                renderElements(startElements);
				display.syncExec(new Runnable(){
					public void run() {
					    if( !(cancel || text.isDisposed() || text.getCharCount()>0) ) {
					        appendText(Messages.getString(provider.hideHtml ? "msaa.no_flash" : "msaa.empty_page"),SWT.COLOR_GRAY,-1,false); //$NON-NLS-1$ //$NON-NLS-2$
				        }
				    }
				});
            }
            catch( InterruptedException e ) {
            }
        }
        private void renderElements(Object[] inputElements) throws InterruptedException {
            if( null == inputElements ) {
                return;
            }
            for( int i=0; i<inputElements.length; i++ ) {
                if( cancel ) {
                    throw new InterruptedException();
                }
            	if( inputElements[i] instanceof AccessibleObject ) {
                	final int index = i;
                	final boolean sayFlashEnd[] = new boolean[]{false};
                	final Object[][] renderChildren = new Object[][]{null};
                    final AccessibleObject accObject = (AccessibleObject)inputElements[i];
                	display.syncExec(new Runnable(){
                        public void run() {
                            if( !(cancel || text.isDisposed()) ) {
                                int hwnd = accObject.getWindow();
                                if( hwnd != lastHwnd ) {
                                    if( FlashUtil.isFlash(accObject) ) {
                                        String wmode = null;
                                        if( 0 == hwnd ) {
                                            wmode = WebBrowserUtil.getHtmlAttribute(accObject,"WMode"); //$NON-NLS-1$
                                        }
                                        if( null == wmode ) {
                                            AccessibleObject parentObject = accObject.getCachedParent();
                                            if( null != parentObject && hwnd != parentObject.getWindow() ) {
                                                appendText(Messages.getString("msaa.flash_start")+"\n",SWT.COLOR_GRAY,SWT.COLOR_YELLOW,false); //$NON-NLS-1$ //$NON-NLS-2$
                                                sayFlashEnd[0] = true;
                                            }
                                        }
                                        else {
                                            appendText(Messages.getString("msaa.flash_inaccessible")+" wmode="+wmode+"\n",SWT.COLOR_GRAY,SWT.COLOR_RED,false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                                            if( null != flashDOMView ) {
                                                flashDOMView.addWindowlessElement(accObject);
                                            }
                                        }
                                    }
                                    lastHwnd = hwnd;
                                }
                                renderItem(accObject, false, index);
                                renderChildren[0] = provider.getChildren(accObject);
                            }
                        }
                    });
                    renderElements(renderChildren[0]);
                    if ( sayFlashEnd[0] ) {
                        display.syncExec(new Runnable(){
                            public void run() {
                                if( !(cancel || text.isDisposed()) ) {
                                    appendText(Messages.getString("msaa.flash_end")+"\n",SWT.COLOR_GRAY,SWT.COLOR_YELLOW,false); //$NON-NLS-1$ //$NON-NLS-2$
                                }
                            }
                        });
                    }
                    Thread.yield();
                    Thread.sleep(waitMS);
                    setBusy(false);
            	}
            }
        }
    };

    public static void setBusy(boolean busy) {
        waitMS = busy ? BUSY_WAIT : IDLE_WAIT;
    }
    
	public String renderItem(AccessibleObject accObject, boolean selected, int parentIndex) {
        String accName = accObject.getAccName();
		String outText = null==accName ? "" : accName.replace('\u00A0',' ').trim(); //$NON-NLS-1$
		int accState = accObject.getAccState();
		int accRole = accObject.getAccRole();
		boolean isFlash = FlashUtil.isFlash(accObject);
//        boolean isBrowser = WebBrowserUtil.isBrowser(accObject);
        boolean isBrowser = isBrowserContent(accObject.getClassName());
		String prefix="", postfix=""; //$NON-NLS-1$ //$NON-NLS-2$
        String defaultAction = accObject.getAccDefaultAction();
		boolean clickable = null != defaultAction && defaultAction.length()>0;
        boolean visible = 0 == (accObject.getAccState() & MSAA.STATE_INVISIBLE);
		int foreground = visible ? (clickable ? SWT.COLOR_BLUE : -1) : SWT.COLOR_GRAY;
		int background = selected ? SWT.COLOR_CYAN : -1;
		switch( accRole ) {
			case MSAA.ROLE_SYSTEM_TEXT:
				{
					boolean editable = (0 == (accState&MSAA.STATE_READONLY));
					if( !isBrowser || editable ) {
						prefix = Messages.getString(editable ? "msaa.edit" : "msaa.edit_readonly"); //$NON-NLS-1$ //$NON-NLS-2$
						outText = accObject.getAccValue();
						if( null==outText || 0==outText.length() ) {
							outText = " "; //$NON-NLS-1$
						}
						break;
					}
				}
			case MSAA.ROLE_SYSTEM_STATICTEXT:
				if( outText.equals(lastText) ) {
					outText = ""; //$NON-NLS-1$
				}
				break;
			case 0x28: // ROLE_SYSTEM_GRAPHIC
                if( isFlash ) {
                    prefix = Messages.getString("msaa.graphic"); //$NON-NLS-1$
                }
                else {
                    postfix = Messages.getString("msaa.graphic"); //$NON-NLS-1$
                }
				if( outText.equals(lastText) ) {
					outText = ""; //$NON-NLS-1$
				}
				break;
			case MSAA.ROLE_SYSTEM_LINK:
				prefix = Messages.getString("msaa.link"); //$NON-NLS-1$
				break;
			case MSAA.ROLE_SYSTEM_CHECKBUTTON:
				prefix = Messages.getString("msaa.checkbox")+" "; //$NON-NLS-1$ //$NON-NLS-2$
				prefix += 0!=(accState&MSAA.STATE_CHECKED) ? Messages.getString("msaa.checked") : Messages.getString("msaa.not_checked"); //$NON-NLS-1$ //$NON-NLS-2$
				break;
			case MSAA.ROLE_SYSTEM_RADIOBUTTON:
				prefix = Messages.getString("msaa.radiobutton")+" "; //$NON-NLS-1$ //$NON-NLS-2$
				prefix += 0!=(accState&MSAA.STATE_CHECKED) ? Messages.getString("msaa.checked") : Messages.getString("msaa.not_checked"); //$NON-NLS-1$ //$NON-NLS-2$
				break;
			case MSAA.ROLE_SYSTEM_SLIDER:
				outText = accObject.getAccValue();
				postfix = Messages.getString("msaa.updown_scrollbat"); //$NON-NLS-1$
				break;
			case MSAA.ROLE_SYSTEM_PROGRESSBAR:
				outText = accObject.getAccValue();
				postfix = Messages.getString("msaa.progressbar"); //$NON-NLS-1$
				break;
			case 0x34:	// ROLE_SYSTEM_SPINBUTTON
				outText = accObject.getAccValue();
				postfix = Messages.getString("msaa.editspinbox"); //$NON-NLS-1$
				break;
			case MSAA.ROLE_SYSTEM_COMBOBOX:
				prefix = Messages.getString("msaa.combobox"); //$NON-NLS-1$
				outText = accObject.getAccValue();
                if( null==outText || 0==outText.length() ) {
                    outText = accObject.getAccName();
                }
				break;
			case 0x3E: // ROLE_SYSTEM_SPLITBUTTON
            case MSAA.ROLE_SYSTEM_BUTTONDROPDOWN:
			case MSAA.ROLE_SYSTEM_PUSHBUTTON:
				postfix = Messages.getString("msaa.button"); //$NON-NLS-1$
				if( 0==outText.length() ) {
                    if( isFlash ) {
                        outText = Integer.toString(parentIndex);
                        foreground = SWT.COLOR_RED;
                    }
                    else {
                        outText = " "; //$NON-NLS-1$
                    }
				}
				break;
			case MSAA.ROLE_SYSTEM_LISTITEM:
                {
                    AccessibleObject parent = accObject.getCachedParent();
                    if( null!=parent) {
                        switch( parent.getAccRole() ) {
                            case MSAA.ROLE_SYSTEM_LIST:
                                postfix = Messages.getString("msaa.listbox"); //$NON-NLS-1$
                                if( 0!=(accState&MSAA.STATE_SELECTED) ) {
                                    postfix += " "+Messages.getString("msaa.selected"); //$NON-NLS-1$ //$NON-NLS-2$
                                }
                                break;
                            case MSAA.ROLE_SYSTEM_COMBOBOX:
                                prefix = Messages.getString("msaa.combobox"); //$NON-NLS-1$
                                break;
                        }
                    }
                }
				break;
			case MSAA.ROLE_SYSTEM_TABLE:
				postfix = Messages.getString("msaa.table"); //$NON-NLS-1$
				break;
			case MSAA.ROLE_SYSTEM_CELL:
				postfix = Messages.getString("msaa.cell"); //$NON-NLS-1$
				break;
			case MSAA.ROLE_SYSTEM_COLUMNHEADER:
				postfix = Messages.getString("msaa.columnheader"); //$NON-NLS-1$
				break;
			case MSAA.ROLE_SYSTEM_ROWHEADER:
				postfix = Messages.getString("msaa.rowheader"); //$NON-NLS-1$
				break;
			case MSAA.ROLE_SYSTEM_PAGETAB:
				postfix = Messages.getString("msaa.tab"); //$NON-NLS-1$
				break;
			case MSAA.ROLE_SYSTEM_OUTLINEITEM:
				postfix = Messages.getString("msaa.treeview"); //$NON-NLS-1$
				if( 0!=(accState&MSAA.STATE_SELECTED) ) {
					postfix += " "+Messages.getString("msaa.selected"); //$NON-NLS-1$ //$NON-NLS-2$
				}
				else if( isFlash ) {
					outText = "";	// Ignore in flash //$NON-NLS-1$
				}
				break;
			case MSAA.ROLE_SYSTEM_OUTLINE:
				postfix = Messages.getString("msaa.tree"); //$NON-NLS-1$
				break;
				
			case MSAA.ROLE_SYSTEM_MENUBAR:
				postfix = Messages.getString("msaa.menubar"); //$NON-NLS-1$
				break;
			case MSAA.ROLE_SYSTEM_MENUPOPUP:
			case MSAA.ROLE_SYSTEM_MENUITEM:
                if( 0 != (accState&MSAA.STATE_SYSTEM_UNAVAILABLE) ) {
                    postfix = Messages.getString("msaa.unavailable"); //$NON-NLS-1$
                    break;
                }
                if( accObject.getChildCount() > 0 ) {
                    AccessibleObject parent = accObject.getCachedParent();
                    if( null != parent && MSAA.ROLE_SYSTEM_MENUITEM==parent.getAccRole() ) {
                        postfix = Messages.getString("msaa.submenu"); //$NON-NLS-1$
                    }
                    else {
                        postfix = Messages.getString("msaa.menu"); //$NON-NLS-1$
                    }
                }
                else if( 0 != (accState&MSAA.STATE_CHECKED) ) {
                    postfix = Messages.getString("msaa.checked"); //$NON-NLS-1$
                }
				break;
			case MSAA.ROLE_SYSTEM_TOOLBAR:
				postfix = Messages.getString("msaa.toolbar"); //$NON-NLS-1$
				break;
			case 0x17: // ROLE_SYSTEM_STATUSBAR
				postfix= Messages.getString("msaa.statusbar"); //$NON-NLS-1$
				break;
			case MSAA.ROLE_SYSTEM_SCROLLBAR:
				postfix = Messages.getString("msaa.scrollbar"); //$NON-NLS-1$
				break;
			case 0x27: // ROLE_SYSTEM_INDICATOR
				postfix = Messages.getString("msaa.indicator"); //$NON-NLS-1$
				break;
			case 0xe: // ROLE_SYSTEM_APPLICATION
				postfix = Messages.getString("msaa.application"); //$NON-NLS-1$
				break;
			case 0xf: // ROLE_SYSTEM_DOCUMENT
				postfix = Messages.getString("msaa.document"); //$NON-NLS-1$
				break;
			case MSAA.ROLE_SYSTEM_WINDOW:
			case 0x10: // ROLE_SYSTEM_PANE
				if( isFlash ) {
					outText = "";	// Ignore in flash //$NON-NLS-1$
				}
				else {
					postfix = Messages.getString("msaa.window"); //$NON-NLS-1$
				}
				break;
			case MSAA.ROLE_SYSTEM_CLIENT:
                if( isFlash || isBrowser || outText.equals(lastText) ) {
                    outText = "";   // Ignore in flash //$NON-NLS-1$
                }
				break;
            case IA2.IA2_ROLE_ROOT_PANE:
            case IA2.IA2_ROLE_OPTION_PANE:
                break;  // TODO Do nothing?
            case IA2.IA2_ROLE_SHAPE:
                {
                    String style = null;
                    Accessible2 ac2 = accObject.getAccessible2();
                    if( null != ac2 ) {
                        style = IA2Util.getAttribute(ac2.getAttributes(),"style"); //$NON-NLS-1$
                    }
                    if( null != style ) {
                        postfix = MessageFormat.format(Messages.getString("ia2.style_shape"),new Object[]{style});  //$NON-NLS-1$
                    }
                    else {
                        postfix += Messages.getString("ia2.shape"); //$NON-NLS-1$
                    }
                }
                break;
            case IA2.IA2_ROLE_CHECK_MENU_ITEM:
            case IA2.IA2_ROLE_RADIO_MENU_ITEM:
                if( 0 != (accState&MSAA.STATE_SYSTEM_UNAVAILABLE) ) {
                    postfix = Messages.getString("msaa.unavailable"); //$NON-NLS-1$
                    break;
                }
                {
                    Accessible2 ac2 = accObject.getAccessible2();
                    if( null != ac2 ) {
                        String extendedStates[] = ac2.getExtendedStates(8);
                        if( IA2Util.getExtendedState(extendedStates,"CHECKED") ) { //$NON-NLS-1$
                            postfix = Messages.getString("msaa.checked"); //$NON-NLS-1$
                        }
                    }
                }
                break;
            case IA2.IA2_ROLE_HEADING:
            	String level = "?"; //$NON-NLS-1$
            	try {
                    Accessible2 ac2 = accObject.getAccessible2();
                    if( null != ac2 ) {
                    	level = IA2Util.getAttribute(ac2.getAttributes(),"heading-level");                 //$NON-NLS-1$
                    }
            	}
            	catch( Exception e) {
            	}
                prefix = MessageFormat.format(Messages.getString("ia2.heading_level"),new Object[]{level});  //$NON-NLS-1$
            case IA2.IA2_ROLE_PARAGRAPH:
                outText = accObject.getAccValue();
                if( null==outText || 0==outText.length() ) {
                    outText = accObject.getAccName();
                }
                break;
			default:
				prefix = "["+accObject.getRoleText() + " 0x"+Integer.toHexString(accRole)+"]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				break;
		}
		String speakText = ""; //$NON-NLS-1$
		Point point = new Point(text.getCharCount(),0);
		if( null!=outText && outText.length()>0 ) {
            if( " ".equals(outText) ) { //$NON-NLS-1$
                outText = ""; //$NON-NLS-1$
            }
			if( prefix.length()>0 ) {
                if( outText.length()>0 ) {
                    prefix += " "; //$NON-NLS-1$
                }
				appendText(prefix,SWT.COLOR_GRAY,background,false);
				speakText += prefix;
			}
            if( outText.length()> 0 ) {
                appendText(outText,foreground,background,clickable);
                speakText += outText;
            }
			if( postfix.length()>0 ) {
                if( speakText.length()> 0 ) {
                    postfix = " "+postfix; //$NON-NLS-1$
                }
				appendText(postfix,SWT.COLOR_GRAY,background,false);
				speakText += postfix;
			}
			text.append("\n"); //$NON-NLS-1$
			lastText = outText;
		}
		point.y = text.getCharCount();
		if( null != textMap ) {
			textMap.put(accObject,point);
		}
		return speakText;
	}
    
    public String renderEvent(int event) {
        String eventText = ""; //$NON-NLS-1$
        switch( event ) {
            case MSAA.EVENT_SYSTEM_MENUSTART:
                eventText = Messages.getString("msaa.menu_start"); //$NON-NLS-1$
                break;
            case MSAA.EVENT_SYSTEM_MENUPOPUPSTART:
                eventText = Messages.getString("msaa.popup_start"); //$NON-NLS-1$
                break;
            case MSAA.EVENT_SYSTEM_MENUEND:
                eventText = Messages.getString("msaa.menu_end"); //$NON-NLS-1$
                break;
            case MSAA.EVENT_SYSTEM_MENUPOPUPEND:
                eventText = Messages.getString("msaa.popup_end"); //$NON-NLS-1$
                break;
        }
        if( eventText.length() > 0 ) {
            appendText(eventText,SWT.COLOR_GRAY,-1,false); //$NON-NLS-1$
            text.append("\n"); //$NON-NLS-1$
            lastText = eventText;
        }
        return eventText;
    }
	
	private void appendText(String str, int foreground, int background, boolean underline ) {
		StyleRange range = new StyleRange();
		if( foreground >= 0 ) {
			range.foreground = Display.getCurrent().getSystemColor(foreground);
		}
		if( background >= 0 ) {
			range.background = Display.getCurrent().getSystemColor(background);
		}
		range.underline = underline;
		range.start = text.getCharCount();
		range.length = str.length();
		text.append(str);
		text.setStyleRange(range);
	}
}
