package test.pages;

import test.pages.CookieTestPage.MyModel;
import wicket.AttributeModifier;
import wicket.Component;
import wicket.Page;
import wicket.markup.ComponentTag;
import wicket.markup.html.form.Button;
import wicket.markup.html.form.Form;
import wicket.markup.html.form.TextField;
import wicket.model.AbstractReadOnlyModel;
import wicket.model.CompoundPropertyModel;

/**
 * A link which can be used exactly like a Button to submit a Form. The href of the link will use JavaScript to 
 * submit the form (form.submit()). To do that it will set the name attribute of the form. 
 * 
 * <p>
 * One of the SubmitLinks must be provided the form in the constructor, so that an AttributeModifier can be 
 * registered. Further SubmitLinks can use the simple id constructor.
 * 
 * Usage:
 * <pre>
        final MyModel mod = new MyModel();
        Form f = new Form("linkForm", new CompoundPropertyModel(mod));
        f.add(new TextField("value1"));
        f.add(new SubmitLink("link1", f) {
            protected void onSubmit() {
                System.out.println("Link1 was clicked, value1 is: "
                        + mod.getValue1());
            };
        });
        f.add(new SubmitLink("link2") {
            protected void onSubmit() {
                System.out.println("Link2 was clicked, value1 is: "
                        + mod.getValue1());
            };
        });
 *  </pre>
 * html:
 * <pre>
     <form wicket:id="linkForm" >
        <input wicket:id="value1" type="text" size="30"/>
        <a wicket:id="link1">Press link1 to submit</a>
        <a wicket:id="link2">Press link 2 to submit</a>
        <input type="submit" value="Send"/>
    </form>
*</pre>
 * 
 * dcode
 * @author chris
 *
 */
public class SubmitLink extends Button{

    private final Form _form;
    
    /**
     * One SubmitLink in your form must use this Constructor. You have to provide 
     * the form so that an attribute modifier can be used. Other SubmitLinks in the form should use
     * the simple id cunstrutor.
     * @param id component id
     * @param form to which the created instance will be added
     */
    public SubmitLink(String id,Form form) {
        super(id);
        if(form == null)
            throw new NullPointerException("You must provide a form");
        _form = form;
        AttributeModifier am = new AttributeModifier("name",true,new AbstractReadOnlyModel(){

            @Override
            public Object getObject(Component component)
            {
                return getFormName();
            }
        });
        _form.add(am);
    }
    
    /**
     * Used inside a Form. There must be at least one SubmitLink on the form which takes the form in 
     * the constructor.
     * @param id
     */
    public SubmitLink(String id){
        super(id);
        _form = null;
    }
    
    @Override
    protected void onComponentTag(ComponentTag tag)
    {
        checkComponentTag(tag, "a");
        String script = "javascript:document.getElementsByName('"+getInputName()+":not')[0].name=\'"+getInputName()+"';";
        script +="document."+getFormName()+".submit();";
        
        tag.put("href",script);
    }
    
    protected void onRender(){
        super.onRender();
        getResponse().write("<input type=\"hidden\" name=\""+ getInputName()+ ":not\">");
        
    }

    public String getFormName()
    {
        final Form form;
        if(_form == null){
            form = (Form) findParent(Form.class);
        }else{
            form = _form;
        }
            
        String id = form.getId();
        final StringBuffer inputName = new StringBuffer();
        Component c = form;
        while (true)
        {
            inputName.insert(0, id);
            c = c.getParent();
            if (c == null || c instanceof Page || inputName.length() > 100)
            {
                break;
            }
            inputName.insert(0, ':');
            id = c.getId();
        }
        return inputName.toString();
    }
    

}
