/*
 * Create_plugin_release_text.bsh - a BeanShell macro script for the
 * jEdit text editor - Parses a plugin's properties file to create the
 * text for a plugin submission
 * Copyright ( C ) 2006 Jeffrey Hoyt
 * jchoyt@jedit.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program 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 for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */


// import statements
import javax.swing.border.*;

// main routine
void pluginTextDialog( View view, Buffer buffer )
{
	this.view = view;
    this.buffer=buffer;

    File propsFile = new File( buffer.getPath() );
    Properties props = new Properties();
    InputStream in = new FileInputStream( propsFile );
    try
    {
        props.load( in );
    }
    finally
    {
        in.close();
    }

    //setup the strings we are interested in and can get from the props file
    String fileName = propsFile.getName();
    String pluginName = fileName.substring( 0, fileName.indexOf( '.' ) );
    String version = null;
    String jEditDependency = null;
    String javaDependency = null;
    String activate = null;
    ArrayList pluginDependencies = new ArrayList();
    ArrayList optionalPluginDependencies = new ArrayList();
    String announcement, shortDescription, source;
    String longDescription="";
    String classname=null;
    String longDescriptionFileName=null;

    //extract the properties we care about
    String start = "plugin.";
    for ( Enumeration e = props.keys(); e.hasMoreElements() ; )
    {
        String key = ( String ) e.nextElement();
        // Log.log( Log.DEBUG, this, "Parsing key: " + key );
        if( key.startsWith( start ) )
        {
            if( key.endsWith( ".activate" ) )
            {
                activate = props.getProperty( key );
            }
            else if( key.endsWith( ".version" ) )
            {
                version = props.getProperty( key );
            }
            else if( key.indexOf( ".depend." ) != -1 )
            {
                String value = props.getProperty( key ).trim();
                String[] parts = value.split( " " );
                if( parts.length < 2 )
                {
                    Macros.error( view, "Badly constructed dependency ( " + value + " ).  All dependencies must have at least 2 parts" );
                }
                if( parts[0].equals( "jedit" ) )
                {
                    jEditDependency = parts[1];
                }
                else if( parts[0].equals( "jdk" ) )
                {
                    javaDependency = parts[1];
                }
                else if( parts[0].equals( "plugin" ) )
                {
                    pluginDependencies.add( parts[1] + " " + parts[2] );
                }
                else if( parts[0].equals( "optional" ) && parts[1].equals( "plugin" ) )
                {
                    optionalPluginDependencies.add( parts[2] + " " + parts[3] );
                }
                else
                {
                    Macros.error( view, "Unexpected dependency ( " + value + " ).  See the javadoc of org.gjt.sp.jedit.EditPlugin" );
                }
            }
            else if(key.endsWith(".longdescription") )
            {
                longDescriptionFileName = props.getProperty( key );
            }
            else if(key.endsWith(".description") )
            {
                shortDescription = props.getProperty( key );
            }
            else if(key.endsWith(".name") )
            {
                if (props.getProperty( key ).equals(pluginName))
                {
                    classname = key.substring( start.length(), key.length() - 5 );
                    // Macros.error( view, "Classname is " + classname );
                }
            }
        }
    }
    // Macros.error( view, "Parsing complete" );

    if( javaDependency==null )
    {
        Macros.error( view, "You must supply a JDK dependency.  Please add it and rerun the macro." );
        return;
    }
    if( jEditDependency==null )
    {
        Macros.error( view, "You must supply a jEdit dependency.  Please add it and rerun the macro." );
        return;
    }
    if( shortDescription==null )
    {
        Macros.error( view, "You must supply a short description in the plugin." + classname + ".description property.  Please add it and rerun the macro." );
        return;
    }
    if( longDescriptionFileName==null )
    {
        longDescriptionFileName = "description.html";
        // Macros.error(view, "setting default long description file");
    }

    //load the long description
    File descriptionFile = new File( new File(buffer.getPath()).getParent(), longDescriptionFileName );
    if(!descriptionFile.exists())
    {
        Macros.error( view, "You must supply a long description in a file located at " + descriptionFile.getPath() + ".  Please create it and rerun the macro." );
        return;
    }
    BufferedReader reader = new BufferedReader( new FileReader( descriptionFile ) );
    try
    {
        String line;
        while( (line = reader.readLine())!=null )
        {
            longDescription = longDescription + line + "\n";
        }
    }
    finally
    {
        reader.close();
    }

    // create dialog object and set its features
    title = "Create Plugin Announcement";
    dialog = new JDialog( view, title, false );
    content = new JPanel( new BorderLayout() );
    content.setBorder( new EmptyBorder( 12, 12, 12, 12 ) );
    dialog.setContentPane( content );

    // add to the dialog a panel containing the text fields for
    // entry of the prefix and suffix text
    propsPanel = new JPanel( new GridLayout( 5 + pluginDependencies.size() + optionalPluginDependencies.size() , 2, 2, 6 ) );
    propsPanel.add( new JLabel( "Plugin name" ) );
    propsPanel.add( new JLabel( pluginName ) );
    propsPanel.add( new JLabel( "Plugin version" ) );
    propsPanel.add( new JLabel( version ) );
    propsPanel.add( new JLabel( "Activates" ) );
    propsPanel.add( new JLabel( activate ) );
    propsPanel.add( new JLabel( "jEdit Dependency" ) );
    propsPanel.add( new JLabel( jEditDependency ) );
    propsPanel.add( new JLabel( "JDK Dependency" ) );
    propsPanel.add( new JLabel( javaDependency ) );
    for( int i=0; i<pluginDependencies.size(); i++ )
    {
        propsPanel.add( new JLabel( "Depends on" ) );
        propsPanel.add( new JLabel( pluginDependencies.get( i ).toString() ) );
    }
    for( int i=0; i<optionalPluginDependencies.size(); i++ )
    {
        propsPanel.add( new JLabel( "Optional" ) );
        propsPanel.add( new JLabel( optionalPluginDependencies.get( i ).toString() ) );
    }
    content.add( propsPanel, "Center" );

    //add areas for source location, Announcement, Short Description, and Long Description
    descriptionPanel = new JPanel();
    descriptionPanel.setLayout( new BoxLayout( descriptionPanel, BoxLayout.Y_AXIS ) );
    descriptionPanel.setBorder(new EmptyBorder(12, 5, 0, 5));

    descriptionPanel.add( new JLabel( "Source Code Location (SVN and tag, or URL): " ) );
    sourceArea = new JEditorPane();
    sourceArea.setText("Source code is in SVN with the tag XXXX (no SVN release numbers, please)");
    sourceArea.setPreferredSize( new Dimension( 250, 36 ) );
    descriptionPanel.add( new JScrollPane( sourceArea ) );

    descriptionPanel.add( new JLabel( "Announcement: " ) );
    announcementArea = new JEditorPane();
    announcementArea.setPreferredSize( new Dimension( 250, 120 ) );
    descriptionPanel.add( new JScrollPane( announcementArea ) );

    descriptionPanel.add( new JLabel( "Short Description ( for new plugins or updated descriptions only ): " ) );
    shortDescriptionArea = new JEditorPane("text/plain", shortDescription);
    shortDescriptionArea.disable();
    shortDescriptionArea.setPreferredSize( new Dimension( 250, 72 ) );
    descriptionPanel.add( new JScrollPane( shortDescriptionArea ) );

    descriptionPanel.add( new JLabel( "Long Description ( for new plugins or updated descriptions only ): " ) );
    longDescriptionArea = new JEditorPane("text/plain", longDescription);
    longDescriptionArea.disable();
    longDescriptionArea.setPreferredSize( new Dimension( 250, 120 ) );
    descriptionPanel.add( new JScrollPane( longDescriptionArea ) );

        //add buttons to description panel
        buttonPanel = new JPanel();
        buttonPanel.setLayout( new BoxLayout( buttonPanel, BoxLayout.X_AXIS ) );
        ok = new JButton( "Create Announcement" );
        buttonPanel.add( ok );
        cancel = new JButton( "Cancel" );
        buttonPanel.add( cancel );
        descriptionPanel.add( buttonPanel );
    content.add( descriptionPanel, "South" );

    // register this method as an ActionListener for
    // the buttons and text fields
    ok.addActionListener( this );
    cancel.addActionListener( this );

    // locate the dialog in the center of the
    // editing pane and make it visible
    dialog.pack();
    dialog.setLocationRelativeTo( view );
    dialog.setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE );
    dialog.setVisible( true );

    // this method will be called when a button is clicked
    // or when ENTER is pressed
    void actionPerformed( e )
    {
        if( e.getSource() != cancel )
        {
           createAnnouncement();
        }
        dialog.dispose();
    }

    void createAnnouncement()
    {
        announcement = announcementArea.getText();
        shortDescription = shortDescriptionArea.getText();
        longDescription = longDescriptionArea.getText();
        source = sourceArea.getText();
        StringBuffer ret = new StringBuffer();
        ret.append( "Paste the text below into the Plugin Central Submission Tracker at https://sourceforge.net/tracker/?group_id=588&atid=625093\n" );
        ret.append( "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
        ret.append( "\n{{{ " );
        ret.append( pluginName );
        ret.append( " " );
        ret.append( version );
        ret.append( "\n    Source: " );
        ret.append( source );
        ret.append( "\n    Announcement: " + announcement.replaceAll("\n", "\n        " ) );
        ret.append( "\n    Requires Java " );
        ret.append( javaDependency );
        ret.append( "\n    Requires jEdit " );
        ret.append( jEditDependency );
        if( pluginDependencies.size() > 0 )
        {
            ret.append( "\n    Required plugins: " );
            for( int i=0; i<pluginDependencies.size(); i++ )
            {
                ret.append( "\n        " );
                ret.append( pluginDependencies.get( i ) );
            }
        }
        if( optionalPluginDependencies.size() > 0 )
        {
            ret.append( "\n    Optional plugins: " );
            for( int i=0; i<optionalPluginDependencies.size(); i++ )
            {
                ret.append( "\n        " );
                ret.append( optionalPluginDependencies.get( i ) );
            }
        }
        if( shortDescription!=null && !shortDescription.equals( "" ) )
        {
            ret.append( "\n    \n    Short Description: " + shortDescription );
        }
        if( longDescription!=null && !longDescription.equals( "" ) )
        {
            ret.append( "\n    \n    Long Description: " + longDescription );
        }
        ret.append( " }}}" );
        newbuf = jEdit.newFile( view );
        newbuf.insert( 0, ret.toString() );
    }
}

// this single line of code is the script's main routine
// it calls the methods and exits
if( buffer.getMode().toString().equals( "properties" ) )
	pluginTextDialog( view, buffer );
else
	Macros.error( view, "This must be run on a jEdit plugin's properties file.  \nOpen your Plugin's props file and rerun this macro." );

/*
	Macro index data ( in DocBook format )

<listitem>
    <para><filename>Create_Plugin_Announcement.bsh</filename></para>
    <abstract><para>
        Creates a machine-parsable version of the release announcement from the source files and minimal user input.
        The wiz can then read this file and do the release automatically.
    </para></abstract>
    <para>
        Creates a machine-parsable version of the release announcement from the source files and minimal user input.
        The wiz can then read this file and do the release automatically.
    </para>
</listitem>

*/

