#!/usr/bin/perl

# ipknot.pl ver. 1.2.0
# Copyright (C) 2012 Yuki Kato
# This script is used to access the web server IPknot for predicting RNA secondary structures with pseudoknots and parse the output.
# Usage: Type "./ipknot.pl" in your terminal.

use strict;
use warnings;
use Getopt::Long;
use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
use HTML::TreeBuilder;

my %opt = (level => 2, model => "McCaskill", refinement => 0, weight1 => 2, weight2 => 16, weight3 => 16, help => 0);
GetOptions(\%opt, qw(level=i model=s refinement=i weight1=i weight2=i weight3=i help)) or exit;

# Argument check
if (!exists $ARGV[0] || $opt{help} == 1) {
    print "ipknot.pl ver. 1.2.0\n\n";
    print "This script is used to access the web server IPknot for predicting RNA secondary structures with pseudoknots and parse the output.\n\n";
    print "Usage: ./ipknot.pl [OPTIONS] [FILE]\n\n";
    print "[FILE]\n";
    print " Note: The file for input sequences must be specified in FASTA or CLUSTALW format.\n\n";
    print "[OPTIONS]\n";
    print " -l, --level       1, 2 or 3 (default: 2)\n";
    print " -m, --model       McCaskill, CONTRAfold or NUPACK (default: McCaskill)\n";
    print " -r, --refinement  Do (1) or not (0) (default: 0, i.e. no refinement)\n";
    print "     --weight1     A positive weight for true base pairs at level 1 (default: 2)\n";
    print "     --weight2     A positive weight for true base pairs at level 2 (default: 16)\n";
    print "     --weight3     A positive weight for true base pairs at level 3 (default: 16)\n";
    print " -h, --help        Show this message\n\n";
    exit;
}

# File input
open(FILE, $ARGV[0]) or die "$!";
my $sequence;

while (my $line = <FILE>) {
	$sequence = $sequence.$line;
}

close(FILE);

# Set the parameters
my %params = (
	seq => $sequence,
	level => $opt{level},
	model => $opt{model},
	refinement => $opt{refinement},
	gamma1 => $opt{weight1},
	gamma2 => $opt{weight2},
	gamma3 =>$opt{weight3},
);

# Create a request
my $req = POST("http://ws.sato-lab.org/rtips/ipknot/process.php", [%params]);

# Retrieve the result for the request
my $ua = LWP::UserAgent->new;
my $res = $ua->request($req);

if ($res->is_success) {
	my $content = $res->content;
	my $tree = HTML::TreeBuilder->new;
	$tree->parse($content);
	
	my @h2 = $tree->find('h2');
	my $heading = $h2[0]->as_text;
	
	# Show an error
	if ($heading eq "Error") {
		print "Error!\n";
		my @warning = $tree->look_down('class', 'warning');
		print $_->as_text."\n" for @warning;
	}
	
	# Show the result
	else {
		my @structure = $tree->look_down('id', 'vienna')->find('pre');
		print $_->as_text."\n" for @structure;
	}

}

else {
	print $res->status_line, "\n";
}

print "\n";
